注意我只是想了解下面显示的这段特定代码中发生了什么。我知道这可能不是解决问题的最佳方法。
我正在尝试使用Writer
带有记忆斐波那契函数的惰性单子来计算函数被调用的次数。该函数快速返回正确的值,但Writer
环境永远不会返回并且不使用任何 CPU 或内存。
import Control.Monad.Writer.Lazy as W
fib :: Int -> Writer (Sum Int) Int
fib = let fibs = mapM fib' [0..]
fib' 0 = return 0
fib' 1 = return 1
fib' n = liftM2 (+) (fib $ n-1) (fib $ n-2)
in \n -> tell (Sum 1) >> fibs >>= return . (!!n)
Prelude W> runWriter $ fib 51
(20365011074,Sum {getSum = Interrupted.
有人可以解释发生了什么吗?为什么环境不返回值?
编辑
无限列表[0..]
不是这里的问题。我尝试用有限的列表替换它,例如[0..10]
or[0..n]
但问题仍然存在。
如果无限列表是问题所在,那将是一个非常占用内存的计算,这就是为什么我在上面提到它不消耗任何 CPU 或内存,这让我感到困惑。
fib
我相信,由于懒惰,在评估函数的节点时会以某种方式发生死锁。