2014-05-19 27 views
108

Haskell有一個標識函數,它返回輸入不變。該定義很簡單:爲什麼Haskell的「什麼都不做」的功能,ID,消耗大量的內存?

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 

幾秒鐘(根據任務管理器的內存約2 GB)之後,編譯失敗與ghc: out of memory。同樣,口譯員說ghci: out of memory

由於id是一個非常簡單的函數,我不希望它在運行時或編譯時成爲內存負擔。什麼是所有使用的內存?

+10

你想組成這些'id's。在VIM中,將光標放在'f'的定義上,執行:':s/id id/id。 id。/ g'。 –

+1

我給你你的第一個金徽章,通過將你的問題從+99增加到+100 :)。我通過以99票的方式查看所有問題,以及在沒有金徽章的情況下發布它們的問題發現了它)。 –

回答

128

我們知道的id類型,

id :: a -> a 

當我們專注此爲id id,該留下的id副本類型:

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

然後當你再次專攻此對於id id id中最左邊的id,您將獲得:

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

所以你看到你添加的每個id,最左邊的id的類型簽名是兩倍大。

請注意,類型在編譯期間被刪除,所以這隻會佔用GHC中的內存。它不會佔用你程序中的內存。

+9

有趣但相關:http://britton.disted.camosun.bc.ca/jbchessgrain.htm – Barmar

+0

我記得岡崎在他編寫嵌入Haskell的RPN計算器時遇到類似的麻煩。 – dfeuer

+3

問題可能在於,GHC是否應該找到一種更優雅地處理這類事情的方法。特別是當寫出完整的類型時,類型非常大,但是有大量的重複 - 可以用共享來壓縮這些東西嗎?有沒有一種有效的方法來處理它們? – dfeuer

相關問題