9

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

问题

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

a, b, c, a, b, c, ...

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

可能的解决方案

我至少能想到一对。

更单调的脚踏实地的方法是在惰性范围上进行映射 。在REPL 中:@array[<variable> mod length-of-@array]0..Infperl6

> 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 ...)

一个更酷(我认为)的解决方案是让您首先将您的列表变成一个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 ...)

结论

尽管我可以实现这一点(特别是最后一个解决方案非常简洁和令人满意),但我想知道我是否遗漏了专门为此目的而构建的任何东西。


编辑回复:接受的答案

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

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

<a b c> <<~>> ("" xx 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)

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

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

返回

List on right side of hyperop of infix:<~> is known to be infinite
  in block <unit> at <unknown file> line 1
4

3 回答 3

9

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

|< a b c > xx *

好吧,有一个例外,如果您使用类似的东西«~»为您扩展它。

< a b c > «~» (1..10)
# (a1 b2 c3 a4 b5 c6 a7 b8 c9 a10)
于 2020-10-17T04:03:45.830 回答
2

我不知道我是否理解了这个问题。但是我的理解是,您需要一种方法来按照某种模式生成无限列表。好吧,如果这是“在 Raku 中思考”一书中的问题,那么在第 14.5 部分中可能会有所帮助(改编自如何进行斐波那契数列)

("a","b","c", -> $a, $b, $c {$a} ...* )

这个元素是纯列表,如果你想要提取值,你需要更常规的列表(比如分配和提取值)

my @list = ("a","b","c", -> $a, $b, $c {$a} ...* )
@list[0..100]
@list[91]

我认为在Inf上下文中使用 map 并不是一个好主意,但是如果我遗漏了什么,请告诉我,我还在学习这种很棒的语言!

于 2020-10-19T20:48:15.370 回答
1

你的第一个“脚踏实地”的例子可以写成(^Inf).map({ @ar[$_ % *] })

此外,滑动和重复也可以正常工作,但仅适用于大小合理的列表。

sub bad-cycle(@xs) {
    |@xs xx Inf
}

my $big-list = ^1e6;
say bad-cycle($big-list).head(100);    # Hangs for several seconds

更好的选择是上面显示的地图,或者gather像这样的循环

sub cycle(@xs) {
    gather loop { .take for @xs }
}

say cycle($big-list).head(100);    # Instant output
于 2020-10-19T15:16:12.447 回答