首页 > 解决方案 > 意外的非懒惰

问题描述

我为这周的挑战编写了这段代码,以产生丑陋的数字。

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..*;

我按预期立即得到输出。

这是一个错误,是吗?

标签: lazy-evaluationrakurakudo

解决方案


这不是一个错误(尽管可能会更好地记录下来)。索引与[]具体化它索引的元素,因此[^150]计算前 150 个元素的(非惰性)列表。(列表的其余部分仍然是惰性的,但那些初始元素不会)。

如果你想懒惰地迭代,你可以使用&head它,它会给你以下最后一行:

.say for ( 1, |grep *.&factors.all ∈ ( 2, 3, 5 ), 2..* ).head(150);

推荐阅读