首页 > 解决方案 > 子集块(或一般的可调用对象)

问题描述

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

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␤␤»

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

标签: signaturerakusubtyping

解决方案


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

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

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

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

这当然永远不会返回True,因为 lambda 的签名为:(;; $ is raw)


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

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

推荐阅读