Komonader
Typeklasser
cokleisli :: w a -> b
class Functor w => Comonad w where
-- bird / co-fish
(=>=) :: (w a -> b) -> (w b -> c) -> (w a -> c)
-- "co-bind"
extend :: (w a -> b) -> w a -> w b
-- co-join
duplicate :: w a -> w (w a)
-- co-return
extract :: w a -> a
kleisli :: a -> m b
class Functor m => Monad m where
-- fish
(>=>) :: (a -> m b) -> (b -> m c) -> (a -> m c)
-- bind
(>>=) :: m a -> (a -> m b) -> m b
join :: m (m a) -> m a
return :: a -> m a
Typeklasser
cokleisli :: w a -> b
class Functor w => Comonad w where
-- bird / co-fish
(=>=) :: (w a -> b) -> (w b -> c) -> (w a -> c)
f =>= g = g . extend f
-- co-bind
extend :: (w a -> b) -> w a -> w b
extend f = fmap f . duplicate
-- co-join
duplicate :: w a -> w (w a)
duplicate = extend id
-- co-return
extract :: w a -> a
kleisli :: a -> m b
class Functor m => Monad m where
-- fish
(>=>) :: (a -> m b) -> (b -> m c) -> (a -> m c)
f >=> g = \a ->
let mb = f a
in mb >>= g
-- bind
(>>=) :: m a -> (a -> m b) -> m b
ma >>= f = join (fmap f ma)
join :: m (m a) -> m a
join mma = mma >>= id
return :: m a -> a
Monade
- Kan putte ting inn, men ikke hente de ut
Komonade
- Kan hente ting ut, men ikke putte noe inn
Begge kan utvides til å tillate inn-/ut-henting, men det er ikke del av (ko)monaden
Product-komonaden:
nesten samme som Reader-monaden
Product er mer "naturlig" enn Reader
Men finnes ingen do-notasjon for komonader
Product er høyreadjunkt til Reader
Vanligvis større konseptuelle forskjeller mellom monader og komonader
Stream
data Stream a = Cons a (Stream a)
instance Functor Stream where
fmap f (Cons a as) = Cons (f a) (fmap f as)
instance Comonad Stream where
extract (Cons a _) = a
duplicate (Cons a as) = Cons (Cons a as) (duplicate as)
Komonaden kategorisk
Snu pilene
\eta :: I \rightarrow T \qquad \varepsilon :: T \rightarrow I \\
\mu :: T^2 \rightarrow T \qquad \delta :: T \rightarrow T^2 \\
Snu pilene - komonoide
\eta :: i \rightarrow m \qquad \varepsilon :: m \rightarrow i \\
\mu :: m \otimes m \rightarrow m \qquad \delta :: m \rightarrow m \otimes m
Komonoide i Set
class Comonoid m where
-- co-mu
split :: m -> (m, m)
split x = (x, x)
-- co-eta
destroy :: m -> ()
destroy _ = ()
Alle objekter i Set er en komonoide
Men:
komonaden er en komonoide i kategorien av endofunktorer
Store / Costate
Fra adjunksjon
L z = z \times s \quad (\text{Product}) \\
R a = s \Rightarrow a \quad (\text{Reader})\\
T = R \circ L: \enskip R (L z) = s \Rightarrow (z \times s) \quad (\text{State}) \\
T = L \circ R: \enskip L (R a) = (s \Rightarrow a) \times s \quad (\text{Store})
\varepsilon :: L \circ R \rightarrow I\\
\varepsilon_a :: ((s \Rightarrow a) \times s) \rightarrow a \\
Extract
data Store s a = Store (s -> a) s
-- Store = Prod . Reader
counit (Prod (Reader f) s) = f s
-- samme som
extract (Store f s) = f s
\eta :: I \rightarrow R \circ L \quad (\text{unit / return})\\
\delta :: L \circ R \rightarrow L \circ R \circ L \circ R \\
\delta = L \circ \eta \circ R \\
Duplicate
unit :: a -> Reader s (Product a s)
unit a = Reader (\s -> Prod (a, s))
-- same as partially applied data constructor:
Store f :: s -> Store f s
-- Remember that in the formulas for delta,
-- L and R stand for identity natural transformations
-- whose components are identity morphisms ???
duplicate (Store f s) = Store (Store f) s
-- L . unit . R
duplicateLR :: Product s (Reader s a) -> Product s (Reader s (Product s (Reader s a)))
duplicateLR (Prod (Reader f, s)) = Prod (fmap unit Reader f, s)
instance Comonad (Store s) where
-- extract :: Store s a -> a
extract (Store f s) = f s
-- duplicate :: Store s a -> Store s (Store s a)
duplicate (Store f s) = Store (Store f) s
You may think of the Reader part of Store as a generalized container of as that are keyed using elements of type s.
komonader
By Simon Mitternacht
komonader
Kapittel 23 i Category Theory for Programmers
- 370