子集块(或一般的 Callables)

Subsetting Blocks (or Callables in general)

question was originally posted by lookatme in the Perl6 IRC channel. The original intention is to constrain a Callable by using subsets 或任何其他可能的方式。它适用于签名,但是:

subset WalkCb of Callable where *.signature ~~ :(Int $a); 
my WalkCb $x = sub (Int $a) { return $a; };

returns

«Type check failed in assignment to $x; expected WalkCb but got Sub (sub (Int $a) { #`(Sub...)␤  in block <unit> at <tmp> line 1␤␤»

声明的其他变体return 类似的消息。正确的语法是什么?

在这种情况下,WhateverCode 解析似乎出现了问题。因此,如果您在 where:

中指定一个块
subset WalkCb of Callable where { .signature ~~ :(Int $) }
my WalkCb $x = sub (Int $a) { return $a; }

它似乎按预期工作。另请注意,我删除了行尾的 ;,因为行尾的 } 也是语句的结尾。并且我从签名中删除了 "a":忽略签名智能匹配中位置参数的名称。

where 约束可以采用块 (lambda) 或语句。

… where { $_ == 42 }; # block
… where    * == 42;   # lambda
… where   $_ == 42;   # statement

问题是 ~~ 不参与创建 WhateverCode lambdas (*)
所以你真正在做的是在更大的 where 语句 (不是 lambda)中创建一个 *.signature 的 lambda。

constant $lambda = *.signature;
subset WalkCb of Callable where $lambda ~~ :(Int $);

当然永远不会 return True 因为 lambda 的签名是 :(;; $ is raw)


因此,只需编写声明表格即可。 (使用隐式 $_

subset WalkCb of Callable where .signature ~~ :(Int $);
my WalkCb $x = sub (Int $a) { return $a }
say $x(42); # 42␤