step
したがって、基本的には、前の結果を取り込んで を出力する計算がありますRand g Path
。ここPath
で、 はカスタム データ型です (巡回セールスマンのような問題と考えてください)。MonadRandom
ジェネレーターの受け渡しなどすべてを処理させます。
たとえば、この計算自体の n 番目の構成を見つけたいと思います。今、私は使用しています
thecomputation :: (RandomGen g) => Rand g Path
thecomputation = (iterate (>>= step) (return startingPath)) !! n
そして、それを印刷するために実行します
main = do
res <- evalRandIO thecomputation
print res
しかし、私には問題があります
十分な高さを選択するn
と (10^6 のオーダーが必要です)、スタック オーバーフローが発生します。
私は、計算が実際には重く構成された (ネストされた?) IO オブジェクトであるという事実に問題を追跡することができました。これは一連の IO 計算であるため、ghc はネストされた IO のすべてのレイヤーを追跡する必要があり、十分な数のレイヤーの後、あきらめます。
これにどう対処すればいいですか?命令型言語では、これにはあまり意味がありません。しかし、私はここで何をすべきですか?一部の IO を強制的に評価する必要がありますか、それとも ...?
このサイトには同様の質問がありますが、受け入れられた回答から役立つものを得ることができなかったので、まだかなり迷っています
具体例
import System.Random
import Control.Monad.Random
import Control.Monad
data Path = DoublePath Double deriving Show
step :: (RandomGen g) => Path -> Rand g Path
step (DoublePath x) = do
dx <- getRandom
return (DoublePath ((x + dx)/x))
thecomputation :: (RandomGen g) => Rand g Path
thecomputation = (iterate (>>= step) (return (DoublePath 10.0))) !! 1000000
main = do
result <- evalRandIO thecomputation
print result
コンピューターでオーバーフローする