为什么 Haskell 的“ do nothing”函数 id 会消耗大量内存?

Haskell 有一个标识函数,它返回的输入不变。定义很简单:

id :: a -> a
id x = x

所以为了好玩,这个应该输出 8:

f = id id id id id id id id id id id id id id id id id id id id id id id id id id id
main = print $ f 8

几秒钟后(根据 TaskManager,大约有2gb 的内存) ,使用 ghc: out of memory编译失败。类似地,解释器说 ghci: out of memory

由于 id是一个非常简单的函数,我不希望它在运行时或编译时占用大量内存。所有的内存都是用来做什么的?

6845 次浏览

We know the type of id,

id :: a -> a

And when we specialize this for id id, the left copy of id has type:

id :: (a -> a) -> (a -> a)

And then when you specialize this again for the leftmost id in id id id, you get:

id :: ((a -> a) -> (a -> a)) -> ((a -> a) -> (a -> a))

So you see each id you add, the type signature of the leftmost id is twice as large.

Note that types are deleted during compilation, so this will only take up memory in GHC. It won't take up memory in your program.