unsafeセグメンテーション違反エラーが発生し、名前にFFI または関数を使用していない場合、それはどのような状況でも驚くことではありません! これは、GHC にバグがあるか、使用しているライブラリが安全でないことを行っていることを意味します。
Doubleを使用してs の無限リストを出力することmapM_ printはまったく問題ありません。リストは段階的に処理され、プログラムは一定のメモリ使用量で実行されます。使用しているモジュールにバグがあるSystem.Random.Mersenneか、それがベースにしている C ライブラリにバグがあるか、またはコンピュータの問題 (RAM の故障など) があると思われます。1newMTGenこの警告に付随する注意事項:
現在の SFMT ライブラリは非常に不純であるため、現在、プログラムごとに 1 つのジェネレータしか許可されていません。再初期化しようとすると失敗します。
代わりに、提供されているグローバルMTGenを使用する方がよい場合があります。
IO [Double]つまり、そのように変換することはできません[IO Double]。結果のリストがアクションを実行せずにどれくらいの長さになるかを知る方法はありませんIO。これは不可能です。純粋な結果があるためです (たまたまIOアクションが含まれている場合でも)。無限リストの場合、次のように記述できます。
desequence :: IO [a] -> [IO a]
desequence = desequence' 0
where
desequence n m = fmap (!! n) m : desequence (n+1) m
ただし、このリストのアクションを実行するたびに、IO [a]アクションが再度実行されます。リストの残りを破棄するだけです。
randoms機能して乱数の無限リストを返すことができる理由は、 で遅延 IO を使用するためunsafeInterleaveIOです。(名前に「危険」が含まれているにもかかわらず、これはセグメンテーション違反を引き起こすことはできないため、別のことが進行中であることに注意してください。)
1その他の可能性は低いですが、C ライブラリのコンパイルミスや GHC のバグが含まれます。