ふつける

ふつうのHaskellプログラミング ふつうのプログラマのための関数型言語入門

ふつうのHaskellプログラミング ふつうのプログラマのための関数型言語入門

すごく分かり易い。
Haskellについては多少は知ってたけど、これは奥が深い言語だな〜。
P122のHaskellの利点(3)にははっとさせられた。

例えば巨大なツリー構造の全要素にアクセスしたい場合には、flatten関数で全要素を含むリストを作ってしまえばよい。

CとかJavaとかほとんど全ての最内簡約な言語ではこんな処理はコストが大きすぎる。
遅延評価なHaskellだからこそ、こういったコーディングができるということだった。


遅延評価は単に簡約を遅らせるだけみたいに考えてたけど、アルゴリズムそのものに対する考え方にも影響してくるんだなぁ。
ストリームを無限リストとして扱えるという点も素晴らしい。

モナド

Haskellでのモナド則ってのは

1. (return x) >>= f == f x
2. m >>= return     == m
3. (m >>= f) >>= g  == m >>= (\x -> f x >>= g)

の3つで、モナドクラスの要素mに上の3法則を満たすreturnと>>=が定義されていれば良いらしい。

モナド圏論の概念だということだった。圏論集合論の授業でやったけど、モナドは出てこなかった気がする。
そこで、大学の参考書「集合論入門 (基礎数学シリーズ)」をちょっと読んでみた。簡単な本だからモナドについては書かれてなかったけど、雰囲気は掴めた気がする。


型を集合(例えばIntegerは整数の集合)とみなし、型コンストラクタを型の集合と読み替えると圏論と対応していることが良く分かる。
Monadクラスのインスタンスは型コンストラクタなので、例えばそれをMとすれば

M a

型の集合Mの要素aを取り出したことになる。
圏論の言葉で言えば、aはMの対象(object)ということになるのだろう。

return と >>=

m >>= fは雰囲気的にはf(m)の書き換えと思ってしまって良いと思う。
例えばm >>= f >>= gはg(f(m))と思ってしまえば良い。
そうするとモナド則は

1. (return x) >>= f == f x

はf(return(x)) == f(x)を表していて

2. m >>= return   == m

はreturn(m) == mを意味しているので、つまりreturnは何もしない写像(恒等写像)であるということを要請しているだけ。

実際はreturnは要素xを圏の対象の要素に移すという意味合いがあるみたい。

3. (m >>= f) >>= g  == m >>= (\x -> f x >>= g)


g(f(m)) = g\circ f(m)
である事を要請している。

結局なにをしたいのか?

ふつけるに書いてあった「世界」という表現がすごく分かり易い。
例えば「xにfしてその結果にgする」という操作を考えた場合にfやgが副作用を持ってしまっていてはまずい。そこで、xを圏という新しい世界に移して実行をする。

(return x) >>= f >>= g

は「return x」でxを新しい世界(圏)に移す。これで元の世界には何も影響を及ぼさない。次にこの世界の上でf、gを行う。
モナド則1はこの時にxの意味やf xの意味などが変わってしまわないことを保証している。
モナド則2はreturnが新しい世界の中では恒等写像であることを保証している。
モナド則3は多分評価順序の保証。これが圏論の何に対応しているのかはちょっと分からない。


圏論の本今度借りてこよう。