在Okasaki的纯功能数据结构中的Streams章节

时间:2015-08-11 18:39:49

标签: functional-programming lazy-evaluation sml purely-functional

在关于流的介绍性章节中,Okasaki为流上的drop提供了2个实现。 enter image description here

他明确提到第二个更有效(并且两者都具有相同的语义),但我似乎无法弄清楚为什么一个比另一个更有效。任何见解将不胜感激。

1 个答案:

答案 0 :(得分:4)

如果我不得不猜测,我会说这必须是因为第二个版本并没有像第一个版本那样利用懒惰,但似乎无论上下文如何,如果你强迫任何结果的位,然后你强制整个计算。例如,假设我想这样做:

val x = hd ($drop(10, l))

对于第一个版本,我们需要经历所有10次迭代,然后才能得到一个cons单元(假设流有超过10个元素)。这与在第二个版本中执行的计算量相同,但是,我们不必处理在每次迭代中创建thunk并强制它的开销。

某些编译器,如GHC,实际上会执行一种称为严格性分析的东西,在这种情况下,你会尝试确定某个特定术语是否会被强制,如果是这样,就不需要创建一个thunk然后强制它,更多有关详细信息,请访问here

另一方面,take

val x = hd ($take(10, l))

在完全懒惰的版本下,我们只需要评估take的第一次迭代,直到我们可以停止,而第二种版本的模拟将评估所有10次迭代。在这个例子中,懒惰会给你一些节省。