めもめも

このブログに記載の内容は個人の見解であり、必ずしも所属組織の立場、戦略、意見を代表するものではありません。

Haskell の Monad を圏論の Monad と対比する (2)

前回定義した圏論の 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