地图签名与任何内容都不匹配? x vs X vs xx

时间:2019-03-03 04:26:31

标签: perl6

此处的最后一行导致对地图调用的签名不正确:

my @array=[0,1,2];
say "String Repetition";
say @array.map({($_ x 2)});
say @array.map: * x 2;

say "\nCross product ";
say @array.map({($_ X 2)});
say @array.map: * X 2;

say "\nList Repetition";
say @array.map({$_ xx 2});
say @array.map: * xx 2;

输出为:

String Repetition
(00 11 22)
(00 11 22)

Cross product 
(((0 2)) ((1 2)) ((2 2)))
(((0 2)) ((1 2)) ((2 2)))

List Repetition
((0 0) (1 1) (2 2))
Cannot resolve caller map(Array:D: Seq:D); none of these signatures match:
    ($: Hash \h, *%_)
    (\SELF: █; :$label, :$item, *%_)

x运算符返回一个Str,X运算符返回一个列表列表,而xx返回一个列表。

使用Whatever,这是否有所改变?为什么会发生此错误?预先感谢

2 个答案:

答案 0 :(得分:7)

让我看看我能否清楚地做到这一点。如果我不这样做,请询问。

简短的回答:xxWhatever一起具有特殊的含义,因此它不会像其余示例中那样创建WhateverCode

让我们看看我能不能用长篇幅的答案弄清楚这一点。

首先,定义。 *称为Whatever。它通常用于咖喱

  

我对这个名字不太满意,这个名字指向函数语言-currying,但似乎并没有在这个意义上使用,而是在 steching 烘焙。无论如何。

通过加密将其转换为WhateverCode。因此,*本身就是Whatever,*带有某些东西就是WhateverCode,凭空创建了一个块。

但是,这并不是自动发生的,因为有时我们需要“无论是什么”。 listed on Whatever documentation例外。其中之一正在使用xx,因为xxWhatever一起会创建无限列表。

但是,这不是我在做什么。 *在要乘数的前面。嗯,是。但是Actions.nqp中的this code(从源代码生成代码)指的是中缀 xx。因此,这并不重要。

因此,回到简短的答案:您不能始终始终将*与其他元素一起使用来创建代码。一些运算符(例如,..或...)在*附近具有特殊含义,因此您需要使用其他运算符,例如占位符参数。

答案 1 :(得分:7)

xx运算符是“ thunky”。

say( rand xx 2 );
# (0.7080396712923503 0.3938678220039854)

请注意,rand被执行了两次。 xX不会这样做。

say( rand x 2 );
0.133525574759261740.13352557475926174

say( rand X 1,2 );
((0.2969453468495996 1) (0.2969453468495996 2))

也就是说xx本身将每一面都看作是lambda。
(“暴徒”)

say (* + 1 xx 2);
# ({ ... } { ... })

say (* + 1 xx 2)».(5);
# (6 6)

因此,您得到*的序列重复两次。

say (* xx 2).map: {.^name}
# (Whatever Whatever)

(术语*是Whatever的一个实例)


这也意味着您无法使用&& / and|| / or^^ // {{1} }或xor

//

请注意,say (* && 1); # 1 *的右侧也有不同之处。
它创建了一个无限序列。

xx

如果say ( 2 xx * ).head(20); # (2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2) 并不“笨拙”,那么这还将创建一个WhateverCode lambda。