{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE Safe #-}
-----------------------------------------------------------------------------
-- |
-- Module      :  Control.Comonad.Hoist.Class
-- Copyright   :  (C) 2008-2013 Edward Kmett
-- License     :  BSD-style (see the file LICENSE)
--
-- Maintainer  :  Edward Kmett <ekmett@gmail.com>
-- Stability   :  provisional
-- Portability :  portable
----------------------------------------------------------------------------
module Control.Comonad.Hoist.Class
  ( ComonadHoist(cohoist)
  ) where

import Control.Comonad
import Control.Monad.Trans.Identity

class ComonadHoist t where
  -- | Given any comonad-homomorphism from @w@ to @v@ this yields a comonad
  -- homomorphism from @t w@ to @t v@.
  cohoist :: (Comonad w, Comonad v) => (forall x. w x -> v x) -> t w a -> t v a

instance ComonadHoist IdentityT where
  cohoist :: forall (w :: * -> *) (v :: * -> *) a.
(Comonad w, Comonad v) =>
(forall x. w x -> v x) -> IdentityT w a -> IdentityT v a
cohoist forall x. w x -> v x
l = v a -> IdentityT v a
forall {k} (f :: k -> *) (a :: k). f a -> IdentityT f a
IdentityT (v a -> IdentityT v a)
-> (IdentityT w a -> v a) -> IdentityT w a -> IdentityT v a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. w a -> v a
forall x. w x -> v x
l (w a -> v a) -> (IdentityT w a -> w a) -> IdentityT w a -> v a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. IdentityT w a -> w a
forall {k} (f :: k -> *) (a :: k). IdentityT f a -> f a
runIdentityT
  {-# INLINE cohoist #-}