ハスケルの初心者として、私は関数(例えば、ロジスティックマップ)を何回も繰り返そうとしています。命令型言語ではこれは単純なループになりますが、Haskellではスタックオーバーフローが発生します。コードが動作の反復の数が少ないためHaskell:stackoverflowを使わずに多数の関数を繰り返す
main = print $ iter 1000000
f x = 4.0*x*(1.0-x)
iter :: Int -> Double
iter 0 = 0.3
iter n = f $ iter (n-1)
を、しかし、百万回の反復のために私はスタック領域のオーバーフローを得る:例えば、このコードを取り、これが起こるんなぜ私が理解できない
Stack space overflow: current size 8388608 bytes.
Use `+RTS -Ksize -RTS' to increase it.
。尾の再帰はここでうまくいくはずです。 問題は遅延評価です。 $!
またはseq
をさまざまな位置に挿入することで、厳密な評価を強制するいくつかの方法を試しましたが、成功しませんでした。
関数を膨大な回数繰り返すハスケルの方法は何でしょうか?
私は、関連記事からの提案を試してみました:hereまたはhereが、私は常に多数の反復、例えば、main = print $ iterate f 0.3 !! 1000000
のためにStackOverflowになってしまいました。
問題は、 'iter(n-1)'を直接返さないので、末尾再帰を持たないということです。 – Simon
人々はちょうど末尾再帰が何であるか分かりません。 FYI、この定義は間違っています:「関数の名前がその関数の最後の行に現れたとき」。 – Ingo