{-# LANGUAGE RankNTypes, TypeOperators, DefaultSignatures #-} -- | Compare to indexed.Control.Comonad.Indexed (IxComonad) module MHask.Indexed.Comonad where import MHask.Arrow import qualified MHask.Indexed.Functor as MHask import qualified MHask.Indexed.Copointed as MHask -- | Indexed version of "MHask.Comonad". -- Dual of "MHask.Indexed.Monad" class (MHask.IxCopointed t) => IxComonad t where iduplicate :: (Monad m) => t i j (t j k m) <~ t i k m default iduplicate :: (Monad m, Monad (t j k m)) => t i j (t j k m) <~ t i k m iduplicate = iextend id iextend :: (Monad m, Monad n) => (m <~ t j k n) -> (t i j m <~ t i k n) default iextend :: (Monad m, Monad n, Monad (t i j m), Monad (t j k n), Monad (t i k n), Monad (t i j (t j k n))) => (m <~ t j k n) -> (t i j m <~ t i k n) iextend f = MHask.imap f ~<~ iduplicate -- | If you define your IxComonad in terms of iextend and iextract, -- then you get a free implementation of imap which can -- be used for IxFunctor. imapComonad :: (Monad m, Monad n, Monad (t j j n), IxComonad t) => (m <~ n) -> (t i j m <~ t i j n) imapComonad f = iextend (f ~<~ MHask.iextract)