10

我有一个使用 perl6 的子集命令和一些专门针对这些类型的多子集构建的类型层次结构。当多分派发生时,如何为最窄子类型专门化的子提供最高优先级?

这是简化的代码:

#! /usr/bin/env perl6

use v6.c;

proto check($value) { * }

subset Positive of Int where * > 0;

subset PositiveEven of Positive where * %% 2;

multi check(Int $value) {
    say "integer"
}

multi check(Positive $value) {
    say "positive"
}

multi check(PositiveEven $value) {
    say "positive & even"
}

# example:
check(32);

# expected output:
#   positive & even

# actual output:
#   positive 
4

2 回答 2

10

由于所有候选者都同样紧张,因此它将采用第一个与约束的其余部分相匹配(或缺少约束)的候选者。这是指定多个候选者的顺序变得重要的时候。如果您按此顺序指定它们:

multi check(PositiveEven $value) { say "positive & even" }
multi check(Positive $value) { say "positive" }
multi check(Int $value) { say "integer" }

以下满足您的期望:

check(32);   # positive & even
于 2019-01-23T13:45:51.053 回答
5

主要问题是子集实际上不是类型,只是约束。如果你这样做

say :(PositiveEven $value).perl;
say :(Positive $value).perl;
say :(Int $value).perl;

您将获得

:(Int $value where { ... })
:(Int $value where { ... })
:(Int $value)

虽然最新的一个明显不同,但另外两个在签名上没有区别,因此使用找到的第一个。您将需要将它们声明为类或找到另一种通过签名来区分它们的方法,或者在子本身内部使用nextsame

proto check($value) { * }

subset PositiveEven of UInt where * %% 2;

multi check(Int $value) {
    say "integer"
}

multi check(UInt $value) {
    if $value ~~ PositiveEven {
    nextsame;
    }
    say "positive"
}

multi check(PositiveEven $value) {
    say "positive & even"
}

这将按positive & even预期返回。您甚至不需要将最后一个子的 arg 定义为PositiveEven,但可以将其留在那里以提供信息。

于 2019-01-23T11:16:40.770 回答