generated at
Kleisli TripleとMonadの対応
Kleisli TripleMonad型クラスの定義を同時に見ることで対応を見る


Kleisli Tripleの3つ組(T,\eta,(-)^*)が以下のような対応になる
対応
クライスリトリプルHaskell
T型コンストラクタM
ηreturn
(-)^*(=<<)反対向きのbind



Monad型クラスの定義
hs
class Applicative m => Monad (m :: * -> *) where (>>=) :: m a -> (a -> m b) -> m b return :: a -> m a
また、 (=<<) は、 (>>=) の2つの引数を入れ替えたものなので、
型は、 (a -> m b) -> m a -> m b



Kleisli Tripleの満たすべき3条件と、モナド則の対応
クライスリトリプル
f^*\circ\eta_A=f
\eta_A^*=\mathrm{id}_{TA}
g^*\circ f^*=(g^*\circ f)^*
モナド則
hs
return x >>= f == f x -- ① m >>= return == m -- ② (m >>= f) >>= g == m >>= (\x -> f x >>= g) -- ③
前提
hs
return :: A -> M A f :: A -> B g :: B -> C
コツは、
Kleisli Triple\eta (=<<) が対応しているわけだが、
Monad型クラスでよく定義される (>>=) と向きが逆であることに注意すること
Monad型クラスの方を (=<<) に変換してから考えるとわかりやすくなる
またKleisli Tripleの方は、写像の話しかしていない
ポイントフリーにしてる感じ
なので良い感じに引数を与えてあげるとHaskellとの対応が取りやすくなる
モナド則の x とか m はどこから来たの?という感じなので、例えば①も \x -> return x >>= f のように、 x を引数として与えるように書き直せば扱いやすくなる


①の対応
f^*\circ\eta_A=fの左辺をそのままHaskellで書くと、
(=<<) f . return になる
この型は、 A -> B である
これのbindの向きを変えて、 >>= を使うように変更すると、
(\x -> x >>= f) . return と書ける
合成 . の仕方を考えれば、これは (\x -> return x >>= f) と同じであることがわかる
これで、両者の左辺f^*\circ\eta_A return x >>= f の対応が取れた
右辺も同じで、ちゃんと書けば \x -> f x なので、対応が取れている
図で見るとわかりやすい
Kleisli Tripleの図と、Haskellの記号と一緒に描いてみた



②の対応
\eta_A^*=\mathrm{id}_{TA}の左辺をそのままHaskellで書くと、
(=<<) return になる
この型は、 M A -> M A
これのbindの向きを変えて、 >>= を使うように変更すると、
\m -> (=<<) return m
\m -> (>>=) m return
\m -> m >>= return
これは、モナド則の2つ目の左辺と同じである
右辺も m を与えてあげるようにすれば、
\m -> id m であり、これはモナド則の右辺と同じ
Kleisli Triple#615947c819827000003e424eをHaskellの記号と一緒に描くと



③の対応
g^*\circ f^*=(g^*\circ f)^*の左辺と右辺を別々に変換していって、モナド則と同じ形にする
まず左辺を見る
g^*\circ f^*をそのままHaskellで書くと
(=<<) g . (=<<) f
(\m -> (=<<) g m) . (=<<) f
g の方をポイントフリーでなくしたmrsekut
(\m -> m >>= g) . (=<<) f
g の方で >>= を使うように書き換えたmrsekut
\m -> (=<<) f m >>= g
\m -> m >>= f >>= g
これで、モナド則の左辺と同じになった
右辺
(g^*\circ f)^*をそのままHaskellで書くと、
(=<<) ((=<<) g . f)
(=<<) ((\x -> (=<<) g x) . f)
g の方をポイントフリーでなくしたmrsekut
(=<<) ((\x -> x >>= g) . f)
g の方で >>= を使うように書き換えたmrsekut
(=<<) (\x -> f x >>= g)
\m -> (=<<) (\x -> f x >>= g) m
\m -> m >>= (\x -> f x >>= g)
これで、モナド則の右辺と同じになった