module Control.Comonad.Composition where
import Control.Comonad
import Control.Functor.Composition
import Control.Functor.Composition.Class
import Control.Functor.Extras
import Control.Functor.Pointed
import Control.Functor.Pointed.Composition
instance (Comonad w, Copointed f, PostUnfold w f) => Comonad (PostCompF w f) where
extract = copoint . extract . decompose
duplicate = compose . liftW (fmap compose . postUnfold) . duplicate . decompose
instance (Copointed f, Comonad w, PreUnfold f w) => Comonad (PreCompF f w) where
extract = extract . copoint . decompose
duplicate = compose . fmap (liftW compose) . preUnfold . fmap (duplicate) . decompose
instance (Comonad f, Comonad g, Distributes f g) => Comonad (DistCompF f g) where
extract = extract . extract . decompose
duplicate = compose . fmap (fmap compose . dist) . duplicate . fmap duplicate . decompose