前回定義した圏論の Monad となるトリプレット (T, η, μ)から逆に、Haskell の Monad を構成するとこうなります。(Monad 則をつかってごにょごにょ計算すると分かります。)
x >>= f := (μ.Tf)(x) return x := η(x)
f:a->T a (Haskell的に言うと f:a->m a)の場合に、この関係を図にするとこんな感じ。
T^2 a / | Tf / | / |μ / ↑ | / |T ↓ x ===> T a | T a ===> x >>= f | / |/ / / f / a
もう一つおもしろいのは、モナド演算する際は、上図のように、
(>>=) :: m a -> (a -> m a) -> m a
というタイプを利用することが多いのですが、一般的な定義は、
(>>=) :: m a -> (a -> m b) -> m b
なので、モナド m a をモナド m b に変換することも可能な点です。
特に、a = m b の場合を考えると、
(>>=) :: m m a -> (m a -> m a) -> m a
という事で、モナドの皮 m を一枚はがす演算が定義できます。
サンプルはこんな感じ。(ただし、最後の一枚の皮ははがせません。。。)
main = do let c = Just ( Just ( Just 999 ) ) print $ c print $ c >>= (\x -> x) print $ c >>= (\x -> x) >>= (\x -> x)
$ runghc monad.hs Just (Just (Just 999)) Just (Just 999) Just 999
これを図にすると、こうなります。
T f = Id x ===> T^2 a ---------------> T^2 a ↑ | |T |μ | ↓ T a ---------------> T a ===> x >> = f = μ x f = Id