IOモナドの >> 演算子

IOモナドのプログラミングは基本的にIOモナドの関数を >>= 演算子でつないでいくことになる。したがって、前段の関数の出力(厳密にはIO a 型のパラメータ)の型と、後段の関数の引数の型が一致していなければならない。したがって、前段の戻値と後段の引数の型があわないとき、型エラーになってしまう。

例えば、次のようなプログラムはエラーになる。

Main> putStr "input name: " >>= getLine >>= putStrLn
ERROR - Type error in application
*** Expression : putStr "input name: " >>= getLine
*** Term : getLine
*** Type : IO String
*** Does not match : a -> b c

つぎのように、putStr は、IO () 型のデータを返すのに、getLine は引数を取らないからだ。

Main> :info putStr
putStr :: String -> IO ()

Main> :info getLine
getLine :: IO String

こういう時は、>>= 演算子の代わりに >> 演算子を使う。>> 演算子は前段の関数の戻値を無視して、後段に伝えない作用があるからだ。したがって、上のプログラムは putStr "input name: " >> getLine のように >>= 演算子ではなく、>> 演算子を使うとうまく動く。

Main> putStr "input name: " >> getLine >>= putStrLn
input name: Dolly
Dolly

do 記法の時は >>= と >> の選択は自動的に起きるようなので次のように書いてもエラーが出ない。そのため、一見手続き型のプログラムのようにみえるが、IOモナドが >>= 演算子を介してデータの受け渡しをやっているということが忘れられやすい。

main = do
  putStr "input name: "
  cs <- getLine
  putStrLn cs

また、余計な変数名を考えないでいい分、パイプライン型のプログラムのほうが楽な気がする。
[PR]
by tnomura9 | 2010-10-29 11:47 | Haskell | Comments(0)
<< IOモナドのループ処理 IOモナドでパイプラインプログラム >>