withFileとopenFileの違い 質問する

withFileとopenFileの違い 質問する

このプログラムは、\n で区切られたテキストの入力ファイルを与えられた場合に、期待どおりの出力を生成します。

import System.IO

main :: IO ()
main = do h <- openFile "test.txt" ReadMode 
          xs <- getlines h
          sequence_ $ map putStrLn xs

getlines :: Handle -> IO [String]
getlines h = hGetContents h >>= return . lines

openFileをwithFileに置き換えて少し並べ替えると

import System.IO

main :: IO ()
main = do xs <- withFile "test.txt" ReadMode getlines
          sequence_ $ map putStrLn xs

getlines :: Handle -> IO [String]
getlines h = hGetContents h >>= return . lines  

まったく出力が得られません。困惑しています。

追記:もう困惑していません。思慮深く考えさせられる回答をくださった皆様に感謝します。ドキュメントをもう少し読んで、次のことを知りました。ファイル付きの部分的な応用として理解できるブラケット

最終的にこうなりました:

import System.IO

main :: IO ()
main = withFile "test.txt" ReadMode $ \h -> getlines h >>= mapM_ putStrLn 

getlines :: Handle -> IO [String]
getlines h = lines `fmap` hGetContents h

ベストアンサー1

ファイルが閉じられるのが早すぎます。ドキュメンテーション:

ハンドルはwithFile の終了時に閉じられます

これは、関数が返されるとすぐにファイルが閉じられることを意味しますwithFile

および の仲間は怠惰なのでhGetContents、 で強制されるまでファイルを読み取ろうとはしませんputStrLnが、その時点では、withFileすでにファイルが閉じられているでしょう。

問題を解決するには、全体を に渡しますwithFile:

main = withFile "test.txt" ReadMode $ \handle -> do
           xs <- getlines handle
           sequence_ $ map putStrLn xs

これが機能するのは、withFileファイルを閉じるまでに、すでに印刷が完了しているからです。

おすすめ記事