Perl 6 уменьшает функцию, а метаоператор сокращения дает разные результаты

12
my @s=<1 2 3 2 3 4>;
say reduce {$^a < $^b}, @s;
say [<] @s;
# --------
# True
# False

У меня два вопроса: во-первых, почему метаоператор редукции обрабатывает <оператор по-разному? Похоже, что метаопция редукции использует переменную, которая при первом изменении true на false сохраняет это изменение, потому что:

say [\<] @s;
# ----------
# (True True True False False False)

Во-вторых, я бы хотел использовать это и в функции сокращения, то есть ввести некоторый код в фигурные скобки функции сокращения, чтобы он давал тот же результат, что и мета-оператор сокращения. Как мне это сделать? Спасибо.

Romario
источник

Ответы:

17

Как мета-оператор, так и reduceучитывают ассоциативность передаваемого им оператора; в случае <оператор является цепочкой.

При передаче пользовательского блока reduceне может видеть внутри него, и поэтому он возвращается к значению по умолчанию слева-ассоциативно; затем он сравнивает более поздние значения с логическим значением, возвращаемым из редуктора, который нумерует 0или 1, и поэтому результат заканчивается как Trueв конце.

Вы можете получить желаемую семантику, объявив свою функцию редукции как имеющую цепную ассоциативность:

my @s1 =<1 2 3 2 3 4>;
my @s2 =<1 2 3 4>;
sub my-reducer($a, $b) is assoc('chain') {
    $a < $b
}
say reduce &my-reducer, @s1;    # False
say reduce &my-reducer, @s2;    # True
Джонатан Уортингтон
источник