モナドとの付き合い方。

モナドの本当の意味を理解しようとすると、圏論の概念や定理に対する正確な理解が必要だが、それは、不可能に近い。それにもかかわらず、データを表示したり、ファイルの読み書きなどIOモナドを使ったプログラムを書くことはできる。要するに、正確な理解はできなくてもプログラムは動くのだ。それに、使っているうちにモナドの振る舞いが何となくわかってきてモナドの利点を利用したプログラムが書けるようになるかもしれない。

ただ、モナドを使ったプログラムをするときに気をつけておいたほうが良い点がありそうなので書いてみた。もちろんモナドを圏論的に理解しているとは言えないのであくまでも印象だ。

1.モナドの大きな特質は、一連のプログラムとデータのカプセル化だ。たとえば、IOモナドの中で使う関数は、IOモナドを引数にとり、IOモナドを戻り値として戻す。つまり、IOモナドに関連する関数はIOモナドの世界から抜けられない。したがって、IOモナドの中で定義されている関数の戻り値を普通の関数が利用するにはインターフェースがいる。

2.Bind 演算子( >>= ) の働きは関数の結合であるが、通常の関数の合成を拡張した働きを持っていることが多い。たとえば、Maybe モナドは、Nothing と Just a の2種類のデータを次の関数に伝達することができるし、IOモナド型の bind 演算子は、関数の実行される順序を保つように設計されている。また、この演算子をモナド内で利用することで、関数を結合してそのモナド内で働く新しい関数を簡単に作り出すことができる。

3.Return 関数は、定義としてはモナド内の単位元で、恒等関数だが、普通の関数の世界の値をIOモナド内に移すインターフェースの役割を果たす。普通の関数の世界で定義した関数の戻り値を利用する時、return 関数によってモナドの値を返すように記述することができる。

4.>>= 演算子の引数はモナドの関数で、モナド型の値はその関数の引数であるという関係がある。モナドで集合の要素の役割を果たすのはあくまでも関数だが、これらの関数は必ずモナド型の値を引数にし、モナド型の値を返さなければならない。

5.モナドを利用したプログラムは、それぞれのモナド内で完結した小宇宙を持つことになる。モナド内の bind 演算子によるプログラムの結果はモナドの世界の外に出ることはないのでプログラムのモジュール化が保証される。プログラマはモナド内でプログラムしたものが他の領域に干渉することを懸念せずにプログラムを進めていくことができる。

まとめると、モナドでプログラムをする理由は、プログラムのカプセル化であるということ。モナドの世界では、集合の要素に当たるものが関数であること、また、モナド内の関数が扱う値は必ずモナド型の値でなければならないこと、return 関数はモナドの世界と外部世界とのインターフェースであるということ、bind 演算子を用いる演算はモナドの世界から出ることはないのでプログラマはモナド間の干渉を気にしないでプログラムできるということ、また、bind 演算子には関数の合成以外の機能をもたせることができるということなどではないだろうか。

Haskell に関するブログを見ても、みんなモナドの取り扱いについは苦慮しているようだが、それぞれの解釈でプログラムはきちんと動いているようだ。知識として学ぶのは大変だが、使うのは簡単だという Haskell の大原則がここでも見られる。モナドなど理解できなくても使ったもの勝ちなのだ。
[PR]
by tnomura9 | 2009-08-28 07:09 | Haskell | Comments(0)
<< Maybe モナドのプログラミング モナド >>