言語ゲーム

とあるエンジニアが嘘ばかり書く日記

Twitter: @propella

IT なモナド

まず hugs で Monad が何かという事を調べてみる。

:i Monad

これによると、Monad は class らしい。と言うことはくどいようだがオブジェ
クト指向の言葉で言うとクラスでは無くインタフェースという事だ。実際には、
IO や Maybe や 配列と言った type が Monad を「実装」している。Monad の
一番のハイライトは >>= 演算子だ。>>= 演算子は左側を実行してから右側を
実行する。という事を保障する。なんのこっちゃ。IO や Maybe は難しそうな
ので配列で実験してみる。>>= の type は

(>>=) :: Monad a => a b -> (b -> a c) -> a c

なので、引数としてモナド型と、一引数でモナド型を返す関数が必要だ。最初
の引数は単なる配列で良いとして、一引数で例えば配列を返す関数を用意する。

[1,2,3] >>= \it -> [it * 2]

\it はラムダ式を表現する方法。\it -> [it * 2] で引数を一つ取りそれを倍に
した数字を持つ配列を返す。例えば(\it -> [it * 2]) 5 は [10] になる。全体
としてなんでこれがうまく動くのかよく分からんが、とにかく [2,4,6] が返
る。変数名は何でも良いけど、HyperCard 風に it にしてみました。

>>= は、パイプのような物だと考える事が出来る。ためしに

[1,2,3] >>= \it -> [it * 10] >>=  \it -> [it + 1] 

とやってみる。期待通り [11,21,31] が返る。

結論: Monad 演算子 >>= はパイプのように、操作をつなぐ手段である。>>= 
の後ろは引数を一つだけ受け取る。この引数によって前の操作の続きを行う。

疑問: そもそも、Monad を持ち出さなくても計算の順序は内側からやると決まっ
ている。もしも Monad の存在意義が計算順序を保障する事にあるなら、何で
わざわざ別の仕組みを用意したのだろう。きっとすごい理由があるに違いない!
けどワカラン。

ちなみに、Monad の説明に良くある do 構文は、>>= の構文糖なので、同じよ
うにこう書ける。

do it <- [1,2,3]; it <- [it * 10]; [it + 1]

ただ、この場合は余計事態を複雑に見せてしまう。。。