Yet Another Haskell Tutorial 24

9.2 Definition

この節では、Monad (タイプ)クラスの多相関数 retrun と >>= が満たすべき条件について説明してある。

class 宣言で Monad (タイプ)クラスの多相関数が宣言されても、それは単にそれらの多相関数の型が宣言されているだけだ。自前のデータ型を Monad (タイプ)クラスのインスタンスにするためには、instance 宣言と同時に多相関数の実装をしなければならない。この実装については、class 宣言では何も言っていないのだ。

しかし、自前のデータ型の多相関数 return と >>= は自由に実装を設計していいという訳ではなく、それらがある条件を満たしていないと、自前のデータ型をモナドとして扱う事ができない。端的には、基準を満たしていない場合、do 記法がきちんと動作しない。

この return と >>= が満たすべき条件は、次の3つでモナド則と呼ばれている。

1. return a >>= f ≡ f a
2. f >>= return ≡ f
3. f >>= (\x -> g x >>= h) ≡ (f >>= g) >>= h

第1の規則は return の >>= 演算に対する右単位元性、第2の規則は retrun の左単位元性、第3の規則は >>= の結合法則と呼ばれている。しかし、この意味を正確に理解する事は不可能だ。なぜなら、これらのモナド則は圏論の Kleisli 圏についての規則で、retrun も >>= も単なる関数ではなく、自然変換つまり関手から関手への射だからだ。

完全に理解することが必須の条件なら、自前のモナドなど到底プログラムする事はできないが、さいわい上のモナド則は操作的に理解するだけで十分な場合が多い。もちろん、きちんと理解したい人むけのページもある。

第1の規則は return の引数 a は >>= をはさんで右項のアクション f へ渡す事ができるということを意味している。第2の規則は >>= の左項のアクション f から引き継いだ値は return を介してもそのままだという事を意味している。第3の規則は荒っぽく言うと f >>= g >>= h というアクションの連鎖が結合的であるということ、つまり、 (f >>= g) >>= h == f >>= (g >>= h) のように >>= の演算の順番を変えても結果は同じであることを意味している。

したがって、YAHT の説明も抽象的で理解が難しくなっているが、理解できないところは置いておいて、return と >>= には実装の際の条件がある事、do 記法の記述を return と >>= を使ったモナド演算に翻訳するにはどうするかということ位を押さえて軽く通り過ぎた方がいいかもしれない。

9.2.1 Law 1

このサブセクションでは第1の法則 return a >>= f a について説明されている。説明の方は本文を読んでもらう事にして、上の規則を ghci で試してみよう。

Prelude> return "hello" >>= putStrLn
hello

操作的には return の引数 "hello" は >>= を介して putStrLn に引き渡されている。また、return を使った do 記法は次のように翻訳される。

do {x <- return a; f x} == do {f x}

9.2.2 Law 2

このサブセクションでは第2の法則 f >>= return == f を表している。>>= の右の return は受け取ったデータをそのままラッピングして返すだけだ。

Prelude> getLine >>= return
hello
"hello"

do 記法では次のように書き換える事ができる。

do {x <- f; return x} == do {f}

9.2.3 Law 3

ここでは第3の法則 f >>= (\x -> g x >>= h) ≡ (f >>= g) >>= h について述べてある。ghci で確認すると次のようになる。

Prelude> return 2 >>= (\x -> return (2*x) >>= print)
4
Prelude> (return 2 >>= \x -> return (2*x)) >>= print
4

do 記法に置ける結合法則の翻訳は次のようになる。

law3a = do
  x <- f
  do g <- x
     hy

law3b = do
  y <- do x <- f
           g x
  h y

Yet Another Haskell Tutorial 25 へ続く ...
[PR]
by tnomura9 | 2013-03-08 07:24 | Haskell | Comments(0)
<< Yet Another Has... つかさ と さやにゃん >>