比方说,我们有以下multi sub
:类型数组
multi sub abc(Int @array) { say 10, ' ', @array; }
multi sub abc(Array[Int] @array) { say 20, ' ', @array; }
multi sub abc(Str @array) { say 30, ' ', @array; }
multi sub abc(Array[Str] @array) { say 40, ' ', @array; }
正如this question提到的,调用这些有类型的数组可以得到详细:
abc Array[Int].new([1,2,3]);
abc Array[Array[Int]].new([Array[Int].new([1,2,3]), Array[Int].new([2,3,4])]);
这将是很好如果类型可以从字面上推断出来,我们可以这样做:
abc typed([1,2,3]);
abc typed([[1,2,3],[2,3,4]]);
abc typed(['a', 'b', 'c']);
abc typed([['a', 'b', 'c'], ['b', 'c', 'd']]);
进一步说,让我们添加它执行的类型推断我们的条款:
multi sub abc(@array) { abc typed(@array); }
现在我们可以得到充分的推理,没有额外征收的语法:
abc [1,2,3];
abc [[1,2,3],[2,3,4]];
abc ['a', 'b', 'c'];
abc [['a', 'b', 'c'], ['b', 'c', 'd']];
上面显示以下内容:
10 [1 2 3]
20 [[1 2 3] [2 3 4]]
30 [a b c]
40 [[a b c] [b c d]]
下面是一个简单的版本typed
其对作品:
Array[Int]
Array[Array[Int]]
Array[Str]
Array[Array[Str]]
我的问题是,你将如何去实现这种类型推断的?有更好的方法吗?是否有类似的设施?
sub type-of(\obj)
{
if obj.^name eq 'Array'
{
if obj.map({ type-of($_).^name }).all eq obj.map({ type-of($_).^name })[0]
{
my $type = type-of(obj[0]);
return Array[$type];
}
return Array;
}
if obj.^name eq 'Int' { return Int; }
if obj.^name eq 'Str' { return Str; }
}
sub typed(\obj)
{
if obj.^name eq 'Array'
{
return type-of(obj)(obj.List.map({ $_.&typed }).Array);
}
return (type-of(obj))(obj);
}