Haskell 折叠和堆栈溢出?

发布于 2024-10-17 00:30:17 字数 259 浏览 6 评论 0原文

我读到一篇文章声称 foldl 可能很容易发生堆栈溢出。发布的示例代码是:

maximum [1..1000000]

代码在我的机器中没有溢出。然而,它可能因环境而异。我这样增加了数字:

maximum [1..1000000000]

它导致了硬盘交换,所以我不得不停止评估。 示例代码并不重要。真的会发生堆栈溢出吗?或者只是一个古老的故事?

I read a posting claims foldl may occur stack overflow easily. And the posting sample code was:

maximum [1..1000000]

The code doesn't overflown in my machine. However it can vary by environment. I increased number like this:

maximum [1..1000000000]

it caused hard disk swapping, so I have to stop evaluation.
Sample code is not important. Is it really occur stack overflow? Or just an old days story?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

虫児飞 2024-10-24 00:30:17

一些要点

  • 递归函数每次调用都会占用堆栈空间,因此深度嵌套调用会导致溢出
  • 尾递归函数可以优化为迭代,因此不会溢出
  • foldr不是尾递归
  • 惰性求值可以防止尾递归函数被优化
  • foldl 是尾递归且惰性的,因此它可以溢出
  • foldl' 是尾递归且严格,所以很安全

Some points

  • Recursive function take stack space in each call, so deeply nested calls will cause overflows
  • Tail-recursive function can be optimized to iterations and therefore don't overflow
  • foldr is not tail-recursive
  • Lazy evaluation can prevent tail-recursive functions from being optimized
  • foldl is tail-recursive and lazy, so it can overflow
  • foldl' is tail-recursive and strict, so it's safe
苦笑流年记忆 2024-10-24 00:30:17

Data.List.maximum 是使用惰性foldl1 实现的。如果列表包含 IntInteger,则有一条使用 strictMaximum 的规则(使用严格的 foldl1' 实现) 。

因此,经过优化编译的以下程序不会导致堆栈溢出:

main = 打印 $ 最大值 [1..1000000000 ]

Data.List.maximum is implemented using the lazy foldl1. There is a rule to use strictMaximum (implemented using the strict foldl1') if the list contains Int or Integer.

So, the following program compiled with optimisations does not cause a stack overflow:

main = print $ maximum [1..1000000000 ]

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文