{-# LANGUAGE CPP #-}
{-# LANGUAGE MultiParamTypeClasses #-}
#if __GLASGOW_HASKELL__ >= 702 && __GLASGOW_HASKELL__ < 710
{-# LANGUAGE Trustworthy #-}
#endif
-----------------------------------------------------------------------------
-- |
-- 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)
#if __GLASGOW_HASKELL__ < 710
import Control.Applicative
#endif
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 { 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 :: g (f a) -> Adjoint f g a
adjoint = g (Identity (f a)) -> Adjoint f g a
forall (f :: * -> *) (g :: * -> *) (m :: * -> *) a.
g (m (f a)) -> AdjointT f g m a
AdjointT (g (Identity (f a)) -> Adjoint f g a)
-> (g (f a) -> g (Identity (f a))) -> g (f a) -> Adjoint f g a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (f a -> Identity (f a)) -> g (f a) -> g (Identity (f a))
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 :: Adjoint f g a -> g (f a)
runAdjoint = (Identity (f a) -> f a) -> g (Identity (f a)) -> g (f a)
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 :: (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 (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 (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap a -> b
f)) g (m (f a))
g
  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 (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 (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 :: 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 (f :: * -> *) (u :: * -> *) a b.
Adjunction f u =>
(f a -> b) -> a -> u b
leftAdjunct f a -> m (f a)
forall (m :: * -> *) a. Monad m => a -> m a
return
  <*> :: 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 :: a -> AdjointT f g m a
return = a -> AdjointT f g m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure
  AdjointT g (m (f a))
m >>= :: 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 (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (m (f a) -> (f a -> m (f b)) -> m (f 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 (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 :: 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 (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)
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 (f :: * -> *) (u :: * -> *) a.
Adjunction f u =>
a -> u (f a)
unit