私は実世界の Haskell (私は第 4 章にいます) に取り組んでおり、本から少し外れた練習をするために、n 番目の素数を計算する次のプログラムを作成しました。
import System.Environment
isPrime primes test = loop primes test
where
loop (p:primes) test
| test `mod` p == 0 = False
| p * p > test = True
| otherwise = loop primes test
primes = [2, 3] ++ loop [2, 3] 5
where
loop primes test
| isPrime primes test = test:(loop primes' test')
| otherwise = test' `seq` (loop primes test')
where
test' = test + 2
primes' = primes ++ [test]
main :: IO()
main = do
args <- getArgs
print(last (take (read (head args) :: Int) primes))
明らかに、素数のリストを保存しているので、これは一定の空間ソリューションではありません。問題は、非常に大きな素数を取得しようとすると./primes 1000000
、エラーが発生することです。
Stack space overflow: current size 8388608 bytes.
Use `+RTS -Ksize -RTS' to increase
テール再帰が正しく行われたことはかなり確信しています。http://www.haskell.org/haskellwiki/Stack_overflowを読んで、ここのさまざまな応答から、それは遅延評価の副産物であると信じるようになり、サンクはオーバーフローするまで蓄積されますが、これまでのところ修正に失敗していますそれ。いろいろなところに使っseq
て評価を強制してみましたが、効果がありませんでした。私は正しい軌道に乗っていますか?私が得ていないものは他にありますか?