子集块(或一般的Callables)

jjm*_*elo 6 signature perl6 subtyping

问题最初由lookatmePerl6 IRC频道发布.最初的目的是通过使用子集或任何其他可能的方式来约束Callable.它适用于签名,但是:

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

回报

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

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

Bra*_*ert 7

一个where约束可以拿块(拉姆达)或者声明.

… where { $_ == 42 }; # block
… where    * == 42;   # lambda
… where   $_ == 42;   # statement
Run Code Online (Sandbox Code Playgroud)

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

constant $lambda = *.signature;
subset WalkCb of Callable where $lambda ~~ :(Int $);
Run Code Online (Sandbox Code Playgroud)

当然True,由于lambda具有签名,因此永远不会返回:(;; $ is raw)


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

subset WalkCb of Callable where .signature ~~ :(Int $);
my WalkCb $x = sub (Int $a) { return $a }
say $x(42); # 42?
Run Code Online (Sandbox Code Playgroud)


Eli*_*sen 6

WhateverCode在这种情况下,解析似乎变得混乱.因此,如果您在以下位置指定一个块where:

subset WalkCb of Callable where { .signature ~~ :(Int $) }
my WalkCb $x = sub (Int $a) { return $a; }
Run Code Online (Sandbox Code Playgroud)

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