Haskell中无限列表的内存使用情况

时间:2014-12-03 23:05:33

标签: haskell memory ghc lazy-evaluation

此代码仅使用1Mb RAM:

main = putStrLn $ show $ length (take 2000000 [1..])

此代码使用90Mb of RAM

nums :: [Int]
nums = nextInts 0
  where
    nextInts x = x : nextInts (succ x)

main = putStrLn $ show $ length (take 2000000 nums)

如果我这样更改它,它将再次使用1Mb的RAM:

nums :: [Int]
nums = nextInts 0
  where
    nextInts x 
        |x == 90000000 = []    -- some large number
        |otherwise = x : nextInts (succ x) 

main = putStrLn $ show $ length (take 2000000 nums)

问题:有人可以解释为什么第二个代码示例将整个列表存储在RAM中,而第三个代码样本没有这样做。还描述了我应该如何更改第二个样本以使用O(1)RAM并且仍然是无限列表。

1 个答案:

答案 0 :(得分:13)

在第二种情况下,您的内存使用量不是来自存储列表,而是来自使用succ x构建未评估的thunk。

succ是懒惰的,所以调用succ x只是在堆上分配一个新的thunk。这个thunk永远不会被评估,因为你永远不需要知道任何列表元素的值。

在第三种情况下,您使用警卫x强制对x == 9000000进行评估,因此没有积累thunk。

相关问题