⍣
,如果应用于函数f
,则会叠加f
的应用。如何在Raku中实现该运算符?例如,使用以下定义的
f
:sub f(Int:D $i){ $i + 1 }
命令say (f ⍣ 4)(10);
应该等同于say f(f(f(f(10))));
。
我下面的实现是针对一个参数的函数。
问题
如何扩展或替换以适用于多个(或任何)签名的更好实现?
如何定义新的幂运算符的“高优先级”?
是否有更好的方法来定义
f ⍣ 0
的“恒等函数”结果?
参考链接
这里是APL的⍣
的描述:“Power Operator”。
(⍣
是一个“带有两个点的星号”,或更正式地说,是“Apl Functional Symbol Star Diaeresis”。)
尝试
这是一种实现尝试:
sub infix:<⍣>( &func, Int:D $times where $times >= 0 ) {
if $times == 0 {
sub func2($d) {$d}
} else {
sub func2($d) {
my $res = &func($d);
for 2..$times -> $t { $res = &func($res) }
$res
}
}
}
sub plus1(Int:D $i){ $i + 1 }
say 'Using (&plus1 ⍣ 0) over 4 :';
say (&plus1 ⍣ 0)(4);
say 'Using (&plus1 ⍣ 10) over 4 :';
say (&plus1 ⍣ 10)(4);
# Using (&plus1 ⍣ 0) over 4 :
# 4
# Using (&plus1 ⍣ 10) over 4 :
# 14
我按照这个教程页面进行了操作:https://docs.raku.org/language/optut。
测试
Brad Gilbert的回答中提供的定义通过了以下所有测试。
use Test;
sub infix:<⍣> ( &func, UInt $repeat ) is tighter( &[∘] ) { [∘] &func xx $repeat }
proto plus1(|) {*}
multi plus1(Int:D $i){ $i + 1 }
multi plus1(Bool:D $b){ $b.Int + 1 }
multi plus1(Int:D $i, Bool:D $b){ $i + $b.Int + 1 }
multi plus1(Int:D $i, Int:D $j){ $i + $j + 1 }
multi plus1(@j){ ([+] @j) + 1}
multi plus1(Int:D $i, @j){ plus1($i) + plus1(@j) - 1 }
multi plus1(%h){ ([+] %h.values) + 1 }
plan 9;
is plus1([1, 3, 5, 3]), 13, 'plus1([1, 3, 5, 3])';
is plus1(3, [1, 3, 5, 3]), 16, 'plus1(3, [1, 3, 5, 3])';
is plus1(3, True), 5, 'plus1(3, True)';
is (&plus1 ⍣ 0)(4), 4, '(&plus1 ⍣ 0)(4)';
is (&plus1 ⍣ 10)(4), 14, '(&plus1 ⍣ 10)(4)';
is (&plus1 ⍣ 10)([1, 3, 5, 3]), 22, '(&plus1 ⍣ 10)([1, 3, 5, 3])';
is (&plus1 ⍣ 3)(4, True), 8, '(&plus1 ⍣ 3)(4, True)';
is (&plus1 ⍣ 3)(3, [1, 3, 5, 3]), 18, '(&plus1 ⍣ 3)(3, [1, 3, 5, 3])';
is (&plus1 ⍣ 3)({a => 1, b => 3, c => 5}), 12, '(&plus1 ⍣ 3)({a => 1, b => 3, c => 5})';
done-testing;
([+] @j)
可以写成[+]( @j )
(]
和(
之间没有空格)。您也可以完全不使用括号来编写它,例如1 + [+] @j
或[+] 1, |@j
。 - Brad Gilbert