module Control.Functor.Pointed.Composition
( PointedCompF(..)
, PostCompF(..)
, PreCompF(..)
, DistCompF(..)
) where
import Control.Functor.Extras
import Control.Functor.Composition
import Control.Comonad
import Control.Monad
import Control.Functor.Exponential
import Control.Functor.Full
newtype PointedCompF f g a = PointedCompF (CompF f g a) deriving (Functor, ExpFunctor, Full, Composition)
instance (Pointed f, Pointed g) => Pointed (PointedCompF f g) where
point = compose . point . point
instance (Copointed f, Copointed g) => Copointed (PointedCompF f g) where
extract = extract . extract . decompose
newtype PostCompF mw f a = PostCompF (PointedCompF mw f a) deriving (Functor, ExpFunctor, Full, Composition, Pointed, Copointed)
instance (Comonad w, Copointed f, PostUnfold w f) => Comonad (PostCompF w f) where
duplicate = compose . liftW (fmap compose . postUnfold) . duplicate . decompose
newtype PreCompF f mw a = PreCompF (PointedCompF f mw a) deriving (Functor, ExpFunctor, Full, Composition, Pointed, Copointed)
instance (Copointed f, Comonad w, PreUnfold f w) => Comonad (PreCompF f w) where
duplicate = compose . fmap (liftW compose) . preUnfold . fmap (duplicate) . decompose
newtype DistCompF f g a = DistCompF (PointedCompF f g a) deriving (Functor, ExpFunctor, Full, Composition, Pointed, Copointed)
instance (Comonad f, Comonad g, Distributes f g) => Comonad (DistCompF f g) where
duplicate = compose . fmap (fmap compose . dist) . duplicate . fmap duplicate . decompose