図でわかる?モナドの説明

モナドで悟りをひらきたいのなら - 図でわかる(?)モナド - 北海道苫小牧市出身の初老PGが書くブログ
このあたりを見ていたら、なんかあたまに降りてきた。けど初見さんに圏論は無理だよなぁ、と思ったので、もっと曖昧で単純な図に起こしてみることにしよう。以下、圏論とかそういうのを隅においておくことにします。あしからず。

モナドの全体図


モナドの目的は「α → m β」の関数を作成すること。例えば「String → Maybe Integer」とか「String → IO ()」とか。その関数の構成を大雑把に表したものが上の図。上図では「a → m c」の関数を作るために色々と頑張ってます。上図では4つのブロックに分かれていて、上から「モナド層」「do 層」「return 層」「演算層」の4種類*1。これらの構造を繋げることで、演算の順序を上手く固定化することができる、という認識です。

モナド

モナド層の目的は、実際に演算をつなげること。モナドな値「m a」「m b」「m c」……が用意されていて、それらが「>>=」関数で結び付けられている、という形になっています。

do 層

do 層の目的は、「>>=」関数と結びつく関数を作成すること。この関数の形式は「α → m β」つまり何らかの値を受け取って、モナドの値を返す関数となります。

演算層

演算層の目的は、実際に値を計算すること。関数の形式としては「α → β」のような形になります。この関数はモナドを返すとは限らないので、もしモナド以外の値を返すような場合は、次の return 層でモナドに変換してあげる必要があります。

return 層

return 層の目的は、一般の値をモナドに変換すること。関数の形式としては「β → m β」のような形になります。

モナド則の意味

モナド則は、モナドを >>= 演算子で結合していく上で、便利な規則を表しています。

m >>= return ≡ m

この規則は、m a の値を return と結合しても、m a のまま変化が無いという意味を持っています。return は何回でも結合することができます。

return a >>= f ≡ f a

この規則は、return a の値を f と結合したものは、a をそのまま f にかけたものと同じという意味を持っています。一番最初の図でも、この規則を用いて図を簡略化することができたりです。

(m >>= f) >>= g ≡ m >>= (\x -> f x >>= g)

この規則は説明が難しいのですが「最終的に得られた“α → m β”の関数を、さらに >>= 関数へと結び付けても良い」ということを表しています。最終的に得られる関数の型も、do 層で作られる関数の型も、どちらも同じ「α → m β」なので、融通が利くという仕組みになっています。
下図の下半分では、「a → m c」関数をさらに >>= へと結びつけています。

メモ

まだまだモナドがよく理解できていないんだけど、とりあえずあたまの中にあることをでろでろっと書き下してみるテスト。ツッコミとか大歓迎です。

*1:命名は適当すぎ。正式名称とかあるのかな