在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
复制相似问题