关于懒惰[RAKU]

问题描述 投票:3回答:1

[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,如果我们取消了” lazy“定义,则生成的Sequence(使用collect-take)将永远运行(不延迟)。

在第二种情况下(将Seq分配给@ f2)@ f2变得懒惰。

我们为什么在行为上有所区别?尽管我们尝试做同样的事情:以惰性方式将Seq分配给数组

有人可以澄清这个问题吗?

arrays lazy-evaluation raku lazy-sequences rakudo
1个回答
1
投票

gather不会告诉世界它是懒惰的:

say .is-lazy
for (gather { take 42 }),                 # False
    (gather { loop { take 42 } });        # False

前缀lazy将创建一个新的Seq,它将从其右侧的结构中提取。 Seq创建的新lazy告诉世界it(新Seq)是惰性的:

say .is-lazy
for (lazy gather { take 42 }),            # True
    (lazy gather { loop { take 42 } });   # True

同时,(1...Inf) 知道它是懒惰的,不需要前缀lazy就可以告诉世界它是:

say .is-lazy
for (1 ... Inf)                           # True

因此,在您的@f1 = gather ...情况下,@f1被分配了一个序列,该序列表示它不是惰性的。因为变量是@标记,所以赋值操作会忠实地要求序列交付所获得的一切。而Seq则尽职尽责。但是它包含一个无限循环,因此分配永远不会完成。

在其他情况下,要分配的序列会声明自己是惰性的。 @变量以此为线索来标记自己为惰性,并且仅懒惰地向序列询问值。这样他们就可以工作。

因此,总而言之,分配给它的@ sigil'd variable is lazy if a Seq`表示它是惰性的,反之则渴望。


您没有问这个,但是另一种情况是将Seq分配或绑定到标量变量或无sigil标识符。

在这种情况下,在变量/标识符上调用.is-lazy将根据分配/绑定的True返回FalseSeq

但是,不管.is-lazy返回True还是False,它都会懒惰地迭代Seq

© www.soinside.com 2019 - 2024. All rights reserved.