像函数一样传递运算符

anq*_*egi 23 raku

在学习 Raku 的同时,我到达了高阶函数和排序函数的点。

我有这个例子:

> sort <4 6 2 9 1 5 11>
(1 2 4 5 6 9 11)
Run Code Online (Sandbox Code Playgroud)

然后例程的文档是这样说的:

Sorts the list, smallest element first. By default infix:<cmp>  is used for
comparing list elements.
Run Code Online (Sandbox Code Playgroud)

我正在关注的那本书“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'?
Run Code Online (Sandbox Code Playgroud)

但是遇到这个问题,而不是按字典顺序排列的排序列表。所以可能对我来说理解这一点还为时过早,但应该可以像函数一样在 Raku 中传递一个运算符,因为文档还说它正在使用中缀:或者我需要做这样的事情,也许我' m 混淆运算符和子程序:

sub my-le($a,$b) {
    $a le $b;
}

sort &my-le, <4 6 2 9 1 5 11>;
Run Code Online (Sandbox Code Playgroud)

或这个:

   sort { $^b le $^a  }, <4 6 2 9 1 5 11>;
Run Code Online (Sandbox Code Playgroud)

所以我有一个关于不同使用中缀运算符和一个子程序的问题,也许这种差异的问题是操作数的顺序会影响某些操作的结果。所以你不能这么轻易地将它作为函数或参数或变量传递

> 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)
Run Code Online (Sandbox Code Playgroud)

我希望我能解释我对这个问题的怀疑。

Sci*_*mon 19

le运营商的定义是这样的:

sub infix:<le> { ... }
Run Code Online (Sandbox Code Playgroud)

infix:前缀告诉它是一个管道符的语言。因此,如果您想调用 is as a sub its &infix:<le>(1,2)or for your sort :

sort &infix:<le>, <4 6 2 9 1 5 11>;
(9 6 5 4 2 11 1)
Run Code Online (Sandbox Code Playgroud)

这可能会有所帮助https://docs.raku.org/language/optut


jak*_*kar 12

添加到 Scimon 的答案中,如果您想要更“清晰”的演示,您可以使用以下任何结构:

sort *le*, <4 6 2 9 1 5 11>;
Run Code Online (Sandbox Code Playgroud)

前面的代码是一个whatever构造(代码对象)。

what 构造使用多个 * 来生成具有尽可能多参数的代码块(匿名子例程):

my $c = * + *;   # same as   -> $a, $b { $a + $b }
Run Code Online (Sandbox Code Playgroud)

这意味着使用任何符号 (*) 来表示计算中使用的两个(或更多)参数

我们的案例也是如此:

sort *le*, <4 6 2 9 1 5 11>;
Run Code Online (Sandbox Code Playgroud)

是相同的 :

sort * le *, <4 6 2 9 1 5 11>;   # adding space between operator and the whatever sign (*)
Run Code Online (Sandbox Code Playgroud)

这反过来与:

sort -> $a, $b { $a le $b }, <4 6 2 9 1 5 11>;   # anonymous subroutine
 
Run Code Online (Sandbox Code Playgroud)

或者

sort { $^a le $^b }, <4 6 2 9 1 5 11>;
Run Code Online (Sandbox Code Playgroud)

甚至

sub le {
    $^a le $^b
}

sort &le, <4 6 2 9 1 5 11>;
Run Code Online (Sandbox Code Playgroud)

参考:

https://docs.raku.org/type/Whatever

https://docs.raku.org/type/Block

  • FWIW,为了清楚起见,我会用额外的空格来写:`sort * le *, &lt;4 6 2 9 1 5 11&gt;`。否则,人们可能会认为“*le*”本身就是一个东西。 (2认同)
  • 这是一个很棒的更新,也是 TIMTOWDI 实际应用的完美示例。两个选项同样有效。 (2认同)