如 Why does (sum $ takeWhile (<10000000) [1..]) use so much memory? 中所述以下内容不会破坏ghci中的内存:
foldl' (+) 0 $ takeWhile (< 10000000) [1 .. ]
但是,如果我创建一个包含以下内容的文件:
import Data.List
longList::[Int]
longList = [1 .. ]
result :: Int
result = foldl' (+) 0 $ takeWhile (< 10000000) longList
main = do
print $ result
并加载到 ghci 中,然后在运行程序时内存消耗激增。这是为什么,我该怎么做才能修复该程序?我正在使用 ghc 7.8.3。
[编辑]
如果我先通过 ghc Test.hs
编译,它似乎不会 爆炸。但是,如果我删除所有 .hi
和 .o
文件,并通过 ghci Test.hs
加载到 ghci,那么内存就会爆炸。
最佳答案
我认为这是由于在 GHCi 中 :l
文件时标识符 longList
的处理方式与编译时不同。
当您在 GHCi 中 :l ModuleName
时,默认情况下 所有 模块中的顶级标识符都会进入范围,以便您可以有效地调试它。对于您的示例,这包括 longList
。这意味着 GHCi 保留 longList
的内容在被评估后,这会导致内存泄漏。我怀疑即使使用 -fobjectcode
也是如此,所以我不确定其他评论中讨论的行为实际上是一个错误。
相反,当您编译模块时,GHC 使用模块导出列表找出结果中公开了哪些标识符。由于您没有明确的 module
声明,因此默认为 ( last paragraph )
module Main (main) where
这意味着在编译时,GHC 可以注意到除 main
之外的所有标识符都没有暴露,并且 longList
只使用了一次。然后它可以放弃保持它的值(value),避免内存泄漏。
关于haskell - 内存在 ghci 中因严格求和/严格折叠而爆炸,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24838982/