comonad-0.3.0: Haskell 98 comonads

MaintainerEdward Kmett <>




A Comonad is the categorical dual of a Monad.


Functor and Comonad

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, Data.Maybe.Maybe and System.IO.IO satisfy these laws.


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.

class Functor w => Comonad w whereSource

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 andduplicate and the 'default' definition of liftW respectively.


extract :: w a -> aSource

aka coreturn

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

aka cojoin

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

aka cobind



Naming conventions

The functions in this library use the following naming conventions, based on those of Control.Monad.

  • A postfix 'W' always stands for a function in the Cokleisli category: The monad type constructor w is added to function results (modulo currying) and nowhere else. So, for example,
  filter  ::              (a ->   Bool) -> [a] ->   [a]
  filterW :: Comonad w => (w a -> Bool) -> w [a] -> [a]
  • A prefix 'w' generalizes an existing function to a comonadic form. Thus, for example:
  fix  :: (a -> a) -> a
  wfix :: w (w a -> a) -> a

When ambiguous, consistency with existing Control.Monad combinator naming supercedes these rules (e.g. liftW)


(=>=) :: 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 -> (w a -> b) -> w bSource

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

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

extend in operator form

Fixed points and folds

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

Comonadic fixed point

unfoldW :: Comonad w => (w b -> (a, b)) -> w b -> [a]Source

A generalized comonadic list anamorphism

Comonadic lifting

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

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

Comonads with Zipping

class Comonad w => ComonadZip w whereSource

As a symmetric semi-monoidal comonad, an instance of ComonadZip is required to satisfy:

 extract (a <.> b) = extract a (extract b)

Minimal definition: <.>

Based on the ComonadZip from "The Essence of Dataflow Programming" by Tarmo Uustalu and Varmo Vene, but adapted to fit the programming style of Control.Applicative.


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

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

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


(<..>) :: ComonadZip w => w a -> w (a -> b) -> w bSource

A variant of <.> with the arguments reversed.

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

Lift a binary function into a comonad with zipping

liftW3 :: ComonadZip 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 Arrows of a given Comonad




runCokleisli :: w a -> b