あどけない話

インターネットに関する技術的な話など

モナド則

3つのモナド則の内、ようやく2つが理解できました。

(return x) >>= f == f x

以下のような DB を考えます。

db = [("alice", [("title", "Ms."), ("city", "Yokohama")]),
      ("bob",   [("title", "Mr."), ("city", "Sapporo" )])]

"alice" の "city" が調べたいなら、こういう風にするでしょう。

lookup "alice" db >>= lookup "city"
→ Just "Yokohama"

左と右の lookup の使い方が違うのはなぜか常々疑問でした。左側では、db がいつのまにか Maybe モナドになっているのです。(ここは僕の思い違いでした。db は Maybe モナドになっていません。)

2つの lookup を同じように使うには、こう書きます。

return db >>= lookup "alice" >>= lookup "city"
→ Just "Yokohama"

これなら、return でモナドを作り、lookup を >>= で適応していくので、論理的には理解しやすいです。

しかし、いちいちこう書くのは面倒ですね。そこで、モナド則の出番です。

(return x) >>= f == f x

これは、return db >>= lookup "alice" と書く代わりに、lookup "alice" db と書けますよという意味だったんですね。

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

これが理解できなかった理由が分りました。丸括弧が

  • 結合力
  • 関数

の 2 つの意味で使われています!

左は結合力の括弧で、右は関数の括弧ですね。右も結合力かと思って混乱していました。

>>= は左結合なので、

m >>= f >>= g

は、

(m >>= f) >>= g

のように処理されます。

その意味するところは、

  • m から値 x を取り出し、f を適応しモナドを作る
  • そして、そのモナドに >>= g を適応する (値を取り出し、g を適応してモナドを作る)

なんですね。

m >>= return == m

この法則の意味するところが何なのか、分る人がいたら教えて下さい。do 記法の最後に return することと関係あるのかなぁ。。。

追記

m さんの言うことが分った気がしますので、追加します。

lookup "alice" の型は、[(String, a)] -> Maybe a です。だから、

lookup "alice" db

と書けるのは当然です。この結果は Maybe モナドです。

Maybe モナドの中身を取り出し、lookup "city" を適応し、Maybe モナドを返すには、当然こう書きます。

lookup "alice" db >>= lookup "city"

左右が対象でないのが気持ち悪いなら、モナド則を使ってこうも書けます。

return db >>= lookup "alice" >>= lookup "city"