モナドって...

なんとなくモナドのことが分かってきたかな、どうだろう。っていうのが最近の感覚。

モナドが実現しようとしていることは大体理解できたと思っている。実現しようとしていることが何か、一言で言うと、注力したい部分だけに注力できるようにし、注力したくない部分は関知しなくて済む仕組み、ではないだろうか。

モナドは 1 つの型変数をとる。2 つ以上の型変数を引数にとる型でも、部分適用を使うことで、1つの型変数を取る型にすることができる。複雑な型でもモナドクラスに属することができる。

その部分適用した部分に、注力したくない部分を閉じ込めることで、床下配線(モナドの説明ではこの言葉がよく使われる)が出来上がる。床下配線に注力したくないこと任せてしまおうというのがモナドの作戦。

必然的に注力したい型(コードを書く人に任せる部分)は一番右側に来る。このあたりが Either の失敗系 (Left a) が先に来ている理由だとうのをスタートHakell2 の中で理解した。そのときのTweet

*Main> :i Either
data Either a b = Left a | Right b  -- Defined in `Data.Either'

その床下配線はどこで定義されるかというと >>=。モナドクラスに属させるためには return と >>= を実装する必要がある。return は値をデフォルトの文脈に取り込む関数でそれほど難しくはない。return よりも >>= が重要で、この実装次第で色々なモナドが出来上がる(当然 return と >>= のつじつまを合わせないといけないので、return も重要だが)。

色々なモナドがある。あらかじめ用意されているのもあれば、自分で作ることだってできる。モナドが難しいと言われる理由はここにあるのではないだろうか。それぞれのモナドによって動作が異なる。現に私も、リスト、Maybe、Either に関しては理解できるが、他のモナドに関してはまだよくわかっていない。例えば Writer、Reader、State などがそう。なので、モナドを理解したかって聞かれると、してないと答えるのではないだろうか。

すべてのモナドに属する型を理解していなければいけないかというと、当然そんなことはない訳だが、一般的なものに関しては理解はしておきたい。Writer、Reader、State あたりのモナドが理解できるようになれば、モナドがわかったと言えるようになるのではないだろうか。次はそのあたりから攻めていこうか。