そこで、単純な試行除算を使用して Haskell を学習するのに役立つ素数のリストを作成しています (この言語に慣れるまで、手の込んだものは必要ありません)。次のコードを使用しようとしています。
primes = 2 : [ x | x <- [3..], all (\p -> (mod x p) /= 0) primes]
これはエラーなしでロードされます。でも:
>take 2 primes
[2ERROR - C stack overflow
ネストされたリスト内包表記で同じことを試しました。うまくいきません。再帰呼び出しが多すぎると思いますが、素数を 1 つしか計算していない場合はそうではありません。私の考えでは、遅延評価はそれを次のようにする必要がtake 2 primes
あります。
primes = 2 : [ 3 | all (\p -> (mod 3 p) /= 0) [2] ]
mod 3 2 == True
それほど多くの計算を必要としないのはどれall (\p -> (mod 3 p) /= 0) == True
ですかtake 2 primes == [2, 3]
? これが機能しない理由がわかりません。関数型プログラミングの黒魔術に精通した誰かが私を助けてくれることを願っています...
それが違いを生むなら、これはHUGSにあります。
編集-私はこの解決策を思いつくことができました(きれいではありません):
primes = 2 : [ x | x <- [3..], all (\p -> (mod x p) /= 0) (takeWhile (<= (ceiling (sqrt (fromIntegral x)))) primes)]
EDIT2- HUGS または GHCi を介して解釈すると、プログラムは正常に動作しますが、GHC でコンパイルしようとすると、出力されますtest: <<loop>>
。誰が問題が何であるか知っていますか?