惰性计算

中文名 惰性计算
相反 热情计算
目录导航

简介

它有两个相关而又有区别的含意,可以表示为“延迟计算”和“短路求值”,本条目专注前者,后者请参见 短路求值条目。除可以得到性能的提升外,惰性计算的最重要的好处是它可以构造一个无限的 数据类型。

惰性计算的相反是热情计算,也叫做 严格计算。这是一个大多数 编程语言所拥有的普通计算方式。

延迟求值

延迟求值特别用于函数式编程语言中。在使用延迟求值的时候, 表达式不在它被绑定到 变量之后就立即求值,而是在该值被取用的时候求值,也就是说,语句如 (把一个表达式的结果赋值给一个变量)明显的调用这个表达式被计算并把结果放置到 中,但是先不管实际在 中的是什么,直到通过后面的表达式中到 的引用而有了对它的值的需求的时候,而后面表达式自身的求值也可以被延迟,最终为了生成让外界看到的某个符号而计算这个快速增长的依赖树。

某些 编程语言缺省延迟表达式的求值,另一些提供 函数或特殊 语法来延迟求值。在 Miranda 和 Haskell 中,缺省延迟 函数 实际参数的求值。在很多其他语言中,可以使用特殊 语法明确悬置计算来延迟求值(比如 Scheme 的 "delay" 或 "force"),更一般的通过把一个表达式包装在 thunk 中。表示这种明确延迟求值的对象叫做预期或承诺。

延迟求值的一个好处是能够建立可计算的无限列表而没有妨碍计算的无限循环或大小问题。例如,可以建立生成无限 斐波那契数列表的的 函数(经常叫做“流”)。第 个 斐波那契数的计算仅是从这个无限列表上提取出这个元素,它只强迫这个列表的前 n 个成员的计算。

例如,在 Haskell 中,斐波纳契数的列表可以写为

fibs = 0 : 1 : zipWith (+) fibs (tail fibs)

在 Haskell 语法中,":" 预备一个元素给列表,tail 返回去掉第一个元素的一个列表,而 zipWith 使用一个特殊 函数(这里是加法)来组合两个列表的对应元素生成第三个列表。

假定编程者是仔细的,只有生成特定结果所需要的值才被求值。但是特定计算可能导致程序尝试求值无限数目个元素;例如,要求列表的长度或使用fold运算总和这个列表的元素将导致程序不能终止或耗尽内存。

相关百科
返回顶部
产品求购 求购