comonad-4.0: Comonads

Portability | portable
Stability | provisional
Maintainer | Edward Kmett <ekmett@gmail.com>
Safe Haskell | Trustworthy

Control.Comonad

Contents

- Comonads
- Combining Comonads
- Cokleisli Arrows
- Functors

Description

Synopsis

- class Functor w => Comonad w where
  - extract :: w a -> a
  - duplicate :: w a -> w (w a)
  - extend :: (w a -> b) -> w a -> w b
- liftW :: Comonad w => (a -> b) -> w a -> w b
- wfix :: Comonad w => w (w a -> a) -> a
- cfix :: Comonad w => (w a -> a) -> w a
- (=>=) :: Comonad w => (w a -> b) -> (w b -> c) -> w a -> c
- (=<=) :: Comonad w => (w b -> c) -> (w a -> b) -> w a -> c
- (<<=) :: Comonad w => (w a -> b) -> w a -> w b
- (=>>) :: Comonad w => w a -> (w a -> b) -> w b
- class Comonad w => ComonadApply w where
  - (<@>) :: w (a -> b) -> w a -> w b
  - (@>) :: w a -> w b -> w b
  - (<@) :: w a -> w b -> w a
- (<@@>) :: ComonadApply w => w a -> w (a -> b) -> w b
- liftW2 :: ComonadApply w => (a -> b -> c) -> w a -> w b -> w c
- liftW3 :: ComonadApply w => (a -> b -> c -> d) -> w a -> w b -> w c -> w d
- newtype Cokleisli w a b = Cokleisli {
  - runCokleisli :: w a -> b
  }
- class Functor f where
  - fmap :: (a -> b) -> f a -> f b
  - (<$) :: a -> f b -> f a
- (<$>) :: Functor f => (a -> b) -> f a -> f b
- ($>) :: Functor f => f a -> b -> f b

# Comonads

class Functor w => Comonad w where Source

There are two ways to define a comonad:

I. Provide definitions for `extract` and `extend` satisfying these laws:

     extend extract      = id
     extract . extend f  = f
     extend f . extend g = extend (f . extend g)

In this case, you may simply set `fmap` = `liftW`.

These laws are directly analogous to the laws for monads and perhaps can be made clearer by viewing them as laws stating that Cokleisli composition must be associative, and has extract for a unit:

     f =>= extract   = f
     extract =>= f   = f
     (f =>= g) =>= h = f =>= (g =>= h)

II. Alternately, you may choose to provide definitions for `fmap`, `extract`, and `duplicate` satisfying these laws:

     extract . duplicate      = id
     fmap extract . duplicate = id
     duplicate . duplicate    = fmap duplicate . duplicate

In this case you may not rely on the ability to define `fmap` in terms of `liftW`.

You may of course, choose to define both `duplicate` and `extend`. In that case you must also satisfy these laws:

     extend f  = fmap f . duplicate
     duplicate = extend id
     fmap f    = extend (f . extract)

These are the default definitions of `extend` and `duplicate` and the definition of `liftW` respectively.

Methods

extract :: w a -> aSource

     extract . fmap f = f . extract

duplicate :: w a -> w (w a)Source

     duplicate = extend id
     fmap (fmap f) . duplicate = duplicate . fmap f

extend :: (w a -> b) -> w a -> w bSource

     extend f = fmap f . duplicate

Instances

Comonad Tree |
Comonad Identity |
Comonad NonEmpty |
Monoid m => Comonad ((->) m) |
Comonad ((,) e) |
Comonad w => Comonad (IdentityT w) |
Comonad (Tagged * s) |
Comonad w => Comonad (EnvT e w) |
Comonad w => Comonad (StoreT s w) |
(Comonad w, Monoid m) => Comonad (TracedT m w) |
(Comonad f, Comonad g) => Comonad (Coproduct f g) |

liftW :: Comonad w => (a -> b) -> w a -> w bSource

A suitable default definition for `fmap` for a `Comonad`. Promotes a function to a comonad.

     fmap f = liftW f = extend (f . extract)

wfix :: Comonad w => w (w a -> a) -> aSource

Comonadic fixed point à la Menendez

cfix :: Comonad w => (w a -> a) -> w aSource

Comonadic fixed point à la Orchard

(=>=) :: Comonad w => (w a -> b) -> (w b -> c) -> w a -> cSource

Left-to-right Cokleisli composition

(=<=) :: Comonad w => (w b -> c) -> (w a -> b) -> w a -> cSource

Right-to-left Cokleisli composition

(<<=) :: Comonad w => (w a -> b) -> w a -> w bSource

`extend` in operator form

(=>>) :: Comonad w => w a -> (w a -> b) -> w bSource

`extend` with the arguments swapped. Dual to `>>=` for a `Monad`.

# Combining Comonads

class Comonad w => ComonadApply w where Source

`ComonadApply` is to `Comonad` like `Applicative` is to `Monad`.

Mathematically, it is a strong lax symmetric semi-monoidal comonad on the category `Hask` of Haskell types. That it to say that `w` is a strong lax symmetric semi-monoidal functor on Hask, where both extract and duplicate are symmetric monoidal natural transformations.

Laws:

     (.) <$> u <@> v <@> w = u <@> (v <@> w)
     extract (p <@> q) = extract p (extract q)
     duplicate (p <@> q) = (<@>) <$> duplicate p <@> duplicate q

If our type is both a ComonadApply and Applicative we further require

     (<*>) = (<@>)

Finally, if you choose to define (`<@`) and (`@>`), the results of your definitions should match the following laws:

     a @> b = const id <$> a <@> b
     a <@ b = const <$> a <@> b

Methods

(<@>) :: w (a -> b) -> w a -> w bSource

(@>) :: w a -> w b -> w bSource

(<@) :: w a -> w b -> w aSource

Instances

ComonadApply Tree |
ComonadApply Identity |
ComonadApply NonEmpty |
Monoid m => ComonadApply ((->) m) |
Semigroup m => ComonadApply ((,) m) |
ComonadApply w => ComonadApply (IdentityT w) |
(Semigroup e, ComonadApply w) => ComonadApply (EnvT e w) |
(ComonadApply w, Semigroup s) => ComonadApply (StoreT s w) |
(ComonadApply w, Monoid m) => ComonadApply (TracedT m w) |

(<@@>) :: ComonadApply w => w a -> w (a -> b) -> w bSource

A variant of `<@>` with the arguments reversed.

liftW2 :: ComonadApply w => (a -> b -> c) -> w a -> w b -> w cSource

Lift a binary function into a comonad with zipping

liftW3 :: ComonadApply w => (a -> b -> c -> d) -> w a -> w b -> w c -> w dSource

Lift a ternary function into a comonad with zipping

# Cokleisli Arrows

newtype Cokleisli w a b Source

The `Cokleisli` `Arrow`s of a given `Comonad`

Constructors

Cokleisli |

Fields

runCokleisli :: w a -> b

Instances

Typeable1 w => Typeable2 (Cokleisli w) |
Comonad w => Arrow (Cokleisli w) |
Comonad w => ArrowChoice (Cokleisli w) |
Comonad w => ArrowApply (Cokleisli w) |
ComonadApply w => ArrowLoop (Cokleisli w) |
Comonad w => Category (Cokleisli w) |
Monad (Cokleisli w a) |
Functor (Cokleisli w a) |
Applicative (Cokleisli w a) |

# Functors

class Functor f where

The `Functor` class is used for types that can be mapped over. Instances of `Functor` should satisfy the following laws:

     fmap id  ==  id
     fmap (f . g)  ==  fmap f . fmap g

The instances of `Functor` for lists, `Maybe` and `IO` satisfy these laws.

Methods

fmap :: (a -> b) -> f a -> f b

(<$) :: a -> f b -> f a

Replace all locations in the input with the same value. The default definition is ``fmap` . `const``, but this may be overridden with a more efficient version.

Instances

Functor [] |
Functor IO |
Functor Id |
Functor ZipList |
Functor ReadPrec |
Functor ReadP |
Functor Maybe |
Functor Tree |
Functor Identity |
Functor Option |
Functor NonEmpty |
Functor ((->) r) |
Functor (Either a) |
Functor ((,) a) |
Ix i => Functor (Array i) |
Functor (StateL s) |
Functor (StateR s) |
Functor (Const m) |
Monad m => Functor (WrappedMonad m) |
Arrow a => Functor (ArrowMonad a) |
Functor m => Functor (IdentityT m) |
Arrow a => Functor (WrappedArrow a b) |
Functor (Tagged k s) |
(Functor f, Functor g) => Functor (Compose f g) |
Functor (Cokleisli w a) |
Functor w => Functor (EnvT e w) |
Functor w => Functor (StoreT s w) |
Functor w => Functor (TracedT m w) |
(Functor f, Functor g) => Functor (Coproduct f g) |

(<$>) :: Functor f => (a -> b) -> f a -> f b

An infix synonym for `fmap`.

($>) :: Functor f => f a -> b -> f bSource

Replace the contents of a functor uniformly with a constant value.