Foldl 是如何偷懒的?

2024-04-16

有很多好的问题和答案 https://stackoverflow.com/questions/4977417/haskell-foldl-and-stack-overflow about foldl, foldr, and foldl'在哈斯克尔。

所以现在我知道:
1) foldl is lazy
2)不要使用foldl因为它会炸毁堆栈
3) use foldl'相反,因为它是严格的(ish http://haskell.org/haskellwiki/Foldr_Foldl_Foldl%27)

How foldl被评估:
1) 创建了一大堆 thunk
2) Haskell 创建完 thunk 后,thunk 就会减少
3)如果thunk太多就会溢出堆栈

我感到困惑的是:
1)为什么在所有 thunk-ing 之后都必须进行归约?
2)为什么不是foldl评估就像foldl'?这只是实施的副作用吗?
3)从定义 http://haskell.org/haskellwiki/Foldr_Foldl_Foldl%27, foldl看起来可以使用尾递归有效地评估它——我如何判断一个函数是否实际上会被有效地评估?如果我不想让我的程序崩溃,我似乎必须开始担心 Haskell 中的评估顺序。

提前致谢。不知道我的理解是否符合评价foldl是正确的——如有必要,请提出更正建议。


更新:看起来我的问题的答案与范式、弱范式和头范式以及 Haskell 对它们的实现有关。
但是,我仍在寻找一个示例,其中更急切地评估组合函数会导致不同的结果(崩溃或不必要的评估)。


简短的回答是,在foldl f,情况不一定是这样f是严格的,所以它可能太急于减少预先的重击。然而,在实践中通常是这样,所以你几乎总是想使用foldl'.

I wrote 更深入地解释如何评估顺序foldl and foldl'正在研究另一个问题 https://stackoverflow.com/questions/6872898/haskell-what-is-weak-head-normal-form/6889335#6889335。它相当长,但我认为它应该为您澄清一些事情。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Foldl 是如何偷懒的? 的相关文章

随机推荐