子集块(或一般的Callables)

时间:2018-05-17 06:39:08

标签: signature perl6 subtyping

question was originally posted by lookatme in the Perl6 IRC channel。最初的意图是constrain a Callable using subsets或任何其他可能的方式。它适用于签名,但是:

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

返回

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

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

2 个答案:

答案 0 :(得分:7)

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

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

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

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

当然,由于lambda的签名为True

,所以当然不会返回:(;; $ is raw)

所以只需编写声明表单即可。 (使用隐式$_

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

答案 1 :(得分:6)

在这种情况下,indexOf("<")解析会出现问题。因此,如果您在WhateverCode中指定了一个块:

where

它似乎按预期工作。另请注意,我删除了行尾的subset WalkCb of Callable where { .signature ~~ :(Int $) } my WalkCb $x = sub (Int $a) { return $a; } ,因为行尾的;也是语句的结尾。我从签名中删除了“a”:忽略了签名智能匹配中位置参数的名称。