Fab*_*rey 10 string lambda raku
我正在学习 Raku 作为一个热情的项目,我想实现一个简单的fizzbuzz,为什么join只有当我用尖头块编写 lambda 时才能保留嗡嗡声?
my $iif =-> $x,$y,$z {if $x {$y} else {$z}}
my $modToString =-> $x,$y,$z {$iif($x%%$y,$z,'')}
my $FB =-> $x {join($modToString($x,3,'fizz'),$modToString($x,5,'buzz'))}
my $logic =-> $x {$iif($FB($x),$FB($x),$x)}
say map(-> $x {$logic($x)}, 1..100)
$modToString(1,3,'fizz')
>
$modToString(3,3,'fizz')
> fizz
$modToString(3,5,'buzz')
>
$modToString(5,5,'buzz')
> buzz
Run Code Online (Sandbox Code Playgroud)
如果我将尖头块变量转换为占位符变量,Rakudo 会抛出错误:
my $iif = {if $^x {$^y} else {$^z}};
my $modToString = {$iif($^x%%$^y,$^z,'')};
my $FB = {join($modToString($^x,3,'fizz'),$modToString($^x,5,'buzz'))}
my $logic = {$iif($FB($^x),$FB($^x),$^x)}
say map(-> $x {$logic($x)}, 1..100)
Too many positionals passed; expected 1 argument but got 3
in block at <unknown file> line 1
in block at <unknown file> line 1
in block at <unknown file> line 1
in block at <unknown file> line 1
in block <unit> at <unknown file> line 1
Run Code Online (Sandbox Code Playgroud)
如果我将联接参数放在括号中,它只会输出数字:
my $iif =-> $x,$y,$z {if $x {$y} else {$z}}
my $modToString =-> $x,$y,$z {$iif($x%%$y,$z,'')}
my $FB =-> $x {join(<$modToString($x,3,'fizz'),$modToString($x,5,'buzz')>)}
my $logic =-> $x {$iif($FB($x),$FB($x),$x)}
say map(-> $x {$logic($x)}, 1..100)
Run Code Online (Sandbox Code Playgroud)
为什么?
Sil*_*olo 14
因为Raku 中的很多东西都是块,甚至是看起来不像的东西。特别是,这包括控制流的“参数”,例如if。
if 1 { 2 } else { 3 }
Run Code Online (Sandbox Code Playgroud)
我们实际上在这里写了两个块。一种是返回常量函数2,另一种是返回常量函数3。现在,通常这对我们来说是透明的,并且 Raku 引擎足够智能,可以将这些编译掉。但他们还在那里。事实上,我们可以将它们明确化。以下语句的行为与上述if语句相同。
if 1 -> { 2 } else -> { 3 }
Run Code Online (Sandbox Code Playgroud)
然而,就你而言,它最终很重要。匿名参数(带有 twigil 的参数^)绑定到最里面的块。所以你已经写了
{if $^x {$^y} else {$^z}}
Run Code Online (Sandbox Code Playgroud)
你的意图是它相当于
-> $x, $y, $z {if $x {$y} else {$z}}
Run Code Online (Sandbox Code Playgroud)
但你实际写的是
-> $x {if $x -> $y {$y} else -> $z {$z}};
Run Code Online (Sandbox Code Playgroud)
因此,您实际上已经编写了一个只有一个参数的函数,并向其传递了三个参数,如错误消息所述。
作为一个广泛的规则,您通常可以假设任何时候您看到 a {,它要么开始一个散列文字,要么开始一个块。后者总是引入局部变量和参数可以存在的范围。
在您的特定情况下,您可以使用三元运算符(这与大多数其他语言(如 C++ 或 Java)??!!相同)?:
{$^x ?? $^y !! $^z}
Run Code Online (Sandbox Code Playgroud)
该运算符不会短路,也不会引入块,因此它可以正常工作。