2007-07-18
■ [haskell] モナドについてなんか分かった気がした
モナドって「結局何なの?」ってのがいまいち分からずにもやもやしてたんだが、なんか分かった気がしたのでメモ。
関数型言語では値が関数から関数へと流れていくことで計算が行われる。 このプロセスに「一皮被せる」ことで、計算の本筋とは別にいろいろな「仕掛け」を組み込むのがモナド。
値 a をただ流すんじゃなくて、Maybe a のようにモナドという箱に入れて、箱に入ったものどうしの演算を定義することで仕掛けを作る。 Haskellでは、モナドを「returnとbind(>>=)というメソッドが定義されている型」で表す。returnは値を箱に入れる関数。>>=は値を流す関数。
class Monad m where (>>=) :: m a -> (a -> m b) -> m b return :: a -> m a
returnの型は「a -> m a」のようになっている。生の値(a)を取って、箱に入った値(m a)を返すことが分かる。 (mはMaybeとかStateとか、モナドの種類を表す) >>=の型は「m a -> (a -> m b) -> m b」なので、箱に入った値(m a)を適当な関数(a -> m b)に食わせて結果を箱に入れる(m b)ということが 分かる。>>=に渡す関数の型は(a -> m b)なので、引数は生の値だけど返り値は箱に入れないといけないことが分かる。
箱に入れられた値がベルトコンベアを流れていて、それを監視員の人がチェックして 処分したり入れ替えたり整理するようなイメージ。
/ \ / _ノ ヽ、_ \ / o゜⌒ ⌒゜o \ (また明日からモナドの値をチェックする仕事がはじまるお…) | (__人__) | \ ` ⌒´ /
でもって、これを複数の値を同時に扱えるように拡張したのがArrow。
ということで合ってるんでしょうか先生。
残りの疑問:
- なんで箱に入れる関数がreturnという名前なんだろう
- モナドと副作用(IOとか)の関係
- 「圏」ってやつとモナドの関係 (「群」までは授業で習ったんだが、それ以上は…。)
モナドのすべて - Enjoy Programming を読みつつもう少し考えてみよう。
■ [haskell] ちなみになんで唐突にモナドの話をするかというと
id:r-westさんの日記に触発された。
モナドの解説といえばモナドのすべてが一番有名だと思うのだけど、 これは難しい。読もうとしてもう3回くらい挫折している。 で、これの読解ログが こちらのWikiに 書かれてて、これは読みやすい。とても有難い。[☆+]ボタンがあったら連打してたところだ。
あと、「MonadやArrow=値を流すための機構」と考えたら、HaskellでのReactive Programming(FRP)にArrowを使うのがすごく納得できた。 FRPの仕組みを実装するためには「この値が変化したらこいつらに通知する」という連鎖反応のグラフ構造みたいなもんを 用意しないといけなくて、じゃあArrowがぴったりだろ?という。