为什么 Perl 6 尝试仅在两种类似情况中的一种情况下评估无限列表?
Why does Perl 6 try to evaluate an infinite list only in one of two similar situations?
假设我在 REPL 中使用三角归约定义了一个惰性无限数组,并在前面粘贴了一个元素:
> my @s = 0, |[\+] (1, 2 ... *)
[...]
我可以打印出前几个元素:
> @s[^10]
(0 1 3 6 10 15 21 28 36 45)
我想像这样移动归约中的零元素:
> my @s = [\+] (0, |(1, 2 ... *))
然而,作为对此的回应,REPL 挂起,大概是因为试图评估无限列表。
如果我分步进行,它会起作用:
> my @s = 0, |(1, 2 ... *)
[...]
> ([\+] @s)[^10]
(0 1 3 6 10 15 21 28 36 45)
为什么行不通的方法...行不通?
简答:
这可能是一个错误。
长答案:
(1, 2 ... *)
产生惰性序列,因为它显然是无限的,但不知何故这并没有使结果序列被标记为惰性。
将序列放入数组 @s
会导致它被急切求值,除非它被标记为惰性。
快速修复:
在前面追加lazy
。
> my @s = [\+] lazy 0, |(1, 2 ... *)
[...]
> @s[^10]
(0 1 3 6 10 15 21 28 36 45)
假设我在 REPL 中使用三角归约定义了一个惰性无限数组,并在前面粘贴了一个元素:
> my @s = 0, |[\+] (1, 2 ... *)
[...]
我可以打印出前几个元素:
> @s[^10]
(0 1 3 6 10 15 21 28 36 45)
我想像这样移动归约中的零元素:
> my @s = [\+] (0, |(1, 2 ... *))
然而,作为对此的回应,REPL 挂起,大概是因为试图评估无限列表。
如果我分步进行,它会起作用:
> my @s = 0, |(1, 2 ... *)
[...]
> ([\+] @s)[^10]
(0 1 3 6 10 15 21 28 36 45)
为什么行不通的方法...行不通?
简答:
这可能是一个错误。
长答案:
(1, 2 ... *)
产生惰性序列,因为它显然是无限的,但不知何故这并没有使结果序列被标记为惰性。
将序列放入数组 @s
会导致它被急切求值,除非它被标记为惰性。
快速修复:
在前面追加lazy
。
> my @s = [\+] lazy 0, |(1, 2 ... *)
[...]
> @s[^10]
(0 1 3 6 10 15 21 28 36 45)