人気ブログランキング | 話題のタグを見る

do 記法

前回の記事で述べたようにHaskell の IO モナドは 1 引数で戻り値が IO モナド型の関数を >>= で連結したものだ。IOモナド型関数を「モナド式」と呼ぶらしいのでこの用語を使うと、IOモナドを利用した入出力関数は次のようになる。

モナド式 >>= モナド式 >>= ... >>= モナド式

これは手続き型言語のプログラムとは相当異なっている。しかし、この IO モナドのプログラムを見かけ上手続き型のプログラムと同じように見せるために do 構文を使ったシンタックスシュガーがある。「モナド・ウォークスルルー - Haskell」によると、do 構文は次のような形をしている。

do {式1; 式2; ... ; 式n}

この 式 i には Haskell の式なら何でもよいというわけではなく次の3つの場合に制限される。

(a) モナド式 (引数が一つで戻り値が IO a 型の関数)
(b) パターン <- モナド式
(c) let {宣言 1 ; 宣言 2 ; ... ; 宣言 n }

do 構文はブロックなかの式の並びを上に述べた、モナド式 >>= モナド式 >>= ... というモナド式の連結に変換する働きがあると考えてよい。たとえば次の do 構文を使った手続き言語風のプログラムは、

Prelude> :{
Prelude| do
Prelude| c <- getLine
Prelude| putStrLn c
Prelude| :}
hello, world
hello, world

次のようなモナド式を >>= 演算子で連結したプログラムに変換することができる。

Prelude> getLine >>= \c -> putStrLn c
hello, world
hello, world

また、変数が2つ以上ある場合も

Prelude> :{
Prelude| do
Prelude| x <- getLine
Prelude| y <- getLine
Prelude| putStrLn (x ++ y)
Prelude| :}
hello,
world
hello, world

次のようにモナド式と >>= 演算子だけのプログラムに変換できる。

Prelude> getLine >>= \x -> (getLine >>= \y -> putStrLn (x ++ y))
hello,
world
hello, world

このように、モナド式と >>= 演算子だけのプログラムに変換できないようなプログラムが、手続き言語の類推で書かれていた場合、意味不明のエラーメッセージに悩むことになる。そういうエラーは、IOモナドの本質をつかんでいればたやすく発見できるが、手続き言語の類推では発見できない。

IO モナドに挑戦するのは、Haskell に十分慣れてからでもいい。ghci 上で作業をしていれば、IO モナドがなくてもかなりの処理ができるからだ。

by tnomura9 | 2018-10-09 19:16 | Haskell | Comments(0)
<< do 記法とは何か IOモナドを理解するのに圏論は... >>