- IO型の特殊性
- IO型は対話形式にするための仕組み
- HaskellはIOを除くと、「ファイルにすべてを書き込んで(→コンパイルして)→実行する」〜「いつも同じことをするだけ」という処理を作る
- Haskellで対話式入出力をするときは、対話の受付口と対話の返却口を開いてやる
- Haskellでは、対話は「受付口」と「返却口」のペアとして考えている
- この対話の「受付口」と「返却口」とは、「引数」と「返り値」という関係ではない
- したがって、「『受付口』と『返却口』とでできたその一塊」を一つの型としてとらえて、IO型と名付ける
- IO型の使い方の特殊性
- IO型はその他の普通の型と「並置して」扱う
- IO型はその他の普通の型と「並置して」扱うとき、その動作を「アクション」と呼ぶ
- -
- IO型を持つアクション
- 3つある
- getChar
- 以下に示すように、"IO Char"という型があるだけであって、変化を起こす"->"はない
Prelude> :info getChar
getChar :: IO Char
Prelude> :info putChar
putChar :: Char -> IO ()
Prelude> :info return
class Monad m where
...
return :: a -> m a
...
Prelude> putChar 'a'
aPrelude> getChar
a
'a'
Prelude> Prelude
Prelude> let x = 3
Prelude> x
3
Prelude> return x
3
Prelude> :info >>=
class Monad m where
(>>=) :: m a -> (a -> m b) -> m b
...
infixl 1 >>=
-
- IO型がモナドクラスなので、mをIOに書き換え、aをChar、bもCharとすれば
(>>=) :: IO Char -> (Char -> IO Char) -> IO Char
-
- となる
- これは、getChar アクションの型があって、その次にreturnアクションの型があって、次にまたgetCharアクションの型がある、と読める
- ここでIOしながらの作業であることを忘れないために、一連の流れの中でIOが消えることはない
- do記法
m a -> (a -> m b) -> m b
-
- IO a をして、そのうち、プログラム本体で扱うことが許されたaのみを受けとって(a -> IO b) をして、という部分は、IOを渡さないことがわかっているので、以下のように、IOの関係ないものの受け渡しのように書いても、誤解がない
- そのための記法であることの符丁として"do"が使われていて、do記法と呼ばれる
hoge do c <- getChar
putChar c