リストがモナドであることを確かめてみた。
きっかけは、モナドの定義とか - 檜山正幸のキマイラ飼育記 (はてなBlog)あたりが分かったような分からないようなもやもやした気分になったから。
わからないのは一方的にこっちの勉強が足りないからなので、考えてみることにした。
とりあえず、リストは本当にモナドか?というところをやってみた。
まず、手持ちの圏論の本のモナドの定義を眺めてみたが、エントリにあったKleisli tripleと結びつかなかった。
ということで、リストが(圏論の本の定義の)モナドかどうか自分で確かめることにした。
リストはモナド
結論だけ。
リストの圏は以下のように決めればよい。イメージしやすさのため、Double(実数)のリストとする。
対象:
ここで, Double(実数の集合), のリストの集合, のリストの集合(==実数のリストのリストの集合), のリストの集合, *1
射:以下のようなもの。例で説明する。値の表現はyaml風。
flatten(concat, join)系
flatten :: D3 -> D2, [[[1,2,3],[4,5]],[[6,7]]] -> [[1,2,3],[4,5],[6,7]] 1 2 3 4 1 2 3 [<=入れ子の深さ] - - - - - - 1 - 1 - 2 - 2 - 3 flatten(concat) - 3 - =================> - - 4 - 4 - 5 - 5 - - - - 6 - 6 - 7 - 7
要するに、第2列の「-」を縦に消していくのがflatten。
また、第3列を消すのはmap.flattenと書ける。第4列があれば、map.map.flatten。
以上のようにして、各Diについて定義できるだけの(map^n).flattenを定義しておく。
singleton(return)系
singleton :: D3 -> D4, [[[1,2,3],[4,5]],[[6,7]]] -> [[[[1,2,3],[4,5]],[[6,7]]]] 1 2 3 4 1 2 3 4 5 [<=ネストの深さ] - - - - - - - - 1 - 1 - 2 - 2 - 3 singleton(return) - 3 - ===================> - - 4 - 4 - 5 - 5 - - - - - 6 - 6 - 7 - 7
要するに、第1列のさらに左に「-」を入れるのがsingleton。
第1列と第2列の間に-を入れるのはmap.singletonと書ける。
map.singleton :: D3 -> D4, [[[1,2,3],[4,5]],[[6,7]]] -> [[[[1,2,3],[4,5]]],[[[6,7]]]] 1 2 3 4 123 4 5 [<=ネストの深さ] - - (ここ) - - - - - - 1 - 1 - 2 - 2 - 3 singleton(return) - 3 - ===================> - - 4 - 4 - 5 - 5 (ここ) - - - - - - 6 - 6 - 7 - 7
同様に、2列と3列の間に入れるのはmap.map.singleton,...とつづく。
以上のようにして、各Diについて定義できるだけの(map^n).singletonを定義しておく。
圏の射は、上のようにして作ったflatten系の関数と、singleton系の関数(と、恒等写像)とする。
これで、圏の設定ができた。
モナドであること
このリストの圏にはモナド構造を入れることができる。
モナドは自己関手、自然変換、自然変換の組[tex:
は自己関手なので、。
自然変換は、 (は恒等関手)。
自然変換は、。
満たすべき性質は、図式を使うので省略。http://www.ipsj.or.jp/07editj/promenade/4703.pdfの定義5を参照。
リストの圏に対しては、をHaskellのmapとすればよい。
は自然変換なので、対象から射への写像となり、それぞれ、
=
=
とすればよい。これでモナドの定義を満たしている。
確認はめんどくさいだけで、コツコツやれば比較的簡単にできる。
これで、リストの圏でがモナドになっていることがわかった。
めでたい。
と思ったが、やっぱりHaskellのモナド則には見えてこない。
色々探して、Haskellのモナド則に対応する圏論の概念は、Kleisli tripleというものらしい。
http://www.ipsj.or.jp/07editj/promenade/4703.pdfなどによると、Kleisli tripleからモナドを構成することができるらしい。
Listがモナドだと分かったから、モナド→Kleisli tripleの構成ができればいいはずだけど、モナドからKleisli tripleの構成がわからなかった。
ので、やってみる。
モナド→Kleisli triple
話を一般化して、Listに限らないモナドからKleisli tripleを構成する。
Kleisli tripleの定義
http://www.ipsj.or.jp/07editj/promenade/4703.pdfから引用。文脈に合わせてちょっと改変。
圏上の関手, 自然変換, 射 に対し、が以下の性質を満たすとき、[tex:
]をKlisli triple という。
(1) ?
(定義)
(d)
OK!
(2) ?
(定義)
(b)
(d)
OK!
(3) ?
左辺を変形して右辺にする。
まず両辺を、の定義で書き直す。
左辺
右辺
左辺を変形していく
左辺
(a)
(c)
(関手のくくりだし)
= 右辺
OK!