在Raku文档中,有一种说法是,聚集-获取结构正在被延迟评估。在下面的例子中,我很难总结一下这些构造的惰性:
say 'Iterate to Infinity is : ', (1 ... Inf).WHAT;
say 'gather is : ', gather {
take 0;
my ($last, $this) = 0, 1;
loop {
take $this;
($last, $this) = $this, $last + $this;
}
}.WHAT;
say '------------------------------------';
my @f1 = lazy gather {
take 0;
my ($last, $this) = 0, 1;
loop {
take $this;
($last, $this) = $this, $last + $this;
}
}
say '@f1 : ', @f1.WHAT;
say '@f1 is lazy : ', @f1.is-lazy;
say '------------------------------------';
my @f2 = 1 ... Inf;
say '@f2 : ', @f2.WHAT;
say '@f2 is lazy : ', @f2.is-lazy;
在第一种情况下(将一个Seq分配给@f1),如果我们去掉了“懒惰”定义,那么生成的序列(使用聚集-获取)将永远运行(而不是惰性)。
在第二种情况下(将Seq分配给@f2) @f2变得懒惰。
为什么我们在行为上有区别?尽管我们尝试做同样的事情:以懒惰的方式将Seq分配给数组
有人能澄清这件事吗??
发布于 2020-01-17 15:52:53
在Raku文档中,有一种说法是,聚集-获取结构正在被延迟评估。
他们是可以的。但不一定。不管是哪种方式,他们都很高兴。
关键的一点是,如果询问gather
是否懒惰,它将返回False
。这就是你所看到的行为的结果。
第一条:gather
懒惰的一种行为方式
gather
在需要时计算其序列中的下一个元素。我是懒惰评估的经典定义,如维基百科所描述的
懒惰的评价..。将表达式的计算延迟到需要它的值为止。
第二步:gather
懒惰的第二种行为方式
一些使用价值序列的结构总是懒洋洋地消耗它们。如果他们正在消费的序列是一个gather
,那么他们会懒洋洋地要求它的值。在这种情况下,gather
需要计算它的序列,直到它到达一个take
,然后是屈服,直到需要下一个值为止。
第3条:gather
急切地表现出一种方式
一些使用价值序列的构造总是热切地使用它们。如果他们正在消费的序列是一个gather
,那么他们急切地要求它的值。在这种情况下,gather
会听话,其中的任何懒惰都是没有意义的。
第四步:gather
的第二种行为方式
根据序列对.is-lazy
调用的响应,一些消耗值序列的结构懒洋洋地或急切地要求它们;如果它返回True
,那么它的值就会被懒散地要求,否则就会急切地要求它们。
这里有一个关键的转折:当在一个.is-lazy
构造上调用gather
时,它返回False
。
以#5:你的例子中发生了什么?
say .is-lazy
for (gather { take 42 }), # False
(gather { loop { take 42 } }); # False
在您的@f1 = gather ...
中,@f1
被分配了一个序列,表示它不懒惰。即使它包含一个无限循环,也是如此。@
sigil的变量把它作为一个线索,急切地分配序列--而代码挂起。
前缀lazy
创建了一个新的Seq
,它懒洋洋地从其右侧的表达式中提取。如果调用了True
,它还返回.is-lazy
:
say .is-lazy
for (lazy gather { take 42 }), # True
(lazy gather { loop { take 42 } }); # True
如果为@
sigil'd变量分配了一个值,该值将返回对.is-lazy
的调用的True
,则赋值和变量都是惰性的。因此,代码@f1 = lazy gather ...
运行良好。
最后,序列(1...Inf)
知道它是懒惰的,并且告诉世界它是懒惰的,而不需要前缀lazy
say .is-lazy with (1 ... Inf) # True
因此,无论是否使用lazy
,分配也很好。
总之,如果分配给@
的Seq
表示它是懒惰的,那么它的变量会懒惰地获取元素,而其他的则会急切地获得。
您没有问到这一点,但另一种情况是将Seq
分配或绑定到$
sigil'd变量,或sigil空闲标识符。
与@
sigil'd变量一样,在$
sigil‘s变量或sigil空闲标识符上调用.is-lazy
将按照指定/绑定的Seq
返回True
或False
。
但是,无论.is-lazy
返回的是True
还是False
,Seq
仍然会被延迟迭代。
https://stackoverflow.com/questions/59789051
复制相似问题