这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»
声明的其他变体返回类似的消息。什么是正确的语法?
答案 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”:忽略了签名智能匹配中位置参数的名称。