日別アーカイブ: 2014年8月29日

IOモナドに汚染される感覚。

 IOモナドに汚染される感覚。実用的なプログラムには必ずI/Oがある。必ずある。にもかかわらず純粋関数型言語であるHaskellにおいてIOはモナドとして表現されている。モナドが絡むと面倒が一気に増えるように感じる。実際増える。ディレクトリ一覧を操作したいだけなのにIOモナドが付いてまわる。乱数を使いたいだけなのにIOモナドが付いてくる。現在日時を使いたいだけなのにIOモナドがひっ付いてくる。IOモナドを扱う関数を呼ぶ側にも必ずIOモナドを扱わせないといけない。コマンドラインパラメタにはIOモナドが付いてくるのでプログラムのmain側には必ずIOモナドがありるが、そこから呼ばれる関数にはIOモナドがある必要はない。しかし例えば乱数を使うとなるとその関数を含めそこからmainまでの全ての階層の関数にIOモナドを付けなくてはならない。これがIOモナドに汚染される感覚となる。IOモナドを封じ込める方法はあるようなのだが邪道とされている。困ったもんだ。モナドの何が面倒かって、mapでなくmapMを使わなくてはいけなくなる。ロジック的には普通にmapで表現できるはずのことがmapMでないと表現できなくなる。これって関数型言語一般の問題じゃないですよね。純粋関数型言語だからこその問題ですよね。しかもIOモナドはHaskell特有の機能。簡単な問題を面倒臭く解くことになっちまう。

 例えば指定したディレクトリ以下のファイルリストを得るコードで再帰の時にmapMを使う。ロジック的にはmapで十分な部分なのだがIOモナドのおかげでmapMになってしまっている。普通にmapで書くべき部分でmapMなんて取って付けたような変な名前の関数を使うのはなんというか気色悪い。モナドを導入して得たものは参照透過性。参照透過性や正格性がどれだけ大切かわからないが、Haskellでは数千行が限度で、数万行は書けない、仕事には使えそうにないと感じた。IOモナドに汚染される感覚のせいである。

 なんというかひどいツンデレですね。汚れ仕事は全部モナドに丸投げ。

 ちなみにPythonもインタプリタのまま(コンパイラでのチェックなし)では数万行は書けないと感じる。ScalaはJavaやC/C++/C#と同じように数万行は普通に書ける。不純な(^^;)言語なのでモナドが漏れだすこともない。