distributive-0.4.4: Distributive functors -- Dual to Traversable

Copyright | (C) 2011-2014 Edward Kmett
License | BSD-style (see the file LICENSE)
Maintainer | Edward Kmett <ekmett@gmail.com>
Stability | provisional
Portability | portable
Safe Haskell | Safe
Language | Haskell98

Data.Distributive

Description

Synopsis

- class Functor g => Distributive g where
  - distribute :: Functor f => f (g a) -> g (f a)
  - collect :: Functor f => (a -> g b) -> f a -> g (f b)
  - distributeM :: Monad m => m (g a) -> g (m a)
  - collectM :: Monad m => (a -> g b) -> m a -> g (m b)
- cotraverse :: (Functor f, Distributive g) => (f a -> b) -> f (g a) -> g b
- comapM :: (Monad m, Distributive g) => (m a -> b) -> m (g a) -> g b

# Documentation

class Functor g => Distributive g where Source

This is the categorical dual of `Traversable`.

Due to the lack of non-trivial comonoids in Haskell, we can restrict ourselves to requiring a `Functor` rather than some Coapplicative class. Categorically every `Distributive` functor is actually a right adjoint, and so it must be `Representable` endofunctor and preserve all limits. This is a fancy way of saying it isomorphic to `(->) x` for some x.

Minimal complete definition: `distribute` or `collect`

To be distributable a container will need to have a way to consistently zip a potentially infinite number of copies of itself. This effectively means that the holes in all values of that type, must have the same cardinality, fixed sized vectors, infinite streams, functions, etc. and no extra information to try to merge together.

Minimal complete definition

Nothing

Methods

distribute :: Functor f => f (g a) -> g (f a) Source

The dual of `sequenceA`

    >>> distribute [(+1),(+2)] 1
    [2,3]

    distribute = collect id

collect :: Functor f => (a -> g b) -> f a -> g (f b) Source

    collect f = distribute . fmap f

distributeM :: Monad m => m (g a) -> g (m a) Source

The dual of `sequence`

    distributeM = fmap unwrapMonad . distribute . WrapMonad

collectM :: Monad m => (a -> g b) -> m a -> g (m b) Source

    collectM = distributeM . liftM f

Instances

Distributive Identity Source |
Distributive ((->) e) Source |
Distributive (Proxy *) Source |
Distributive f => Distributive (Reverse f) Source |
Distributive f => Distributive (Backwards f) Source |
Distributive g => Distributive (IdentityT g) Source |
Distributive (Tagged * t) Source |
(Distributive f, Distributive g) => Distributive (Product f g) Source |
(Distributive f, Distributive g) => Distributive (Compose f g) Source |
Distributive g => Distributive (ReaderT e g) Source |

cotraverse :: (Functor f, Distributive g) => (f a -> b) -> f (g a) -> g b Source

The dual of `traverse`

    cotraverse f = fmap f . distribute

comapM :: (Monad m, Distributive g) => (m a -> b) -> m (g a) -> g b Source

The dual of `mapM`

    comapM f = fmap f . distributeM