у perl6 вызывать правый мульти-суб специализированный по подтипу (подмножеству) - PullRequest
0 голосов
/ 23 января 2019

У меня есть иерархия типов, созданная с помощью команды подмножества 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 

Ответы [ 2 ]

0 голосов
/ 23 января 2019

Так как все кандидаты одинаково стеснены, будет выбран первый, соответствующий остальному ограничению (или его отсутствию). Это когда порядок , в котором указаны несколько кандидатов, становится важным. Если бы вы указали их в следующем порядке:

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

Следующее будет делать то, что вы ожидаете:

check(32);   # positive & even
0 голосов
/ 23 января 2019

Основная проблема заключается в том, что подмножества на самом деле не являются типами, это просто ограничения.Если вы сделаете

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, как и ожидалось.Вам даже не нужно определять аргумент последней подпрограммы как PositiveEven, но это нормально, чтобы оставить его там для информативных целей.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...