入出力処理

このページでは,Haskell における入出力処理に関する基本的な話題を説明します.

1. I/O アクション

入出力処理など副作用を伴う演算は,I/O アクション(I/O action)と呼ばれる値で表現されます. 実行すると a 型の結果を返すような I/O アクションは,IO a 型の式として記述します.

Haskell の Hello World プログラムは,次のように書かれます.

main :: IO ()
main = putStrLn "hello, world"

Haskell は,変数 main に束縛された I/O アクションを実行します. 普通,main の型は IO () となります. 型 IO () は,I/O アクションを実行した時に意味のある値が返されないことを意味します.

2. 標準入出力

標準入出力用の I/O アクションや,I/O アクションを作る関数には,次のようなものがあります.

 説明
getCharIO Char1 文字を入力
getLineIO String文字列を 改行文字まで入力
getContentsIO String文字列を EOF まで入力
putCharChar -> IO ()1 文字を出力
putStrString -> IO ()文字列を出力
putStrLnString -> IO ()文字列に改行付きで出力
printShow a => a -> IO ()引数を文字列化して出力

getLine アクションで取得される文字列に改行文字は含まれません.空行が入力された場合には空文字列が返されます.

3. 複数のアクション

複数の I/O アクションを実行するには,do 式が便利です. 次のプログラムは,名前を入力すると "Hello, <名前>!" という挨拶を表示するものです.

main :: IO()
main = do
    putStrLn "What's your name?"
    name <- getLine
    let greeting = "Hello, " ++ name ++ "!"
    putStrLn greeting
What's your name?
Taro
Hello, Taro!

I/O アクションの do 式には,次の 3 通りの式が書けます.

(a) アクション
(b) パターン <- アクション
(c) let { 宣言1 ; …​ ; 宣言n }

式 (b) は,右辺が IO a 型であれば,アクションの実行結果である a 型の値を左辺のパターンに束縛します. 式 (c) は,普通の変数や補助関数を宣言します. 式 (b),(c)で宣言された名前は,その do 式の中だけで有効です.

4. ファイル

簡易的なファイル入出力には,次の 3 関数を使うのが便利です. 型 FilePathString の別名で,ファイルパスを表します.

関数説明
readFileFilePath -> IO String読み込み
writeFileFilePath -> String -> IO()書き込み
appendFileFilePath -> String -> IO()追記方式で書き込み

より高度な操作を行うには,ファイルハンドルを利用する以下の関数が役に立ちます. これらの関数は System.IO モジュールをインポートすると利用できます.

関数説明
openFileFilePath -> IOMode -> IO Handleファイルを開く
hCloseHandle -> IO()ファイルを閉じる
hGetContentsHandle -> IO StringgetContents のバリアント

IOMode 型の値は,ReadMode, WriteMode, AppendMode, ReadWriteMode のいずれかから選べます. この表では省略しましたが,hGetContens の他に hGetChar, hPutStr, hPrint などの関数も利用できます.

次のプログラムは,hGetContents 関数によってファイル hoge.txt の内容を表示する例です.

import System.IO

main :: IO()
main = do
    handle <- openFile "hoge.txt" ReadMode
    text <- hGetContents handle
    putStr text
    hClose handle

5. コマンドライン引数

コマンドライン引数は getArgs,プログラム名は getProgName で取得できます. これらを利用するには System.Environment モジュールをインポートします.

アクション説明
getArgsIO [String]コマンドライン引数のリスト
getProgNameIO Stringプログラム名

次のプログラムは,コマンドライン引数とプログラム名を表示する例です.

import System.Environment

main :: IO()
main = do
    args <- getArgs
    print args
    name <- getProgName
    putStrLn name
% ./hoge aaa bbb ccc
["aaa", "bbb", "ccc"]
hoge