-- Hoogle documentation, generated by Haddock
-- See Hoogle, http://www.haskell.org/hoogle/

-- | Distributive functors -- Dual to Traversable
--   
--   Distributive functors -- Dual to Traversable
@package distributive
@version 0.4.4

module Data.Distributive.Generic
class GDistributive g
gdistribute :: (GDistributive g, Functor f) => f (g a) -> g (f a)

-- | distribute derived from a Generic1 type
--   
--   This can be used to easily produce a Distributive instance
--   for a type with a Generic1 instance,
--   
--   
--   data V2 a = V2 a a deriving (Show, Functor, Generic1)
--   instance Distributive V2' where distribute = genericDistribute
--   
genericDistribute :: (Functor f, Generic1 g, GDistributive (Rep1 g)) => f (g a) -> g (f a)
instance Data.Distributive.Generic.GDistributive GHC.Generics.U1
instance (Data.Distributive.Generic.GDistributive a, Data.Distributive.Generic.GDistributive b) => Data.Distributive.Generic.GDistributive (a GHC.Generics.:*: b)
instance (GHC.Base.Functor a, GHC.Base.Functor b, Data.Distributive.Generic.GDistributive a, Data.Distributive.Generic.GDistributive b) => Data.Distributive.Generic.GDistributive (a GHC.Generics.:.: b)
instance Data.Distributive.Generic.GDistributive GHC.Generics.Par1
instance Data.Distributive.Generic.GDistributive f => Data.Distributive.Generic.GDistributive (GHC.Generics.Rec1 f)
instance Data.Distributive.Generic.GDistributive f => Data.Distributive.Generic.GDistributive (GHC.Generics.M1 i c f)

module Data.Distributive

-- | 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 `(-&gt;) 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.
class Functor g => Distributive g where distribute = collect id collect f = distribute . fmap f distributeM = fmap unwrapMonad . distribute . WrapMonad collectM f = distributeM . liftM f

-- | The dual of sequenceA
--   
--   
--   >>> distribute [(+1),(+2)] 1
--   [2,3]
--   
--   
--   
--   distribute = collect id
--   
distribute :: (Distributive g, Functor f) => f (g a) -> g (f a)

-- | 
--   collect f = distribute . fmap f
--   
collect :: (Distributive g, Functor f) => (a -> g b) -> f a -> g (f b)

-- | The dual of sequence
--   
--   
--   distributeM = fmap unwrapMonad . distribute . WrapMonad
--   
distributeM :: (Distributive g, Monad m) => m (g a) -> g (m a)

-- | 
--   collectM = distributeM . liftM f
--   
collectM :: (Distributive g, Monad m) => (a -> g b) -> m a -> g (m b)

-- | The dual of traverse
--   
--   
--   cotraverse f = fmap f . distribute
--   
cotraverse :: (Functor f, Distributive g) => (f a -> b) -> f (g a) -> g b

-- | The dual of mapM
--   
--   
--   comapM f = fmap f . distributeM
--   
comapM :: (Monad m, Distributive g) => (m a -> b) -> m (g a) -> g b
instance Data.Distributive.Distributive Data.Functor.Identity.Identity
instance Data.Distributive.Distributive Data.Proxy.Proxy
instance Data.Distributive.Distributive (Data.Tagged.Tagged t)
instance Data.Distributive.Distributive ((->) e)
instance Data.Distributive.Distributive g => Data.Distributive.Distributive (Control.Monad.Trans.Reader.ReaderT e g)
instance Data.Distributive.Distributive g => Data.Distributive.Distributive (Control.Monad.Trans.Identity.IdentityT g)
instance (Data.Distributive.Distributive f, Data.Distributive.Distributive g) => Data.Distributive.Distributive (Data.Functor.Compose.Compose f g)
instance (Data.Distributive.Distributive f, Data.Distributive.Distributive g) => Data.Distributive.Distributive (Data.Functor.Product.Product f g)
instance Data.Distributive.Distributive f => Data.Distributive.Distributive (Control.Applicative.Backwards.Backwards f)
instance Data.Distributive.Distributive f => Data.Distributive.Distributive (Data.Functor.Reverse.Reverse f)
