Ответ 1
Это потому, что &infix:<∈>
является мульти, while &infix:<∉>
не является:
$ perl6 -e '&infix:<∈>.candidates.head.multi.say'
True
$ perl6 -e '&infix:<∉>.candidates.head.multi.say'
False
Когда вы определили свой multi &infix:<∉>
, вы затенены only &infix:<∉>
из основного, и именно поэтому вы видите только своего кандидата.
Вероятно, мы можем обнаружить такую ситуацию и потребовать от пользователя предоставления явного proto
чтобы уточнить, что они означают. Я подал это как R # 1530. И я бы сказал, что такие различия, что один оп является multi
, а другой является only
частью более широкого вопроса наличия согласованного ядра; Я добавил его в качестве комментария к RT # 130020 и упомянул проблему в наших документах на D # 1783.
Вы могли бы определить свой собственный op так (если предложение в R#1530
реализовано, proto
будет требоваться, в настоящее время это не так):
proto infix:<∉> (|) {*}
multi infix:<∉> ($a, Complement:D $c) { $a ∈ $c.set }
multi infix:<∉> (|c) { &CORE::infix:<∉>(|c) }
Я могу только догадываться, что вы пытаетесь закодировать, но подумал, что я упоминал об этом, потому что вы должны учитывать это в своем творчестве: отрицательные операторы определяются как not A (op) B
, а не A (not(op)) B
Эта небольшая разница имеет влияние, когда дело доходит до Junctions
:
$ perl6 -e 'say 2 ≠ 2|4'
False
Если бы он был определен как отрицаемый op, применяемый к каждому операнду, вышеупомянутое было бы эквивалентно (2 ≠ 2 or 2 ≠ 4)
и всегда было бы True
, что часто не то, что имел бы в виду программист, следовательно, почему вычислено как not (2 == 2 or 2 == 4)
Чтобы ответить на комментарии Jarrod о OP: subs (включая мутации грамматики, сделанные объявлением пользовательских операторов), являются лексическими, поэтому, если вы завернули объявление в блок BEGIN
, пользовательский op будет привязан к этому блоку.
И причина, по которой он работал в REPL, состоит в том, что на самом деле есть ошибка (RT # 131900), где пользовательские операционные системы теряются между линиями REPL, так же, как и с блоком BEGIN
, к моменту вызова с аргументами, предназначенными для основных кандидатов, пользовательский мультисъемка больше не был в сфере охвата.