distributive-0.3: Haskell 98 Distributive functors -- Dual to Traversable

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

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`. However, there appears to be little benefit to allow the distribution via an arbitrary comonad so we restrict ourselves to `Functor`.

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.

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 = 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 |
Distributive ((->) e) |
Distributive f => Distributive (Reverse f) |
Distributive f => Distributive (Backwards f) |
Distributive g => Distributive (IdentityT g) |
Distributive g => Distributive (ReaderT e g) |
(Distributive f, Distributive g) => Distributive (Compose f g) |
(Distributive f, Distributive g) => Distributive (Product f g) |

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

The dual of `traverse`

    cotraverse f = fmap f . distribute

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

The dual of `mapM`

    comapM f = fmap f . distributeM