Perl 5中的惰性评估技术示例?

Eri*_*rom 5 perl haskell lazy-evaluation

我发现Haskell和Perl6最有趣的特性之一是能够推迟计算值,直到实际需要它们为止.

另一方面,Perl5喜欢立即做所有事情,但据我所知,它包含了懒惰评估的所有必要原语.那些是:

  • 采取参考@_的子程序创建一个别名在其参数列表中的标识符数组引用,即使其中的一些标识符不包含值呢.
  • \@_内部保存的子例程返回重载/绑定对象,然后在需要时取消引用它.(并且有各种CPAN模块可以抽象出领带/过载细节)

我一直在Perl中尝试各种惰性编程技术(我在工作中有一个模块,在Perl5中实现了一些Haskell Prelude(像共同递归:$_ = list 0, 1, zipWith {&sum} $_, tail $_ for my $fibs;定义Fibonacci序列已经在工作)).但我感觉代码中隐藏着一些微妙的错误,这些错误可能在函数用于较大的表达式/程序时显现出来.

所以我想知道是否有任何好的例子(CPAN /博客/书籍),任何人都知道,在Perl5中使用Haskell/Perl6就像懒惰一样?特别是,我想阅读使用这种类型的懒惰的任何重要大小的代码.

我也有兴趣知道是否有任何人遇到任何关于在Perl 5中实现延迟评估的问题或难以处理的问题.

Mic*_*ohl 9

高阶Perl(在线免费提供)有一章称为"无限流".也许这是一个很好的起点.


Eth*_*her 6

好吧,Moose通过延迟加载属性来做到这一点:

默认值和构建器方法
属性可以具有默认值,Moose提供了两种指定默认值的方法.
[描述了"默认"和"构建器"选项...]

Laziness
Moose允许您通过使属性"懒惰"来推迟属性填充:

has 'size' => (
    is      => 'ro',
    lazy    => 1,
    builder => '_build_size',
);
Run Code Online (Sandbox Code Playgroud)

当"lazy"为true时,在调用reader方法之前不会生成默认值,而不是在对象构造时生成.您可能选择这样做有几个原因.

首先,如果此属性的默认值取决于某些其他属性,则该属性必须为"lazy".在对象构造期间,默认值不会以可预测的顺序生成,因此您无法指望在生成默认值时正在填充的其他属性.

其次,通常没有理由在需要之前计算默认值.使属性"延迟"可让您将成本推迟到需要属性之前.如果永远不需要该属性,则可以节省一些CPU时间.

我们建议您使用构建器或非平凡的默认"懒惰"来创建任何属性.