Foldl 是否比它严格的表亲 Foldl' 更好?
Haskell 有两个列表左折叠函数:foldl
和一个“严格”版本 foldl'
。非严格的 foldl
的问题在于它构建了一个 thunk 塔:
foldl (+) 0 [1..5]
--> ((((0 + 1) + 2) + 3) + 4) + 5
--> 15
这会浪费内存,并且如果列表中的项太多,可能会导致堆栈溢出。另一方面,foldl'
强制对每个项目使用累加器。
然而,据我所知,foldl'
在语义上等同于foldl
。将 foldl (+) 0 [1..5]
评估为 head 范式需要在某个时刻强制累加器。如果我们不需要 head-normal 形式,我们就不会开始评估 foldl (+) 0 [1..5]
。
是否有任何令人信服的理由让人们希望 foldl
的行为优于 foldl'
?
Haskell has two left fold functions for lists: foldl
, and a "strict" version, foldl'
. The problem with the non-strict foldl
is that it builds a tower of thunks:
foldl (+) 0 [1..5]
--> ((((0 + 1) + 2) + 3) + 4) + 5
--> 15
This wastes memory, and may cause a stack overflow if the list has too many items. foldl'
, on the other hand, forces the accumulator on every item.
However, as far as I can tell, foldl'
is semantically equivalent to foldl
. Evaluating foldl (+) 0 [1..5]
to head normal form requires forcing the accumulator at some point. If we didn't need a head-normal form, we wouldn't be evaluating foldl (+) 0 [1..5]
to begin with.
Is there any compelling reason one would want the behavior of foldl
over that of foldl'
?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
foldl
和foldl'
在语义上并不等效。简单的反例:然而,在实践中,由于您提到的原因,您通常需要严格的
foldl'
。foldl
andfoldl'
are not semantically equivalent. Trivial counterexample:In practice, however, you usually want the strict
foldl'
for the reasons you mentioned.当
foldl
和foldl'
不会产生相同的结果时(如 hammar 的示例所示),必须根据所需的结果做出决定。除此之外,如果折叠函数是构造函数(应用构造函数会在 WHNF 中创建一个值,则没有必要强制它),则可以使用foldl
而不是foldl'
再次变为 WHNF),并且在foldl (.) id 函数
中,强制 WHNF 也不会获得任何结果。除了这些特殊情况外,foldl'
是首选方法。When
foldl
andfoldl'
wouldn't produce the same result, as in hammar's example, the decision has to be made according to the desired outcome. Apart from that, you'd usefoldl
rather thanfoldl'
if the folded function is a constructor (applying a constructor creates a value in WHNF, there's no point in forcing it to WHNF again), and infoldl (.) id functions
where forcing WHNF doesn't gain anything either. Apart from these exceptional cases,foldl'
is the method of choice.