このコードは(あなたがそれをしようとした場合、すぐにそれを殺すために準備され、非常に高速な)メモリをリーク:永久にメモリがネストされるのはなぜですか?
import Control.Monad (forever)
main = do
forever $ forever $ return()
(-O2、-Oでコンパイル、-O0 ...、GHC 7.0.3) 私はなぜこの漏れがあるのか理解できません - 私は永遠の間の例外ハンドラでこのようなコードをかなり使用していますが、なぜこれがメモリをリークさせるのか分かりません。
私はちょうどソースを調べましたControl.Monadのために:
{- Note [Make forever INLINABLE]
If you say x = forever a
you'll get x = a >> a >> a >> a >> ... etc ...
and that can make a massive space leak (see TraC#5205)
In some monads, where (>>) is expensive, this might be the right
thing, but not in the IO monad. We want to specialise 'forever' for
the IO monad, so that eta expansion happens and there's no space leak.
To achieve this we must make forever INLINABLE, so that it'll get
specialised at call sites.
Still delicate, though, because it depends on optimisation. But there
really is a space/time tradeoff here, and only optimisation reveals
the "right" answer.
-}
このbugは、おそらく '修正済み'です。残念ながら、ネストされた永遠にバグが再度トリガされるようです。興味深いことに、永遠のこの定義は、(Control.Monadから借りた)バグをトリガ:
forever a = a >> forever a
次の定義が問題なく動作しますが:
forever a = a >>= \_ -> forever a
>>
オペレータで怪しい何かが私のように、ありますこのコードは同等になります。
これは7.2.2で修正されているようです。 Unfortunatelly haskellプラットフォームは7.0.4を使用しているようですが、私はUbuntuに7.0.3を持っています:(新しいバージョンをインストールする方法を見つけなければならないでしょう) – ondra
GHC 7.2をインストールする場合、Haskell Platformは本当に必要ありません。 2とcabal-install([GHC 7.2の特別な手順はこちら](https://gist.github.com/1169332)を参照)、これはOS Xだけでなくすべてのプラットフォームで動作します。 Haskell Platformの価値は、あらかじめコンパイルされパッケージ化されているだけです。 – ehird