像函数一样传递运算符
Pass an operator like a function
在学习Raku的过程中,我到了高阶函数和排序函数的地步。
我有这个例子:
> sort <4 6 2 9 1 5 11>
(1 2 4 5 6 9 11)
然后例程的文档是这样说的:
Sorts the list, smallest element first. By default infix:<cmp> is used for
comparing list elements.
我正在阅读的书 "Piensa en raku" 在第 9.2 节中对数字排序和字典排序进行了比较。
我尝试了以下方法:
> sort &le, <4 6 2 9 1 5 11>;
===SORRY!=== Error while compiling:
Undeclared routine:
le used at line 1. Did you mean 'lc'?
但得到这个问题,而不是按字典顺序排列的排序列表。所以对我来说理解这一点可能还为时过早,但应该可以像函数一样在 Raku 中传递一个运算符,因为文档也说它正在使用中缀:或者我需要做这样的事情,也许我m 令人困惑的运算符和子例程:
sub my-le($a,$b) {
$a le $b;
}
sort &my-le, <4 6 2 9 1 5 11>;
或者这个:
sort { $^b le $^a }, <4 6 2 9 1 5 11>;
所以我有关于中缀运算符和子例程的不同使用的问题,也许关于这种差异的问题是操作数的顺序影响某些操作的结果。所以你不能这么轻易地将它作为函数或参数或变量传递
> sort { $^a le $^b }, <4 6 2 9 1 5 11>
(9 6 5 4 2 11 1)
> sort { $^b le $^a }, <4 6 2 9 1 5 11>
(1 11 2 4 5 6 9)
希望能解释一下我对这个问题的疑惑
le
运算符定义如下:
sub infix:<le> { ... }
infix:
前缀告诉语言它是中缀运算符。所以如果你想调用 is 作为它的子 &infix:<le>(1,2)
或者你的排序 :
sort &infix:<le>, <4 6 2 9 1 5 11>;
(9 6 5 4 2 11 1)
这可能会有所帮助 https://docs.raku.org/language/optut
添加到 Scimon 的答案中,如果您想要更“清晰”的演示,您可以使用以下任何结构:
sort *le*, <4 6 2 9 1 5 11>;
前面的代码是一个 whatever 构造(代码对象)。
whatever 构造使用多个 * 生成具有尽可能多参数的代码块(匿名子例程):
my $c = * + *; # same as -> $a, $b { $a + $b }
这意味着无论符号 (*) 用于表示计算中使用的两个(或更多)参数
我们的案例也是如此:
sort *le*, <4 6 2 9 1 5 11>;
等同于:
sort * le *, <4 6 2 9 1 5 11>; # adding space between operator and the whatever sign (*)
而这与 :
相同
sort -> $a, $b { $a le $b }, <4 6 2 9 1 5 11>; # anonymous subroutine
或
sort { $^a le $^b }, <4 6 2 9 1 5 11>;
甚至
sub le {
$^a le $^b
}
sort &le, <4 6 2 9 1 5 11>;
参考文献:
在学习Raku的过程中,我到了高阶函数和排序函数的地步。
我有这个例子:
> sort <4 6 2 9 1 5 11>
(1 2 4 5 6 9 11)
然后例程的文档是这样说的:
Sorts the list, smallest element first. By default infix:<cmp> is used for
comparing list elements.
我正在阅读的书 "Piensa en raku" 在第 9.2 节中对数字排序和字典排序进行了比较。
我尝试了以下方法:
> sort &le, <4 6 2 9 1 5 11>;
===SORRY!=== Error while compiling:
Undeclared routine:
le used at line 1. Did you mean 'lc'?
但得到这个问题,而不是按字典顺序排列的排序列表。所以对我来说理解这一点可能还为时过早,但应该可以像函数一样在 Raku 中传递一个运算符,因为文档也说它正在使用中缀:或者我需要做这样的事情,也许我m 令人困惑的运算符和子例程:
sub my-le($a,$b) {
$a le $b;
}
sort &my-le, <4 6 2 9 1 5 11>;
或者这个:
sort { $^b le $^a }, <4 6 2 9 1 5 11>;
所以我有关于中缀运算符和子例程的不同使用的问题,也许关于这种差异的问题是操作数的顺序影响某些操作的结果。所以你不能这么轻易地将它作为函数或参数或变量传递
> sort { $^a le $^b }, <4 6 2 9 1 5 11>
(9 6 5 4 2 11 1)
> sort { $^b le $^a }, <4 6 2 9 1 5 11>
(1 11 2 4 5 6 9)
希望能解释一下我对这个问题的疑惑
le
运算符定义如下:
sub infix:<le> { ... }
infix:
前缀告诉语言它是中缀运算符。所以如果你想调用 is 作为它的子 &infix:<le>(1,2)
或者你的排序 :
sort &infix:<le>, <4 6 2 9 1 5 11>;
(9 6 5 4 2 11 1)
这可能会有所帮助 https://docs.raku.org/language/optut
添加到 Scimon 的答案中,如果您想要更“清晰”的演示,您可以使用以下任何结构:
sort *le*, <4 6 2 9 1 5 11>;
前面的代码是一个 whatever 构造(代码对象)。
whatever 构造使用多个 * 生成具有尽可能多参数的代码块(匿名子例程):
my $c = * + *; # same as -> $a, $b { $a + $b }
这意味着无论符号 (*) 用于表示计算中使用的两个(或更多)参数
我们的案例也是如此:
sort *le*, <4 6 2 9 1 5 11>;
等同于:
sort * le *, <4 6 2 9 1 5 11>; # adding space between operator and the whatever sign (*)
而这与 :
相同sort -> $a, $b { $a le $b }, <4 6 2 9 1 5 11>; # anonymous subroutine
或
sort { $^a le $^b }, <4 6 2 9 1 5 11>;
甚至
sub le {
$^a le $^b
}
sort &le, <4 6 2 9 1 5 11>;
参考文献: