モナドも、コモナドも、あるんだよ(後篇)
前篇のつづき、コモナドを話す前にまずDualityについて復習しよう:
圏論にて、ある物の双対(Dual)を次のように定義する:
この定義はつまり確定的に明らかであること:矢印をひっくり返すだけ簡単な仕事です。
ある構造xxxに対して、中の要素をすべてdualをかけ、得た新し構造を圏論の言葉で言うとco-xxxである。
???「これから毎日「コ」を付けろうぜ?」
(◕‿‿◕)「…わけがわからないよ」
まぁということで、モナドの定義をすべて対を取ればコモナドになるわけだ。
co-Kleisli category、は下記要素で構成される:
のobject のmorphism と は:
下記法則を従う:
コモナド(comonad)とはtriple()のこと。
GHCのコモナドはhackageDBから配布されてる。定義を見てみよう:
class Functor w => Extend w where duplicate :: w a -> w (w a) class Extend w => Comonad w where extract :: w a -> a (=>=) :: Extend w => (w a -> b) -> (w b -> c) -> w a -> c
つまり:
duplicate <=>
extract <=>
(=>=) <=>
Haskellのコモナドは下記の法則を従わなければならない:
-- 1 f =>= extract = f extract =>= f = f (f =>= g) =>= h = f =>= (g =>= h) -- あるいは -- 2 extract . duplicate = id fmap extract . duplicate = id duplicate . duplicate = fmap duplicate . duplicate
1と2は同じなのは前篇で証明出来たので、略する。