在 Perl 6 中过滤匹配两个正则表达式的元素

Filtering elements matching two regexes in Perl 6

这里发生了一些我不太明白的事情。

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

但是

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

这是什么原因?

您已经想出了完美的 cromulent 解决方案。

另一个是:

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

这个答案的其余部分只是说明了问题。这个问题中的问题是 .

中所涵盖问题的更复杂版本

如果逻辑操作是代码,则不会执行它们的参数。

所以{ $_ ~~ /a/ } && { $_ ~~ /b/ }returns{ $_ ~~ /b/ }.

* ~~ /a/ && * ~~ /b/ returns * ~~ /b/.

同时,grep 执行它的匹配器,如果它是代码或者如果它是正则表达式,所以这些都是一样的:

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

Junctions

的魔法

您的 Junction 解决方案似乎很自然。如果有人能解释我在下面遗漏的内容,我会很高兴。虽然我 期望 它能工作,但它让我费尽心思弄清楚它是如何工作的,但我认为它类似于(但不完全是):

  • foo & bar 成为 foo bar.

    Junction
  • 尝试以 Junction 作为参数调用 grep

  • 因为 Junction 在正常的 Any 值层次之外,大多数例程没有匹配的签名。 grep 没有。

  • 当您调用一个例程并且没有相应的签名时,初始分派将失败,我们会触发分派回退处理程序。 This可能是方法一

  • 如果分派回退处理程序发现有 Junction 个参数,那么它会提取 Junction 中的各个值并在逻辑上并行启动 "threads"(目前从不实际 线程,但如果编译器认为这是一个好主意,则允许编译器将它们设为真正的线程)对应于这些值。因此,它对调用者的每个元素调用 grep 两次,并将结果输出回与传入的 Junction.

  • 相同类型的新 Junction
  • 在布尔上下文中,Junction 折叠为单个结果。

  • (如果 Junction 在整体布尔上下文中,那么它可以根据结果(并行)短路。如果它是 anyany 结果出现在 True 中,然后它可以取消其余的——或者如果它实际上是按顺序做的,那么首先不做它们,就像目前总是这样。如果它是一个 all 和任何结果进来 False 它可以取消其余的。等等)