Фильтрующие элементы, соответствующие двум регулярным выражениям в Perl 6 - PullRequest
0 голосов
/ 30 сентября 2018

Здесь происходит что-то, чего я не совсем понимаю.

> my @arr = <ac bc abc>
> @arr.grep: (( * ~~ /a/ ) && ( * ~~ /b/ ))
(bc abc)

Но

> @arr.grep(* ~~ /a/).grep(* ~~ /b/)
(abc)

В чем причина?

1 Ответ

0 голосов
/ 30 сентября 2018

Вы придумали совершенно громоздкие решения.

Другой вариант:

my @arr = <ac bc abc>
@arr.grep: { $_ ~~ /a/ && $_ ~~ /b/ }
(abc)

Остальная часть этого ответа просто объясняет проблему.Проблема в этом вопросе является более сложной версией проблемы, описанной в WhwhatStar && Wh whatStar .


Логические операции не выполняют свои аргументы, если они являются кодом.

То есть { $_ ~~ /a/ } && { $_ ~~ /b/ } возвращает { $_ ~~ /b/ }.

Или * ~~ /a/ && * ~~ /b/ возвращает * ~~ /b/.

В то же время grep делает выполнить его сопоставление, если это код или регулярное выражение, поэтому все они одинаковы:

foo.grep: { $_ ~~ /.../ }
foo.grep:    * ~~ /.../;
foo.grep:         /.../;

Магия Junction s

Ваше решение Junction кажется естественным,Я был бы рад, если бы кто-то мог объяснить, что мне не хватает в следующем.Хотя я ожидал , что это сработает, он склоняет голову, чтобы понять, как это на самом деле работает, но я думаю, что-то вроде (но не совсем):

  • foo & bar становится Junction из foo и bar.

  • Предпринята попытка вызвать grep с Junction в качестве аргумента.

  • Поскольку Junction находится за пределами обычной иерархии значений Any, большинство подпрограмм не имеют подходящей подписи.grep нет.

  • Когда вы вызываете подпрограмму и отсутствует соответствующая подпись, то первоначальная отправка завершается неудачно, и мы попадаем в обработчик отката диспетчеризации. Этот может быть методом один.

  • Если обработчик отката диспетчеризации видит, что есть Junction аргументов, то он извлекает отдельные значения в Junction и запускаетдо логически параллельных «потоков» (в настоящее время никогда не реальных потоков, но компилятору разрешено делать их настоящими потоками, если он считает это хорошей идеей), соответствующим этим значениям.Таким образом, он вызывает grep дважды на элемент инвоканта и выводит результаты обратно в новый Junction того же типа, что и входящий Junction.

  • В логическом контексте:Junction сворачивается в один результат.

  • (Если Junction находится в общем булевом контексте, то он может (параллельно) замыкаться в зависимости от результатов.any и любой результат приходит в True, тогда он может отменить все остальные - или не делать их в первую очередь, если он на самом деле работает последовательно, как в настоящее время всегда имеет место.all и любой результат приходит в False, остальные могут отменить. И т.д.)

...