    {-# LANGUAGE MultiParamTypeClasses #-}
    -----------------------------------------------------------------------------
    -- |
    -- Copyright   :  (C) 2011-2013 Edward Kmett
    -- License     :  BSD-style (see the file LICENSE)
    --
    -- Maintainer  :  Edward Kmett <ekmett@gmail.com>
    -- Stability   :  provisional
    -- Portability :  MPTCs, fundeps
    --
    ----------------------------------------------------------------------------

    module Control.Monad.Trans.Adjoint
      ( Adjoint
      , runAdjoint
      , adjoint
      , AdjointT(..)
      ) where

    import Prelude hiding (sequence)
    import Control.Monad (ap, liftM)
    import Control.Monad.Trans.Class
    import Data.Traversable
    import Data.Functor.Adjunction
    import Data.Functor.Identity

    type Adjoint f g = AdjointT f g Identity

    newtype AdjointT f g m a = AdjointT { forall (f :: * -> *) (g :: * -> *) (m :: * -> *) a.
    AdjointT f g m a -> g (m (f a))
    runAdjointT :: g (m (f a)) }

    adjoint :: Functor g => g (f a) -> Adjoint f g a
    adjoint :: forall (g :: * -> *) (f :: * -> *) a.
    Functor g =>
    g (f a) -> Adjoint f g a
    adjoint = g (Identity (f a)) -> AdjointT f g Identity a
    forall (f :: * -> *) (g :: * -> *) (m :: * -> *) a.
    g (m (f a)) -> AdjointT f g m a
    AdjointT (g (Identity (f a)) -> AdjointT f g Identity a)
    -> (g (f a) -> g (Identity (f a)))
    -> g (f a)
    -> AdjointT f g Identity a
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . (f a -> Identity (f a)) -> g (f a) -> g (Identity (f a))
    forall a b. (a -> b) -> g a -> g b
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap f a -> Identity (f a)
    forall a. a -> Identity a
    Identity

    runAdjoint :: Functor g => Adjoint f g a -> g (f a)
    runAdjoint :: forall (g :: * -> *) (f :: * -> *) a.
    Functor g =>
    Adjoint f g a -> g (f a)
    runAdjoint = (Identity (f a) -> f a) -> g (Identity (f a)) -> g (f a)
    forall a b. (a -> b) -> g a -> g b
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap Identity (f a) -> f a
    forall a. Identity a -> a
    runIdentity (g (Identity (f a)) -> g (f a))
    -> (Adjoint f g a -> g (Identity (f a)))
    -> Adjoint f g a
    -> g (f a)
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Adjoint f g a -> g (Identity (f a))
    forall (f :: * -> *) (g :: * -> *) (m :: * -> *) a.
    AdjointT f g m a -> g (m (f a))
    runAdjointT

    instance (Adjunction f g, Monad m) => Functor (AdjointT f g m) where
      fmap :: forall a b. (a -> b) -> AdjointT f g m a -> AdjointT f g m b
    fmap a -> b
    f (AdjointT g (m (f a))
    g) = g (m (f b)) -> AdjointT f g m b
    forall (f :: * -> *) (g :: * -> *) (m :: * -> *) a.
    g (m (f a)) -> AdjointT f g m a
    AdjointT (g (m (f b)) -> AdjointT f g m b)
    -> g (m (f b)) -> AdjointT f g m b
    forall a b. (a -> b) -> a -> b
    $ (m (f a) -> m (f b)) -> g (m (f a)) -> g (m (f b))
    forall a b. (a -> b) -> g a -> g b
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap ((f a -> f b) -> m (f a) -> m (f b)
    forall (m :: * -> *) a1 r. Monad m => (a1 -> r) -> m a1 -> m r
    liftM ((a -> b) -> f a -> f b
    forall a b. (a -> b) -> f a -> f b
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap a -> b
    f)) g (m (f a))
    g
      a
    b <$ :: forall a b. a -> AdjointT f g m b -> AdjointT f g m a
    <$ AdjointT g (m (f b))
    g = g (m (f a)) -> AdjointT f g m a
    forall (f :: * -> *) (g :: * -> *) (m :: * -> *) a.
    g (m (f a)) -> AdjointT f g m a
    AdjointT (g (m (f a)) -> AdjointT f g m a)
    -> g (m (f a)) -> AdjointT f g m a
    forall a b. (a -> b) -> a -> b
    $ (m (f b) -> m (f a)) -> g (m (f b)) -> g (m (f a))
    forall a b. (a -> b) -> g a -> g b
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap ((f b -> f a) -> m (f b) -> m (f a)
    forall (m :: * -> *) a1 r. Monad m => (a1 -> r) -> m a1 -> m r
    liftM (a
    b a -> f b -> f a
    forall a b. a -> f b -> f a
    forall (f :: * -> *) a b. Functor f => a -> f b -> f a
    <$)) g (m (f b))
    g

    instance (Adjunction f g, Monad m) => Applicative (AdjointT f g m) where
      pure :: forall a. a -> AdjointT f g m a
    pure = g (m (f a)) -> AdjointT f g m a
    forall (f :: * -> *) (g :: * -> *) (m :: * -> *) a.
    g (m (f a)) -> AdjointT f g m a
    AdjointT (g (m (f a)) -> AdjointT f g m a)
    -> (a -> g (m (f a))) -> a -> AdjointT f g m a
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . (f a -> m (f a)) -> a -> g (m (f a))
    forall a b. (f a -> b) -> a -> g b
    forall (f :: * -> *) (u :: * -> *) a b.
    Adjunction f u =>
    (f a -> b) -> a -> u b
    leftAdjunct f a -> m (f a)
    forall a. a -> m a
    forall (m :: * -> *) a. Monad m => a -> m a
    return
      <*> :: forall a b.
    AdjointT f g m (a -> b) -> AdjointT f g m a -> AdjointT f g m b
    (<*>) = AdjointT f g m (a -> b) -> AdjointT f g m a -> AdjointT f g m b
    forall (m :: * -> *) a b. Monad m => m (a -> b) -> m a -> m b
    ap

    instance (Adjunction f g, Monad m) => Monad (AdjointT f g m) where
      return :: forall a. a -> AdjointT f g m a
    return = a -> AdjointT f g m a
    forall a. a -> AdjointT f g m a
    forall (f :: * -> *) a. Applicative f => a -> f a
    pure
      AdjointT g (m (f a))
    m >>= :: forall a b.
    AdjointT f g m a -> (a -> AdjointT f g m b) -> AdjointT f g m b
    >>= a -> AdjointT f g m b
    f = g (m (f b)) -> AdjointT f g m b
    forall (f :: * -> *) (g :: * -> *) (m :: * -> *) a.
    g (m (f a)) -> AdjointT f g m a
    AdjointT (g (m (f b)) -> AdjointT f g m b)
    -> g (m (f b)) -> AdjointT f g m b
    forall a b. (a -> b) -> a -> b
    $ (m (f a) -> m (f b)) -> g (m (f a)) -> g (m (f b))
    forall a b. (a -> b) -> g a -> g b
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap (m (f a) -> (f a -> m (f b)) -> m (f b)
    forall a b. m a -> (a -> m b) -> m b
    forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
    >>= (a -> g (m (f b))) -> f a -> m (f b)
    forall a b. (a -> g b) -> f a -> b
    forall (f :: * -> *) (u :: * -> *) a b.
    Adjunction f u =>
    (a -> u b) -> f a -> b
    rightAdjunct (AdjointT f g m b -> g (m (f b))
    forall (f :: * -> *) (g :: * -> *) (m :: * -> *) a.
    AdjointT f g m a -> g (m (f a))
    runAdjointT (AdjointT f g m b -> g (m (f b)))
    -> (a -> AdjointT f g m b) -> a -> g (m (f b))
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . a -> AdjointT f g m b
    f)) g (m (f a))
    m

    -- | Exploiting this instance requires that we have the missing Traversables for Identity, (,)e and IdentityT
    instance (Adjunction f g, Traversable f) => MonadTrans (AdjointT f g) where
      lift :: forall (m :: * -> *) a. Monad m => m a -> AdjointT f g m a
    lift = g (m (f a)) -> AdjointT f g m a
    forall (f :: * -> *) (g :: * -> *) (m :: * -> *) a.
    g (m (f a)) -> AdjointT f g m a
    AdjointT (g (m (f a)) -> AdjointT f g m a)
    -> (m a -> g (m (f a))) -> m a -> AdjointT f g m a
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . (f (m a) -> m (f a)) -> g (f (m a)) -> g (m (f a))
    forall a b. (a -> b) -> g a -> g b
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap f (m a) -> m (f a)
    forall (t :: * -> *) (m :: * -> *) a.
    (Traversable t, Monad m) =>
    t (m a) -> m (t a)
    forall (m :: * -> *) a. Monad m => f (m a) -> m (f a)
    sequence (g (f (m a)) -> g (m (f a)))
    -> (m a -> g (f (m a))) -> m a -> g (m (f a))
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . m a -> g (f (m a))
    forall a. a -> g (f a)
    forall (f :: * -> *) (u :: * -> *) a.
    Adjunction f u =>
    a -> u (f a)
    unit