みどりねこ日記

よくわからないけど、頑張りますよ。

Haskellのモナド(11)

モナドは数学の分野の一つである圏論から来ました。嬉しいことに、Haskellモナドを理解して利用するために、圏論を理解する必要は全くありません。しかし、圏論でのモナドの定義はHaskellのそれと少し違います。Haskellに持ってきた時に、圏論のそれと同じ意味を持つけれど、より理解しやすく利用しやすい定義に変わりました。

今まで、モナドを >>= と return で定義してきましたが、それ以外にも「モナドが2つの補助的関数を持つファンクタである」という視点からの定義があります。

fmap :: (a -> b) -> M a -> M b  -- これがファンクタ
return :: a -> M a
join :: M (M a) -> M a

ファンクタMはコンテナと考えられることが多く、そのためM aは型aを保持していることになります。
この考えのもと、それぞれの関数について考えると、

  1. fmapは与えられた関数をコンテナのなかにある全ての要素に対して適用する
  2. returnは要素をコンテナの中にいれる
  3. joinはコンテナのコンテナをとって、1つコンテナを外して返す

となります。

これらの関数を用いれば、>>=演算子は以下のように定義することができます。

m >>= g = join (fmap g m)

逆に、fmapやjoinも>>=演算子を用いて定義することが出来ます。

fmap f x = x >>= (return . f)
join x = x >>= id