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
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
Begge kan utvides til å tillate inn-/ut-henting, men det er ikke del av (ko)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
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)
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
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
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.