web-dev-qa-db-ja.com

Haskellの「何もしない」関数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

数秒後(およびタスクマネージャーによると約2 GBのメモリ)、コンパイルはghc: out of memoryで失敗します。同様に、インタープリターはghci: out of memoryと言います。

idは非常に単純な関数であるため、実行時またはコンパイル時にメモリの負荷になるとは思わないでしょう。使用されているすべてのメモリは何ですか?

112
Ryan

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の型シグネチャが2倍になります。

タイプはコンパイル中に削除されるため、GHCのメモリのみを使用することに注意してください。プログラムのメモリを占有しません。

132
Dietrich Epp