コモナド
モナドの圏論的双対
class Functor w => Comonad w where
extract :: w a -> a
duplicate :: w a -> w (w a)
extend :: (w b -> a) -> w b -> w a
duplicate = extend id
extend f = fmap f . duplicate
入門
- コモナドは基点付き空間 - Functorial Blog - Comonads as Spaces
- コモナドはオブジェクト - Haskell for all: Comonads are objects
- コモナドを使った抽象化の威力をライフゲームで試してみた - Qiita
- トーラス上のライフゲームを、List Zipperを使用して実装してみた - Qiita
- コモナドを攻略する - bitterharvest’s diary
- Comonadic builders
代表的なコモナド
Env
Readerモナドの圏論的双対
type Env e a = (e, a)
instance Comonad (Env e) where
extract = snd
extend f w = (fst w, f w)
Traced
Writerモナドの圏論的双対
type Traced e a = e -> a
instance Monoid e => Comonad (Traced e) where
extract m = m mempty
extend f m = \c -> f (\c' -> m (c <> c'))
Store
Stateモナドの圏論的双対
data Store s a = Store (s -> a) s
instance Functor (Store s) where
fmap f (Store g s) = Store (f . g) s
instance Comonad (Store s) where
extract (Store f s) = f s
extend f (Store g s) = Store (f . Store g) s
LensはStoreコモナドの余代数
type Lens s a = a -> Store s a
Stream
無限の長さを持つリストと考えられる
data Stream a = Cons a (Stream a)
instance Functor Stream where
fmap f (Cons x xs) = Cons (f xs) (fmap f xs)
instance Comonad Stream where
extract (Cons x _) = x
duplicate xs@(Cons _ xs') = Cons xs (duplicate xs')
extend f xs@(Cons _ xs') = Cons (f xs) (extend f xs')
普通のリストは空リストが存在するため extract
が実装できないので Comonad
のインスタンスにならないことに注意
List Zipper
data Zipper a = Zipper [a] a [a]
left, right :: Zipper a -> Zipper a
left (Zipper (l:ls) c rs)) = Zipper ls l (c:rs)
right (Zipper ls c (r:rs)) = Zipper (c:ls) r rs
instance Functor Zipper where
fmap f (Zipper ls c rs) = Zipper (fmap f ls) (f c) (fmap f rs)
iterate1 :: (a -> a) -> a -> [a]
iterate1 f = tail . iterate f
instance Comonad Zipper where
extract (Zipper _ c _) = c
duplicate z = Zipper (iterate1 left z) z (iterate1 right z)
extend f z = Z (fmap f $ iterate1 left z) (f z) (fmap f $ iterate1 right z)
コモナドはZipperの一般化
- Structured Computation on Trees or, What’s Behind That Zipper? (A Comonad)
- haskell - Zipper Comonads, Generically - Stack Overflow
Zipper
- zipper
- Zippers - LYAH
- データ型の微分
- Zippers, Part 2: Zippers as Derivatives
- Scrap Your Zippers
- syz
- Zipper関連のパッケージ
- Zipperに挑む
- Derivatives of Containers
- Dan Ghica’s Blog: Zippers for non-inductive types
- [1908.10926] Performance Analysis of Zippers
- Zipperとは - Qiita
- [2110.07902] Zipping Strategies and Attribute Grammars
コモナドトランスフォーマー
class ComonadTrans t where
lower :: Comonad w => t w a -> w a
圏論のコモナド
The comonad is a comonoid in the category of endofunctors.