比方說,我們有以下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);
}