私はHaskellを(非常に良い意味で)学ぼうとしています。私が行っているさまざまなことの1つは、自分の気力をテストするために、プロジェクトオイラーの問題に取り組んでいることです。
フィボナッチベースの問題のいくつかを実行する際に、私はつまずいて、フィボナッチ数列の再帰的な無限リストバージョンをいじり始めました。
fibs = 1 : 2 : zipWith (+) fibs (tail fibs)
PEの問題の1つとして、4,000,000未満のフィボナッチ数のサブシーケンスを抽出する必要がありました。私はこれをリスト内包表記で行うことにしました。コードをいじってみると、よくわからないことがわかりました。物事を複雑にしているのは、Haskellの遅延評価スキームに対する私の弱い理解だと思います。
次の理解は問題なく機能します。
[x | x <- takeWhile (<= 4000000) fibs, even x]
次の理解は永遠に回転します。それで、私は調べて、出力をstdoutに戻しました。それが正しい場所で停止している間、上限値に達した後、終了せずに再帰的に定義されたリストを永遠に評価し続けるようです。リストの最後の項目がコンマで印刷されているが、それ以上のリスト項目または閉じ角括弧が存在しないという事実を示します。
[x | x <- fibs, x <= 4000000, even x]
では、無限のリストでうまく機能するさまざまな関数で使用される秘密のソースは正確には何ですか?