注意我只是想了解正在發生的事情如下所示的代碼這個特殊的一塊。我知道這可能不是解決問題的最好方法。記憶化的作家單子
我正在嘗試使用帶有memozied斐波納契函數的lazy Writer
monad來計算函數被調用的次數。該函數快速返回正確的值,但環境永遠不會返回,並且不使用任何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]
或[0..n]
,但問題仍然存在。 如果無限的名單是它會一直很內存密集型計算的問題,這就是爲什麼我上面提到的,它不消耗任何CPU或內存這正是讓我困惑。
我認爲,由於懶惰,有評估fib
功能的節點時出現莫名其妙的地方陷入僵局。
你的猜測是正確的。每次調用'fib'都會嘗試執行一次性操作'fibs',它最終會嘗試自我評估,以免卡住。並且因爲這是使用圖減少完成的,所以沒有實際的計算正在發生,只是一個節點本身被阻塞。由於純粹性,編譯器不需要在圖中遍歷這個無限循環,所以它不會,這就解釋了CPU /內存使用情況。 – is7s