意外的非懒惰
Unexpected Non-Laziness
这几周我写了这段代码 challenge 来生成丑陋的数字。
sub factors( $n ) {
if $n > 1 {
$_, |factors $n div $_
given ( grep $n %% *, 2..* ).first } }
.say for ( 1, |grep *.&factors.all ∈ ( 2, 3, 5 ), 2..* )[^150];
从某种意义上说,这是有效的,它会产生正确的输出,但它不会表现得很懒惰:输出不会立即开始,而是在开始后 30 秒开始。
然而,当我删除索引并迭代裸序列时
.say for 1, |grep *.&factors.all ∈ ( 2, 3, 5 ), 2..*;
我按预期立即得到了输出。
这是一个错误,是吗?
这不是一个错误(尽管可以更好地记录)。使用 []
索引具体化它索引的元素,因此 [^150]
计算前 150 个元素的(非惰性)列表。 (列表的其余部分仍然是惰性的,但那些初始元素不是)。
如果你想延迟迭代,你可以使用 &head
代替,这会给你以下最后一行:
.say for ( 1, |grep *.&factors.all ∈ ( 2, 3, 5 ), 2..* ).head(150);
这几周我写了这段代码 challenge 来生成丑陋的数字。
sub factors( $n ) {
if $n > 1 {
$_, |factors $n div $_
given ( grep $n %% *, 2..* ).first } }
.say for ( 1, |grep *.&factors.all ∈ ( 2, 3, 5 ), 2..* )[^150];
从某种意义上说,这是有效的,它会产生正确的输出,但它不会表现得很懒惰:输出不会立即开始,而是在开始后 30 秒开始。
然而,当我删除索引并迭代裸序列时
.say for 1, |grep *.&factors.all ∈ ( 2, 3, 5 ), 2..*;
我按预期立即得到了输出。
这是一个错误,是吗?
这不是一个错误(尽管可以更好地记录)。使用 []
索引具体化它索引的元素,因此 [^150]
计算前 150 个元素的(非惰性)列表。 (列表的其余部分仍然是惰性的,但那些初始元素不是)。
如果你想延迟迭代,你可以使用 &head
代替,这会给你以下最后一行:
.say for ( 1, |grep *.&factors.all ∈ ( 2, 3, 5 ), 2..* ).head(150);