    {-# LANGUAGE RankNTypes #-}
    -----------------------------------------------------------------------------
    -- |
    -- 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 x. w x -> v x) -> IdentityT w a -> IdentityT v a
    cohoist l :: 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 #-}