如何在 Raku 中无限期和懒惰地循环遍历列表?

gro*_*ber 9 list lazy-evaluation rakudo lazy-sequences raku

这主要是为了了解Raku有多棒。

是否有内置方法可以获取列表并无限期地循环遍历它,例如生成惰性列表

a, b, c, a, b, c, ...
Run Code Online (Sandbox Code Playgroud)

(a, b, c)?列表文档中的任何内容似乎都没有明显的作用。

可能的解决方案

我至少能想到一对。

更实际的方法是映射 @array[<variable> mod length-of-@array]惰性范围0..Inf。在perl6REPL 中:

> my @ar=<a b c>
[a b c]
> (0..Inf).map({ @ar[$_ % @ar.elems] }).[0..100]
(a b c a b c a b c a b c a b c a b c a b c a b c a b c a b c a b c a b c a b c a b c a b c a b c a b c a b c a b c a b c a b c a b c a b c a b c a b c a b c a b c a b c a b c a b c a b c a b c a b c a ...)
Run Code Online (Sandbox Code Playgroud)

一个更酷的(我认为)解决方案会让你首先将你的列表变成一个slip,然后无限期地将重复运算符应用于该slip:

> my @ar=<a b c>
[a b c]
> (|@ar xx *).[0..100]
(a b c a b c a b c a b c a b c a b c a b c a b c a b c a b c a b c a b c a b c a b c a b c a b c a b c a b c a b c a b c a b c a b c a b c a b c a b c a b c a b c a b c a b c a b c a b c a b c a b c a ...)
Run Code Online (Sandbox Code Playgroud)

结论

尽管我可以做到这一点(特别是最后一个解决方案非常简洁和令人满意),我想知道我是否遗漏了专门为此目的而内置的任何内容。


编辑回复:接受的答案

这是对@Brad Gilbert 的回答的稍微详细说明。该«~»运算符将字符串连接 包装~« » 超运算符中,这导致将包装的二元运算符应用于从两个列表中顺序选择的元素。

所以为了实现我想要的(列表循环到所需的长度,比如 100),一个人会做

<a b c> <<~>> ("" xx 100)
Run Code Online (Sandbox Code Playgroud)

这产生

(a b c a b c a b c a b c a b c a b c a b c a b c a b c a b c a b c a b c a b c a b c a b c a b c a b c a b c a b c a b c a b c a b c a b c a b c a b c a b c a b c a b c a b c a b c a b c a b c a b c a)
Run Code Online (Sandbox Code Playgroud)

(100 个条目)。但它确实有几个缺点:

  • 由于应用了 ~
  • 它实际上并没有产生一个懒惰的无限列表:
<a b c> <<~>> ("" xx *)
Run Code Online (Sandbox Code Playgroud)

返回

List on right side of hyperop of infix:<~> is known to be infinite
  in block <unit> at <unknown file> line 1
Run Code Online (Sandbox Code Playgroud)

Bra*_*ert 9

当它可以写得这么短时,为什么要为此添加一个功能。特别是因为您需要这样的东西可能是罕见的事件。

|< a b c > xx *
Run Code Online (Sandbox Code Playgroud)

那么有一个例外,如果你使用类似的东西«~»为你扩展它。

< a b c > «~» (1..10)
# (a1 b2 c3 a4 b5 c6 a7 b8 c9 a10)
Run Code Online (Sandbox Code Playgroud)