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

drc*_*law 8 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;
Run Code Online (Sandbox Code Playgroud)

输出为:

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, *%_)
Run Code Online (Sandbox Code Playgroud)

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

使用Whatever会以某种方式更改此设置。为什么会发生此错误?提前致谢

jjm*_*elo 7

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

简短的答案:xx与一起具有特殊的含义Whatever,因此不会WhateverCode像在其余示例中那样创建。

让我们看看我能否用长答案就直截了当。

首先,定义。*被称为Whatever。通常用于需要咖喱的地方

我对这个名称不太满意,该名称指向函数语言-curying,但似乎并没有在这种意义上使用,而是在烘烤的意义上使用。无论如何。

咖喱它变成它WhateverCode。因此,*本身就是Whatever,*带有某些东西就是WhateverCode,凭空创建了一个块。

但是,这并不是自动发生的,因为有时我们需要“无论是什么”。您Whatever文档中列出了一些例外情况。其中之一正在使用xx,因为和xx一起Whatever应创建无限列表。

可以这么说,但这不是我在做什么。*在前面的数量倍增。嗯,是。但是,Actions.nqp(从源代码生成代码)中的这段代码引用了infix xx。因此,这并不重要。

所以,回简短的回答:你不能总是使用*与其它元素来创建代码。某些运算符(例如,..或...)在*附近具有特殊含义,因此您需要使用其他运算符,例如占位符参数。

  • 问题是,如果您愿意,则是xx字面量在字面上是“左”。所以`* xx 2`实际上是((*,*)。Seq`。* xx *是*的无穷Seq(又名“ Whatever”)。为什么'* xx ...'不咖喱的决定,在我的迷雾中迷失了。 (4认同)
  • Whatever文档中的特殊情况显示“ 1 xx *”作为*何时保持Whatever的示例。但是,在我的情况下,我将它与参数以相反的方式与** xx 2一起使用。如果不深入探讨NQP代码(我对Perl6来说还很陌生,更不用说NQP了),也许特殊情况列表似乎只关心运算符(xx)而不是它的参数?感谢您的回复。很多代码需要阅读..最终:) (2认同)
  • @RubenWesterberg。正如我上面所说的,它不关注例程签名,而只是关注例程本身。这是一个很好的问题,让他们继续前进:-) (2认同)

Bra*_*ert 7

xx运营商是“thunky”。

say( rand xx 2 );
# (0.7080396712923503 0.3938678220039854)
Run Code Online (Sandbox Code Playgroud)

注意rand执行了两次。x而且X不要那样做。

say( rand x 2 );
0.133525574759261740.13352557475926174

say( rand X 1,2 );
((0.2969453468495996 1) (0.2969453468495996 2))
Run Code Online (Sandbox Code Playgroud)

这就是说,xx每一方本身都像是lambda。
(一个“ thunk”)

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

say (* + 1 xx 2)».(5);
# (6 6)
Run Code Online (Sandbox Code Playgroud)

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

say (* xx 2).map: {.^name}
# (Whatever Whatever)
Run Code Online (Sandbox Code Playgroud)

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


这也意味着您无法使用&& /  and|| /  or^^ /  xor或来创建WhateverCode闭包//

say (* && 1);
# 1
Run Code Online (Sandbox Code Playgroud)

请注意,*它在的右侧也有不同之处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)
Run Code Online (Sandbox Code Playgroud)

如果xx不是“厚实的”,那么这还将创建一个WhateverCode lambda。