我在理解Haskell懶惰評估時遇到困難。困惑:Haskell IO懶惰
我寫了簡單的測試程序。它讀取4行數據,並且 第二和第四輸入行有很多數字。
consumeList :: [Int] -> [Int] -> [Int]
consumeList [] _ = error "hi" -- to generate heap debug
consumeList (x:xs) y = consumeList xs y
main = do
inputdata <- getContents
let (x:y:z:k:xs) = lines inputdata
s = map (read ::String->Int) $ words $ k
t = []
print $ consumeList s t
words
和map
上的字符流執行 懶惰地,該程序使用常數存儲器。
但是,當我添加論據t
,情況發生了變化。 我的期望是因爲t
是map
和words
懶惰流, 和t
不consumeList
使用,這種變化應該不會改變 內存使用情況。但不是。
consumeList :: [Int] -> [Int] -> [Int]
consumeList [] _ = error "hi" -- to generate heap debug
consumeList (x:xs) y = consumeList xs y
main = do
inputdata <- getContents
let (x:y:z:k:xs) = lines inputdata
s = map (read ::String->Int) $ words $ k
t = map (read ::String->Int) $ words $ y
print $ consumeList s t -- <-- t is not used
Q1)爲什麼這個計劃一直在t
完全不使用的內存分配?
我還有一個問題。當我與[,]
模式匹配延遲流,而不是 與(:)
內存分配行爲已更改。
consumeList :: [Int] -> [Int] -> [Int]
consumeList [] _ = error "hi" -- to generate heap debug
consumeList (x:xs) y = consumeList xs y
main = do
inputdata <- getContents
let [x,y,z,k] = lines inputdata -- <---- changed from (x:y:..)
s = map (read ::String->Int) $ words $ k
t = []
print $ consumeList s t
Q2)是(:)
和懶惰evalutation方面[,]
不同?
歡迎任何評論。感謝
[編輯]
Q3)然後,是否有可能處理第四行第一和 處理第二行,而無需增加內存消耗?
Derek指導的實驗如下。 從第二個例子開關Y,K的,我得到了相同的結果:
consumeList :: [Int] -> [Int] -> [Int]
consumeList [] _ = error "hi"
consumeList (x:xs) y = consumeList xs y
main = do
inputdata <- getContents
let (x:y:z:k:xs) = lines inputdata
s = map (read ::String->Int) $ words $ y -- <- swap with k
t = map (read ::String->Int) $ words $ k -- <- swap with y
print $ consumeList s t
我已經有點了解了。謝謝。你會回答我一些更多的任務嗎? (1)那麼是否可以處理第4行然後處理第2行而不增加內存消耗?如果僅僅從'(x:y:z:k:xs)'持有'y'的指針強制讀取和處理流,是不可能的? (2)圖表''ghc-prim.GHC.Types:'表示由'getContents'讀取的原始字符串或由'map處理的列表。 words'?我看到的內存量爲〜100MB,但實際輸入數據爲5MB。所以,我懷疑分配的內存可能是'map。單詞'處理一個。 –
也許你應該開始提出新的問題 - 但通常在這種情況下離開懶惰IO是一個好主意(正如你所看到的,有時候會有點痛苦) – Carsten
我明白了。我將針對上述評論的第一個問題開始一個新問題。 –