Learn You a Comonad for Greater Good

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
infixl 5 =>>

class Copointed w where
   extract :: w a -> a

class (Copointed w, Functor w) => Comonad w where
  duplicate :: w a -> w (w a)
  extend :: w a -> (w a -> b) -> w b
  (=>>) :: w a -> (w a -> b) -> w b
  w =>> f = extend w f
  extend w f = fmap f (duplicate w)

instance Copointed [] where
  extract = head

instance Comonad [] where
  duplicate [] = []
  duplicate list@(h : t) = list : duplicate t

-- That was easy!