ファイルを行単位で処理する
以下のようなテキストファイルsample.txtがあるとします。
code:_
Lorem ipsum dolor sit amet, consectetur
adipiscing elit, sed do eiusmod tempor
incididunt ut labore et dolore magna aliqua.
このテキストファイルから一行ずつ文字列を取得するには[hGetLine https://hackage.haskell.org/package/base/docs/System-IO.html#v:hGetLine]という関数を使います。
code: (hs)
import System.IO
:t hGetLine
hGetLine :: Handle -> IO String
handle <- openFile "sample.txt" ReadMode
hGetLine handle
"Lorem ipsum dolor sit amet, consectetur"
hGetLine handle
"adipiscing elit, sed do eiusmod tempor"
hGetLine handle
"incididunt ut labore et dolore magna aliqua."
hGetLine handle
*** Exception: sample.txt: hGetLine: end of file
hGetLineはファイルを最後まで読み込んだ後に実行すると例外を吐いてしまいます。ファイルから一行ずつ読み込んで終端まで来たら安全に処理を止めるプログラムを書くには[hIsEOF https://hackage.haskell.org/package/base/docs/System-IO.html#v:hIsEOF]という関数を使ってファイルの終端に来たかどうかを判定するのがいいでしょう。以下にファイルを一行ずつ読み込んで各行に含まれる単語数を出力するプログラムの例を示します。
code: (hs)
:{
| countLines :: Handle -> IO ()
| countLines handle = do
| isEOF <- hIsEOF handle
| if isEOF
| then pure ()
| else do
| line <- hGetLine handle
| print (length $ words line)
| countLines handle
| :}
handle <- openFile "sample.txt" ReadMode
countLines handle
6
6
7
#recipe-collection