首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >懒惰[ RAKU ]

懒惰[ RAKU ]
EN

Stack Overflow用户
提问于 2020-01-17 14:10:12
回答 1查看 218关注 0票数 7

在Raku文档中,有一种说法是,聚集-获取结构正在被延迟评估。在下面的例子中,我很难总结一下这些构造的惰性:

代码语言:javascript
运行
复制
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分配给数组

有人能澄清这件事吗??

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 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:你的例子中发生了什么?

代码语言:javascript
运行
复制
say .is-lazy
for (gather { take 42 }),                 # False
    (gather { loop { take 42 } });        # False

在您的@f1 = gather ...中,@f1被分配了一个序列,表示它不懒惰。即使它包含一个无限循环,也是如此。@ sigil的变量把它作为一个线索,急切地分配序列--而代码挂起。

前缀lazy创建了一个新的Seq,它懒洋洋地从其右侧的表达式中提取。如果调用了True,它还返回.is-lazy

代码语言:javascript
运行
复制
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

代码语言:javascript
运行
复制
say .is-lazy with (1 ... Inf)             # True

因此,无论是否使用lazy,分配也很好。

总之,如果分配给@Seq表示它是懒惰的,那么它的变量会懒惰地获取元素,而其他的则会急切地获得。

您没有问到这一点,但另一种情况是将Seq分配或绑定到$ sigil'd变量,或sigil空闲标识符。

@ sigil'd变量一样,在$ sigil‘s变量或sigil空闲标识符上调用.is-lazy将按照指定/绑定的Seq返回TrueFalse

但是,无论.is-lazy返回的是True还是FalseSeq仍然会被延迟迭代。

票数 10
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/59789051

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档