Perl 6的多调度如何决定使用哪种例程?

bri*_*foy 4 signature perl6 multidispatch

考虑一下我在参数列表中构造一个Array的程序.虽然有一个接受数组的签名,但这会调用接受List的签名:

foo( [ 1, 2, 3 ] );

multi foo ( Array @array ) { put "Called Array @ version" }
multi foo ( Array $array ) { put "Called Array \$ version" }
multi foo ( List $list )   { put "Called List version" }
multi foo ( Range $range ) { put "Called Range version" }
Run Code Online (Sandbox Code Playgroud)

我得到了意外例程的输出:

Called Array $ version
Run Code Online (Sandbox Code Playgroud)

如果我取消注释其他签名,则会调用该签名:

Called List version
Run Code Online (Sandbox Code Playgroud)

为什么不称它为( Array @array )版本?调度员如何做出决定(以及记录在哪里)?

rai*_*iph 5

为什么不调用(Array @array)版本?

您的测试foo调用只有一个Array( [1,2,3])作为它的参数,而不是一个数组 Array S(例如[[1,2,3],[4,5,6]]).

(@in @array表示一个值does Positional,例如数组或列表.Array @array表示相同的东西,但附加约束,数组,列表或其他任何元素都是Array.)

调度员如何做出决定?

简化,它选择最窄的匹配类型:

multi foo ( Array       )              {} # Narrowest
multi foo ( List        )              {} # Broader
multi foo ( Positional  )              {} # Broader still
multi foo ( @array      )              {} # Same as `Positional`
Run Code Online (Sandbox Code Playgroud)

(Array,List和的子类型关系图Positional)

有关详细信息,请参阅jnthn对相关SO问题的权威答案.

(以及它在哪里记录)?

我不确定这个文件.多调度看起来很小.