コードを仮定します
f :: IO [Int]
f = f >>= return . (0 :)
g :: IO [Int]
g = f >>= return . take 3
g
ghci で実行すると、stackoverflow が発生します。[0, 0, 0]
しかし、私はそれが怠惰に評価され、製品がに包まれるのではないかと考えていましたIO
。ここにIO
責任があると思いますが、本当にわかりません。明らかに、次のように機能します。
f' :: [Int]
f' = 0 : f'
g' :: [Int]
g' = take 3 f'
編集:実際、私はそのような単純な関数を持つことに興味がありませんf
。元のコードは次のように見えました:
h :: a -> IO [Either b c]
h a = do
(r, a') <- h' a
case r of
x@(Left _) -> h a' >>= return . (x :)
y@(Right _) -> return [y]
h' :: IO (Either b c, a)
-- something non trivial
main :: IO ()
main = mapM_ print . take 3 =<< h a
h
いくつかのIO
計算を行い、有効な応答 ( ) が生成さLeft
れるまで無効な ( ) 応答をリストに格納します。モナドRight
内にいるにもかかわらず、リストを遅延して構築しようとしています。IO
の結果を読んでいる人h
が、リストが完了する前であってもリストの消費を開始できるようにします (リストは無限になる可能性があるため)。そして、結果を読む人3
が何があっても最初のエントリだけを気にするのであれば、残りのリストを構築する必要さえありません。そして、これは不可能だと感じています:/。