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```

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:

### 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

• Monoid m => Comonad ((->) m)

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 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) }``` ;

Where I can, I have put links to Amazon for books that are relevant to the subject, click on the appropriate country flag to get more details of the book or to buy it from them.

 The Princeton Companion to Mathematics - This is a big book that attempts to give a wide overview of the whole of mathematics, inevitably there are many things missing, but it gives a good insight into the history, concepts, branches, theorems and wider perspective of mathematics. It is well written and, if you are interested in maths, this is the type of book where you can open a page at random and find something interesting to read. To some extent it can be used as a reference book, although it doesn't have tables of formula for trig functions and so on, but where it is most useful is when you want to read about various topics to find out which topics are interesting and relevant to you.