------------------------------------------------------------------------------- |-- Module : Data.Distributive-- Copyright : (C) 2011 Edward Kmett-- License : BSD-style (see the file LICENSE)---- Maintainer : Edward Kmett <ekmett@gmail.com>-- Stability : provisional-- Portability : portable------------------------------------------------------------------------------moduleData.Distributive(Distributive(..),fmapDefault)whereimportControl.ApplicativeimportControl.ComonadimportControl.Monad.Trans.IdentityimportControl.Monad.Instances()importData.Functor.Identity-- | This is the categorical dual of 'Traversable'-- -- Minimal definition: 'mapW' or 'distribute'---- > mapW = fmap f . duplicate-- > distribute = mapW id-- -- 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.classFunctorg=>Distributivegwhere-- | The dual of 'Data.Traversable.mapM'cotraverse::Comonadw=>(wa->b)->w(ga)->gb-- | The dual of 'Data.Traversable.sequence'distribute::Comonadw=>w(ga)->g(wa)cotraversef=fmapf.distributedistribute=cotraverseidinstanceDistributiveIdentitywherecotraversef=Identity.f.fmaprunIdentitydistribute=Identity.fmaprunIdentityinstanceDistributive((->)e)wheredistributewe=fmap($e)winstanceDistributiveg=>Distributive(IdentityTg)wherecotraversefw=IdentityT$cotraversef(runIdentityT<$>w)distributew=IdentityT$distribute(runIdentityT<$>w)-- | Every 'Distributive' is a 'Functor'. This is a valid default definition.fmapDefault::Distributiveg=>(a->b)->ga->gbfmapDefaultf=cotraverse(f.runIdentity).Identity