distributive-0.6.2.1: Distributive functors -- Dual to Traversable

Data.Distributive

Description

Synopsis

# 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 is isomorphic to (->) x for some x.

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

Methods

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

The dual of sequenceA

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

distribute = collect id
distribute . distribute = id


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

collect f = distribute . fmap f
fmap f = runIdentity . collect (Identity . f)
fmap distribute . collect f = getCompose . collect (Compose . 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

Instances details

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

The dual of traverse

cotraverse f = fmap f . distribute


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

The dual of mapM

comapM f = fmap f . distributeM