# day-comonid: The(?) dual of Applicative
This package provides a type class named `Comonoid`.
```haskell
class Comonad f => Comonoid f where
coapply :: f a -> Day f f a
```
The name "Comonoid" should be read in a context. A functor `f` being `Comonoid` means it's a comonoid in the category of `Functor`s
equipped with [Day](https://hackage.haskell.org/package/kan-extensions-5.2.5/docs/Data-Functor-Day.html) as its tensor product.
`Comonoid` can be contrasted with `Applicative`, which is equivalent to a type class for monoids in the said category of `Functor`s.
```haskell
class Functor f => Applicative f where
pure :: a -> f a
(<*>) :: f (a -> b) -> f a -> f b
-- A hypothetical type class equivalent to Applicative
class Functor f => DayMonoid f where
pure' :: Identity a -> f a
default pure' :: Applicative f => Identity a -> f a
pure' = pure . runIdentity
ap' :: Day f f a -> f a
default ap' :: Applicative f => Day f f a -> f a
ap' = dap
```
`Comonoid` is related to [Comonad](https://hackage.haskell.org/package/comonad-5.0.8/docs/Control-Comonad.html),
just like `Applicative` is related to `Monad`.
`Applicative` is a superclass of `Monad` *just because*
any `Monad f` instance is sufficient to implement `Applicative f` in a certain way.
Similarly, `Comonad` is a superclass of `Comonoid`,
*just because* having `(extract :: f a -> a)` and `coapply` is sufficient to make `f` a `Comonad`.
| `Applicative` | `=>` | `Monad` |
|----|----|----|
| `a -> f a` | | `a -> f a` |
| `Day f f a -> f a` | | `f (f a) -> f a` |
| `Comonoid` | `<=` | `Comonad` |
|----|----|----|
| `f a -> a` | | `f a -> a` |
| `f a -> Day f f a` | | `f a -> f (f a)` |
Both of these relations are rooted in the same fact that the following conversion is possible for any `Functor f` and `Functor g`:
```haskell
dayToCompose :: (Functor f, Functor g) => Day f g a -> f (g a)
dayToCompose (Day fb fc op) = fmap (\b -> fmap (op b) fc) fb
```