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


-- | Distributive functors -- Dual to <tt>Traversable</tt>
@package distributive
@version 0.6.2.1


module Data.Distributive

-- | This is the categorical dual of <a>Traversable</a>.
--   
--   Due to the lack of non-trivial comonoids in Haskell, we can restrict
--   ourselves to requiring a <a>Functor</a> rather than some Coapplicative
--   class. Categorically every <a>Distributive</a> functor is actually a
--   right adjoint, and so it must be <tt>Representable</tt> endofunctor
--   and preserve all limits. This is a fancy way of saying it is
--   isomorphic to <tt>(-&gt;) x</tt> 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.
class Functor g => Distributive (g :: Type -> Type)

-- | The dual of <a>sequenceA</a>
--   
--   <pre>
--   &gt;&gt;&gt; distribute [(+1),(+2)] 1
--   [2,3]
--   </pre>
--   
--   <pre>
--   <a>distribute</a> = <a>collect</a> <a>id</a>
--   <a>distribute</a> . <a>distribute</a> = <a>id</a>
--   </pre>
distribute :: (Distributive g, Functor f) => f (g a) -> g (f a)

-- | <pre>
--   <a>collect</a> f = <a>distribute</a> . <a>fmap</a> f
--   <a>fmap</a> f = <a>runIdentity</a> . <a>collect</a> (<a>Identity</a> . f)
--   <a>fmap</a> <a>distribute</a> . <a>collect</a> f = <a>getCompose</a> . <a>collect</a> (<a>Compose</a> . f)
--   </pre>
collect :: (Distributive g, Functor f) => (a -> g b) -> f a -> g (f b)

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

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

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

-- | The dual of <a>mapM</a>
--   
--   <pre>
--   <a>comapM</a> f = <a>fmap</a> f . <a>distributeM</a>
--   </pre>
comapM :: (Distributive g, Monad m) => (m a -> b) -> m (g a) -> g b
instance (Data.Distributive.Distributive a, Data.Distributive.Distributive b) => Data.Distributive.Distributive (a GHC.Internal.Generics.:*: b)
instance (Data.Distributive.Distributive a, Data.Distributive.Distributive b) => Data.Distributive.Distributive (a GHC.Internal.Generics.:.: b)
instance Data.Distributive.Distributive f => Data.Distributive.Distributive (Control.Applicative.Backwards.Backwards f)
instance Data.Distributive.Distributive Data.Complex.Complex
instance (Data.Distributive.Distributive f, Data.Distributive.Distributive g) => Data.Distributive.Distributive (Data.Functor.Compose.Compose f g)
instance Data.Distributive.Distributive GHC.Internal.Data.Semigroup.Internal.Dual
instance Data.Distributive.Distributive ((->) e)
instance Data.Distributive.Distributive Data.Semigroup.First
instance Data.Distributive.Distributive GHC.Internal.Data.Functor.Identity.Identity
instance Data.Distributive.Distributive g => Data.Distributive.Distributive (Control.Monad.Trans.Identity.IdentityT g)
instance Data.Distributive.Distributive Data.Semigroup.Last
instance Data.Distributive.Distributive f => Data.Distributive.Distributive (GHC.Internal.Generics.M1 i c f)
instance Data.Distributive.Distributive Data.Semigroup.Max
instance Data.Distributive.Distributive Data.Semigroup.Min
instance Data.Distributive.Distributive GHC.Internal.Generics.Par1
instance Data.Distributive.Distributive GHC.Internal.Data.Semigroup.Internal.Product
instance (Data.Distributive.Distributive f, Data.Distributive.Distributive g) => Data.Distributive.Distributive (Data.Functor.Product.Product f g)
instance Data.Distributive.Distributive GHC.Internal.Data.Proxy.Proxy
instance Data.Distributive.Distributive g => Data.Distributive.Distributive (Control.Monad.Trans.Reader.ReaderT e g)
instance Data.Distributive.Distributive f => Data.Distributive.Distributive (GHC.Internal.Generics.Rec1 f)
instance Data.Distributive.Distributive f => Data.Distributive.Distributive (Data.Functor.Reverse.Reverse f)
instance Data.Distributive.Distributive GHC.Internal.Data.Semigroup.Internal.Sum
instance forall k (t :: k). Data.Distributive.Distributive (Data.Tagged.Tagged t)
instance Data.Distributive.Distributive GHC.Internal.Generics.U1
instance (Data.Distributive.Distributive m, GHC.Internal.Base.Monad m) => Data.Distributive.Distributive (Control.Applicative.WrappedMonad m)


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

-- | <a>collect</a> derived from a <a>Generic1</a> type
--   
--   This can be used to easily produce a <a>Distributive</a> instance for
--   a type with a <a>Generic1</a> instance,
--   
--   <pre>
--   data V2 a = V2 a a deriving (Show, Functor, Generic1)
--   instance Distributive V2' where collect = genericCollect
--   </pre>
genericCollect :: (Functor f, Generic1 g, GDistributive (Rep1 g)) => (a -> g b) -> f a -> g (f b)

-- | <a>distribute</a> derived from a <a>Generic1</a> type
--   
--   It's often more efficient to use <a>genericCollect</a> instead.
genericDistribute :: (Functor f, Generic1 g, GDistributive (Rep1 g)) => f (g a) -> g (f a)
instance (Data.Distributive.Generic.GDistributive a, Data.Distributive.Generic.GDistributive b) => Data.Distributive.Generic.GDistributive (a GHC.Internal.Generics.:*: b)
instance (Data.Distributive.Distributive a, Data.Distributive.Generic.GDistributive b) => Data.Distributive.Generic.GDistributive (a GHC.Internal.Generics.:.: b)
instance Data.Distributive.Generic.GDistributive f => Data.Distributive.Generic.GDistributive (GHC.Internal.Generics.M1 i c f)
instance Data.Distributive.Generic.GDistributive GHC.Internal.Generics.Par1
instance Data.Distributive.Distributive f => Data.Distributive.Generic.GDistributive (GHC.Internal.Generics.Rec1 f)
instance Data.Distributive.Generic.GDistributive GHC.Internal.Generics.U1
