## Haskell Code

I category theoretic form from here

class Functor w => Comonad w where (=>>) :: w a -> (w a -> b) -> w b coreturn :: w a -> a cojoin :: w a -> w (w a) x =>> f = fmap f (cojoin x)

#### Here is an instance of a celular automita:

instance Comonad U where cojoin a = U (tail $ iterate left a) a (tail $ iterate right a) coreturn (U _ b _) = b

#### Comonad for list:

A colist can't be empty:

data NonEmptyList a = One a | Many a (NonEmptyList a) map :: (a -> b) -> NonEmptyList a -> NonEmptyList b map f (One x) = One (f x) map f (Many x xs) = Many (f x) (map f xs) (++) :: NonEmptyList a -> NonEmptyList a -> NonEmptyList a One x ++ ys = Many x ys Many x xs ++ ys = Many x (xs ++ ys) tails :: NonEmptyList a -> NonEmptyList (NonEmptyList a) tails l@(One _) = One l tails l@(Many _ xs) = Many l (tails xs)

instance

instance Comonad NonEmptyList where coreturn (One x) = x coreturn (Many x xs) = x cojoin = tails

Or if you prefer haskel format:

Control.Comonad - Haskell Code

### Methods

class Functor w => Comonad w where;

- extract :: w a -> aSource
- duplicate :: w a -> w (w a)Source
- extend :: (w a -> b) -> w a -> w bSource

### Instances

Comonad Identity

- Monoid m => Comonad ((->) m)
- Comonad ((,) e)
- Comonad w => Comonad (IdentityT w)

### Haskell Code (from here)

Monad | Comonad |
---|---|

I can put things in a context | I can extract things from a Context |

If I have a function which "computes values from inputs values which might change depending on the context": W a -> b, then I can use "values in context", W a, to return other "values in context", W b | |

-- the comonad operations

-- the dual of return or unit for monads

extract :: W a -> a

-- the dual of bind or flatMap for monads

cobind :: W a -> b -> W a -> W b

## Scala

Forom scalaz

package scalaz trait Comonad[W[_]] extends Copointed[W] with Cojoin[W] trait ComonadLow { implicit def comonad[W[_]](implicit j: Cojoin[W], p: Copointed[W]): Comonad[W] = new Comonad[W] { def cojoin[A](a: W[A]) = j.cojoin(a) def fmap[A, B](a: W[A], f: A => B) = p.fmap(a, f) def copure[A](a: W[A]) = p.copure(a) } } object Comonad extends ComonadLow { import Cojoin._ import Copointed._ implicit def Tuple2Comonad[A] = comonad[({type λ[α]=(A, α)})#λ](Tuple2Cojoin, Tuple2Copointed) import java.util.Map.Entry implicit def MapEntryComonad[X] = comonad[({type λ[α]=Entry[X, α]})#λ](MapEntryCojoin, MapEntryCopointed) }; |