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.

Made with Slides.com