让 perl6 调用由子类型(子集)专门化的正确的多子
have perl6 invoke the right multi sub specialized by subtype(subset)
我有一个用 perl6 的 subset 命令和一些专门针对这些类型的 multi subs 构建的类型层次结构。发生多重调度时,如何为最窄子类型特化的子提供最高优先级?
这里是简化的代码:
#! /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
主要问题是子集实际上不是类型,只是约束。
如果你这样做
say :(PositiveEven $value).perl;
say :(Positive $value).perl;
say :(Int $value).perl;
您将获得
:(Int $value where { ... })
:(Int $value where { ... })
:(Int $value)
虽然最新的明显不同,但其他两个在签名上没有区别,因此使用第一个找到的。您需要将它们声明为 类 或找到另一种通过签名区分它们的方法,或者在 sub 内部使用 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"
}
这将 return positive & even
正如预期的那样。您甚至不需要将最后一个 sub 的 arg 定义为 PositiveEven
,但出于提供信息的目的将其保留在那里是可以的。
由于所有候选项都同样紧,因此将采用第一个匹配其余约束(或不匹配)的候选项。这是指定多个候选的 order 变得重要的时候。如果您按此顺序指定它们:
multi check(PositiveEven $value) { say "positive & even" }
multi check(Positive $value) { say "positive" }
multi check(Int $value) { say "integer" }
以下将做你期望的事情:
check(32); # positive & even
我有一个用 perl6 的 subset 命令和一些专门针对这些类型的 multi subs 构建的类型层次结构。发生多重调度时,如何为最窄子类型特化的子提供最高优先级?
这里是简化的代码:
#! /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
主要问题是子集实际上不是类型,只是约束。 如果你这样做
say :(PositiveEven $value).perl;
say :(Positive $value).perl;
say :(Int $value).perl;
您将获得
:(Int $value where { ... })
:(Int $value where { ... })
:(Int $value)
虽然最新的明显不同,但其他两个在签名上没有区别,因此使用第一个找到的。您需要将它们声明为 类 或找到另一种通过签名区分它们的方法,或者在 sub 内部使用 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"
}
这将 return positive & even
正如预期的那样。您甚至不需要将最后一个 sub 的 arg 定义为 PositiveEven
,但出于提供信息的目的将其保留在那里是可以的。
由于所有候选项都同样紧,因此将采用第一个匹配其余约束(或不匹配)的候选项。这是指定多个候选的 order 变得重要的时候。如果您按此顺序指定它们:
multi check(PositiveEven $value) { say "positive & even" }
multi check(Positive $value) { say "positive" }
multi check(Int $value) { say "integer" }
以下将做你期望的事情:
check(32); # positive & even