catコマンドを実装してみる
Haskellの練習として、catコマンドを実装してみる。
getConentsを使う
もっとも簡潔な実装。
-- cat1.hs main = getContents >>= putStr
do記法を使って書くと次のようになる。
main = do x <- getContents putStr x
上のコードは下と同値である。
main = getContents >>= (\x -> putStr x)
ここで、>>=
はいわゆるbind演算である。
(\x -> putStr x)
はputStr
そのものなので、より簡潔な形に直すことで最初のコードになる。
実行結果。
$ runghc cat1.hs hoge hoge fuga fuga [Ctrl+D]
getLineを使う
getLineで1行ずつ読む場合は、EOFErrorのハンドルが必要になる。
-- cat2.hs import System.IO.Error main = catchIOError catLoop handleError where catLoop = getLine >>= putStrLn >> catLoop handleError e | isEOFError e = return () | otherwise = ioError e
putStrLnの戻り値(IO型)はcatLoopに必要ないので、>>=
の代わりに戻り値を捨てる>>
を使う。
handleErrorはEOFErrorのときのみ()
(unit、空の値を表す)を値に持つモナドを返し、それ以外のときはIOErrorを値に持つモナドを作って返す。
実行結果。
$ runghc cat2.hs hoge hoge fuga fuga [Ctrl+D]