【发布时间】:2011-09-20 15:08:24
【问题描述】:
在 Haskell 中有很多关于 foldl、foldr 和 foldl' 的 good questions and answers。
所以现在我知道了:
1) foldl 很懒
2) 不要使用foldl,因为它会炸毁堆栈
3)改用foldl',因为它很严格(ish)
如何评估foldl:
1) 创建了一大堆 thunk
2) Haskell 完成创建 thunk 后,thunk 减少
3) 如果 thunk 太多,则溢出堆栈
我感到困惑的是:
1)为什么在所有重击之后必须进行还原?
2) 为什么不像foldl' 那样评估foldl?这只是实现的副作用吗?
3) 从definition 来看,foldl 看起来可以使用尾递归有效地评估它——我如何判断一个函数是否真的会被有效地评估?如果我不想让我的程序崩溃,我似乎不得不开始担心 Haskell 中的评估顺序。
提前致谢。不知道我对foldl的评价理解是否正确——如有需要请指正。
更新:看来我的问题的答案与范式、弱范式和头部范式以及 Haskell 对它们的实现有关。
但是,我仍在寻找一个示例,其中更急切地评估组合函数会导致不同的结果(崩溃或不必要的评估)。
【问题讨论】:
-
foldlis 尾递归...但事实证明,在 Haskell 中(与 Eager 语言不同)尾递归是一件坏事。 -
@Daniel -- 好点,我写错了,并编辑了问题以更正它。另外,感谢您澄清这一点——我一直认为尾递归无疑是一件好事。
-
@DanielWagner Bang patterns 来救援!尾递归在 Haskell 中仍然是一件好事。
-
@DanBurton 是的,你打赌。如果你使用 Haskell 的 Eager 片段,那么尾递归当然也不错!
-
@MasterMastic 通常获得尾递归的方法是有一个累加器。将此与惰性结合起来,当您进行所有递归调用时,您会得到一个带有非常深嵌套的 thunk 的累加器。繁荣!堆栈溢出。
标签: haskell lazy-evaluation fold