【发布时间】:2012-02-13 03:56:33
【问题描述】:
作为 Haskell 的新手,我正在尝试多次迭代一个函数(例如逻辑图)。在命令式语言中,这将是一个简单的循环,但是在 Haskell 中,我最终会出现堆栈溢出。以这段代码为例:
main = print $ iter 1000000
f x = 4.0*x*(1.0-x)
iter :: Int -> Double
iter 0 = 0.3
iter n = f $ iter (n-1)
对于少量的迭代,代码可以工作,但对于一百万次迭代,我得到堆栈空间溢出:
Stack space overflow: current size 8388608 bytes.
Use `+RTS -Ksize -RTS' to increase it.
我不明白为什么会发生这种情况。尾递归在这里应该没问题。
也许问题是懒惰的评估。我尝试了几种强制严格评估的方法,在不同的位置插入$! 或seq,但没有成功。
Haskell 对函数进行大量迭代的方法是什么?
我尝试过相关帖子的建议:here 或here,但我总是以stackoverflow 结束大量迭代,例如main = print $ iterate f 0.3 !! 1000000。
【问题讨论】:
-
问题是你没有尾递归,因为你没有直接返回
iter (n-1) -
有趣的是,人们只是不明白尾递归是什么。仅供参考,这个定义是错误的:“当我们所在的函数的名称出现在该函数的最后一行时”。