    {-# LANGUAGE CPP #-}

    -- | The multi-valued version of mtl's Reader / ReaderT
    module Control.Monad.Trans.MultiReader.Strict
      (
      -- * MultiReaderT
        MultiReaderT(..)
      , MultiReaderTNull
      , MultiReader
      -- * MonadMultiReader class
      , MonadMultiReader(..)
      , MonadMultiGet(..)
      -- * run-functions
      , runMultiReaderT
      , runMultiReaderT_
      , runMultiReaderTNil
      , runMultiReaderTNil_
      -- * with-functions (single reader)
      , withMultiReader
      , withMultiReader_
      -- * with-functions (multiple readers)
      , withMultiReaders
      , withMultiReaders_
      -- * without-function (single reader)
      , withoutMultiReader
      -- * inflate-function (run ReaderT in MultiReaderT)
      , inflateReader
      -- * other functions
      , mapMultiReaderT
      , mGetRaw
      , mPutRaw
    ) where

    import Data.HList.HList
    import Data.HList.ContainsType

    import Control.Monad.Trans.MultiReader.Class
    import Control.Monad.Trans.MultiState.Class

    import Control.Monad.State.Strict      ( StateT(..)
                                           , MonadState(..)
                                           , evalStateT
                                           , mapStateT )
    import Control.Monad.Reader            ( ReaderT(..) )
    import Control.Monad.Trans.Class       ( MonadTrans
                                           , lift )
    import Control.Monad.Writer.Class      ( MonadWriter
                                           , listen
                                           , tell
                                           , writer
                                           , pass )

    import Data.Functor.Identity           ( Identity )

    import Control.Applicative             ( Applicative(..)
                                           , Alternative(..)
                                           )
    import Control.Monad                   ( MonadPlus(..)
                                           , liftM
                                           , ap
                                           , void )
    import Control.Monad.Base              ( MonadBase(..)
                                           , liftBaseDefault
                                           )
    import Control.Monad.Trans.Control     ( MonadTransControl(..)
                                           , MonadBaseControl(..)
                                           , ComposeSt
                                           , defaultLiftBaseWith
                                           , defaultRestoreM
                                           )
    import Control.Monad.Fix               ( MonadFix(..) )
    import Control.Monad.IO.Class          ( MonadIO(..) )

    -- | A Reader transformer monad patameterized by:
    --
    -- * x - The list of types constituting the environment / input (to be read),
    -- * m - The inner monad.
    --
    -- 'MultiReaderT' corresponds to mtl's 'ReaderT', but can contain
    -- a heterogenous list of types.
    --
    -- This heterogenous list is represented using Types.Data.List, i.e:
    --
    --   * @'[]@ - The empty list,
    --   * @a ': b@ - A list where @/a/@ is an arbitrary type
    --     and @/b/@ is the rest list.
    --
    -- For example,
    --
    -- > MultiReaderT '[Int, Bool] :: (* -> *) -> (* -> *)
    --
    -- is a Reader transformer containing the types [Int, Bool].
    newtype MultiReaderT x m a = MultiReaderT {
      MultiReaderT x m a -> StateT (HList x) m a
    runMultiReaderTRaw :: StateT (HList x) m a
    }

    -- | A MultiReader transformer carrying an empty state.
    type MultiReaderTNull = MultiReaderT '[]

    -- | A reader monad parameterized by the list of types x of the environment
    -- / input to carry.
    --
    -- Similar to @Reader r = ReaderT r Identity@
    type MultiReader x = MultiReaderT x Identity

    instance (Functor f) => Functor (MultiReaderT x f) where
      fmap :: (a -> b) -> MultiReaderT x f a -> MultiReaderT x f b
    fmap f :: a -> b
    f = StateT (HList x) f b -> MultiReaderT x f b
    forall (x :: [*]) (m :: * -> *) a.
    StateT (HList x) m a -> MultiReaderT x m a
    MultiReaderT (StateT (HList x) f b -> MultiReaderT x f b)
    -> (MultiReaderT x f a -> StateT (HList x) f b)
    -> MultiReaderT x f a
    -> MultiReaderT x f b
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . (a -> b) -> StateT (HList x) f a -> StateT (HList x) f b
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap a -> b
    f (StateT (HList x) f a -> StateT (HList x) f b)
    -> (MultiReaderT x f a -> StateT (HList x) f a)
    -> MultiReaderT x f a
    -> StateT (HList x) f b
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . MultiReaderT x f a -> StateT (HList x) f a
    forall (x :: [*]) (m :: * -> *) a.
    MultiReaderT x m a -> StateT (HList x) m a
    runMultiReaderTRaw

    instance (Applicative m, Monad m) => Applicative (MultiReaderT x m) where
      pure :: a -> MultiReaderT x m a
    pure = StateT (HList x) m a -> MultiReaderT x m a
    forall (x :: [*]) (m :: * -> *) a.
    StateT (HList x) m a -> MultiReaderT x m a
    MultiReaderT (StateT (HList x) m a -> MultiReaderT x m a)
    -> (a -> StateT (HList x) m a) -> a -> MultiReaderT x m a
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . a -> StateT (HList x) m a
    forall (f :: * -> *) a. Applicative f => a -> f a
    pure
      <*> :: MultiReaderT x m (a -> b)
    -> MultiReaderT x m a -> MultiReaderT x m b
    (<*>) = MultiReaderT x m (a -> b)
    -> MultiReaderT x m a -> MultiReaderT x m b
    forall (m :: * -> *) a b. Monad m => m (a -> b) -> m a -> m b
    ap

    instance Monad m => Monad (MultiReaderT x m) where
      return :: a -> MultiReaderT x m a
    return = StateT (HList x) m a -> MultiReaderT x m a
    forall (x :: [*]) (m :: * -> *) a.
    StateT (HList x) m a -> MultiReaderT x m a
    MultiReaderT (StateT (HList x) m a -> MultiReaderT x m a)
    -> (a -> StateT (HList x) m a) -> a -> MultiReaderT x m a
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . a -> StateT (HList x) m a
    forall (m :: * -> *) a. Monad m => a -> m a
    return
      k :: MultiReaderT x m a
    k >>= :: MultiReaderT x m a
    -> (a -> MultiReaderT x m b) -> MultiReaderT x m b
    >>= f :: a -> MultiReaderT x m b
    f = StateT (HList x) m b -> MultiReaderT x m b
    forall (x :: [*]) (m :: * -> *) a.
    StateT (HList x) m a -> MultiReaderT x m a
    MultiReaderT (StateT (HList x) m b -> MultiReaderT x m b)
    -> StateT (HList x) m b -> MultiReaderT x m b
    forall a b. (a -> b) -> a -> b
    $ MultiReaderT x m a -> StateT (HList x) m a
    forall (x :: [*]) (m :: * -> *) a.
    MultiReaderT x m a -> StateT (HList x) m a
    runMultiReaderTRaw MultiReaderT x m a
    k StateT (HList x) m a
    -> (a -> StateT (HList x) m b) -> StateT (HList x) m b
    forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
    >>= (MultiReaderT x m b -> StateT (HList x) m b
    forall (x :: [*]) (m :: * -> *) a.
    MultiReaderT x m a -> StateT (HList x) m a
    runMultiReaderTRaw (MultiReaderT x m b -> StateT (HList x) m b)
    -> (a -> MultiReaderT x m b) -> a -> StateT (HList x) m b
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . a -> MultiReaderT x m b
    f)

    instance MonadTrans (MultiReaderT x) where
      lift :: m a -> MultiReaderT x m a
    lift = StateT (HList x) m a -> MultiReaderT x m a
    forall (x :: [*]) (m :: * -> *) a.
    StateT (HList x) m a -> MultiReaderT x m a
    MultiReaderT (StateT (HList x) m a -> MultiReaderT x m a)
    -> (m a -> StateT (HList x) m a) -> m a -> MultiReaderT x m a
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . m a -> StateT (HList x) m a
    forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
    (MonadTrans t, Monad m) =>
    m a -> t m a
    lift

    #if MIN_VERSION_base(4,8,0)
    instance {-# OVERLAPPING #-} (Monad m, ContainsType a c)
    #else
    instance (Monad m, ContainsType a c)
    #endif
          => MonadMultiReader a (MultiReaderT c m) where
      mAsk :: MultiReaderT c m a
    mAsk = StateT (HList c) m a -> MultiReaderT c m a
    forall (x :: [*]) (m :: * -> *) a.
    StateT (HList x) m a -> MultiReaderT x m a
    MultiReaderT (StateT (HList c) m a -> MultiReaderT c m a)
    -> StateT (HList c) m a -> MultiReaderT c m a
    forall a b. (a -> b) -> a -> b
    $ (HList c -> a)
    -> StateT (HList c) m (HList c) -> StateT (HList c) m a
    forall (m :: * -> *) a1 r. Monad m => (a1 -> r) -> m a1 -> m r
    liftM HList c -> a
    forall a (c :: [*]). ContainsType a c => HList c -> a
    getHListElem StateT (HList c) m (HList c)
    forall s (m :: * -> *). MonadState s m => m s
    get

    #if MIN_VERSION_base(4,8,0)
    instance {-# OVERLAPPING #-} (Monad m, ContainsType a c)
    #else
    instance (Monad m, ContainsType a c)
    #endif
          => MonadMultiGet a (MultiReaderT c m) where
      mGet :: MultiReaderT c m a
    mGet = StateT (HList c) m a -> MultiReaderT c m a
    forall (x :: [*]) (m :: * -> *) a.
    StateT (HList x) m a -> MultiReaderT x m a
    MultiReaderT (StateT (HList c) m a -> MultiReaderT c m a)
    -> StateT (HList c) m a -> MultiReaderT c m a
    forall a b. (a -> b) -> a -> b
    $ (HList c -> a)
    -> StateT (HList c) m (HList c) -> StateT (HList c) m a
    forall (m :: * -> *) a1 r. Monad m => (a1 -> r) -> m a1 -> m r
    liftM HList c -> a
    forall a (c :: [*]). ContainsType a c => HList c -> a
    getHListElem StateT (HList c) m (HList c)
    forall s (m :: * -> *). MonadState s m => m s
    get

    instance MonadFix m => MonadFix (MultiReaderT r m) where
      mfix :: (a -> MultiReaderT r m a) -> MultiReaderT r m a
    mfix f :: a -> MultiReaderT r m a
    f = StateT (HList r) m a -> MultiReaderT r m a
    forall (x :: [*]) (m :: * -> *) a.
    StateT (HList x) m a -> MultiReaderT x m a
    MultiReaderT (StateT (HList r) m a -> MultiReaderT r m a)
    -> StateT (HList r) m a -> MultiReaderT r m a
    forall a b. (a -> b) -> a -> b
    $ (a -> StateT (HList r) m a) -> StateT (HList r) m a
    forall (m :: * -> *) a. MonadFix m => (a -> m a) -> m a
    mfix (MultiReaderT r m a -> StateT (HList r) m a
    forall (x :: [*]) (m :: * -> *) a.
    MultiReaderT x m a -> StateT (HList x) m a
    runMultiReaderTRaw (MultiReaderT r m a -> StateT (HList r) m a)
    -> (a -> MultiReaderT r m a) -> a -> StateT (HList r) m a
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . a -> MultiReaderT r m a
    f)

    -- methods

    -- | A raw extractor of the contained HList (i.e. the complete Reader).
    mGetRaw :: Monad m => MultiReaderT a m (HList a)
    mGetRaw :: MultiReaderT a m (HList a)
    mGetRaw = StateT (HList a) m (HList a) -> MultiReaderT a m (HList a)
    forall (x :: [*]) (m :: * -> *) a.
    StateT (HList x) m a -> MultiReaderT x m a
    MultiReaderT StateT (HList a) m (HList a)
    forall s (m :: * -> *). MonadState s m => m s
    get

    mPutRaw :: Monad m => HList s -> MultiReaderT s m ()
    mPutRaw :: HList s -> MultiReaderT s m ()
    mPutRaw = StateT (HList s) m () -> MultiReaderT s m ()
    forall (x :: [*]) (m :: * -> *) a.
    StateT (HList x) m a -> MultiReaderT x m a
    MultiReaderT (StateT (HList s) m () -> MultiReaderT s m ())
    -> (HList s -> StateT (HList s) m ())
    -> HList s
    -> MultiReaderT s m ()
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . HList s -> StateT (HList s) m ()
    forall s (m :: * -> *). MonadState s m => s -> m ()
    put

    -- | Map both the return value and the environment of a computation
    -- using the given function.
    --
    -- Note that there is a difference to mtl's ReaderT,
    -- where it is /not/ possible to modify the environment.
    mapMultiReaderT :: (m (a, HList w) -> m' (a', HList w))
                   -> MultiReaderT w m  a
                   -> MultiReaderT w m' a'
    mapMultiReaderT :: (m (a, HList w) -> m' (a', HList w))
    -> MultiReaderT w m a -> MultiReaderT w m' a'
    mapMultiReaderT f :: m (a, HList w) -> m' (a', HList w)
    f = StateT (HList w) m' a' -> MultiReaderT w m' a'
    forall (x :: [*]) (m :: * -> *) a.
    StateT (HList x) m a -> MultiReaderT x m a
    MultiReaderT (StateT (HList w) m' a' -> MultiReaderT w m' a')
    -> (MultiReaderT w m a -> StateT (HList w) m' a')
    -> MultiReaderT w m a
    -> MultiReaderT w m' a'
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . (m (a, HList w) -> m' (a', HList w))
    -> StateT (HList w) m a -> StateT (HList w) m' a'
    forall (m :: * -> *) a s (n :: * -> *) b.
    (m (a, s) -> n (b, s)) -> StateT s m a -> StateT s n b
    mapStateT m (a, HList w) -> m' (a', HList w)
    f (StateT (HList w) m a -> StateT (HList w) m' a')
    -> (MultiReaderT w m a -> StateT (HList w) m a)
    -> MultiReaderT w m a
    -> StateT (HList w) m' a'
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . MultiReaderT w m a -> StateT (HList w) m a
    forall (x :: [*]) (m :: * -> *) a.
    MultiReaderT x m a -> StateT (HList x) m a
    runMultiReaderTRaw

    runMultiReaderT   ::   Monad m => HList r -> MultiReaderT r m a -> m a
    runMultiReaderT_  :: Functor m => HList r -> MultiReaderT r m a -> m ()
    -- ghc too dumb for this shortcut, unfortunately
    -- runMultiReaderT   s k = runMultiReaderTNil $ withMultiReaders s k
    -- runMultiReaderT_  s k = runMultiReaderTNil $ withMultiReaders_ s k
    runMultiReaderT :: HList r -> MultiReaderT r m a -> m a
    runMultiReaderT  s :: HList r
    s k :: MultiReaderT r m a
    k = StateT (HList r) m a -> HList r -> m a
    forall (m :: * -> *) s a. Monad m => StateT s m a -> s -> m a
    evalStateT (MultiReaderT r m a -> StateT (HList r) m a
    forall (x :: [*]) (m :: * -> *) a.
    MultiReaderT x m a -> StateT (HList x) m a
    runMultiReaderTRaw MultiReaderT r m a
    k) HList r
    s
    runMultiReaderT_ :: HList r -> MultiReaderT r m a -> m ()
    runMultiReaderT_ s :: HList r
    s k :: MultiReaderT r m a
    k = m (a, HList r) -> m ()
    forall (f :: * -> *) a. Functor f => f a -> f ()
    void (m (a, HList r) -> m ()) -> m (a, HList r) -> m ()
    forall a b. (a -> b) -> a -> b
    $ StateT (HList r) m a -> HList r -> m (a, HList r)
    forall s (m :: * -> *) a. StateT s m a -> s -> m (a, s)
    runStateT (MultiReaderT r m a -> StateT (HList r) m a
    forall (x :: [*]) (m :: * -> *) a.
    MultiReaderT x m a -> StateT (HList x) m a
    runMultiReaderTRaw MultiReaderT r m a
    k) HList r
    s

    runMultiReaderTNil  ::   Monad m => MultiReaderT '[] m a -> m a
    runMultiReaderTNil_ :: Functor m => MultiReaderT '[] m a -> m ()
    runMultiReaderTNil :: MultiReaderT '[] m a -> m a
    runMultiReaderTNil  k :: MultiReaderT '[] m a
    k = StateT (HList '[]) m a -> HList '[] -> m a
    forall (m :: * -> *) s a. Monad m => StateT s m a -> s -> m a
    evalStateT (MultiReaderT '[] m a -> StateT (HList '[]) m a
    forall (x :: [*]) (m :: * -> *) a.
    MultiReaderT x m a -> StateT (HList x) m a
    runMultiReaderTRaw MultiReaderT '[] m a
    k) HList '[]
    HNil
    runMultiReaderTNil_ :: MultiReaderT '[] m a -> m ()
    runMultiReaderTNil_ k :: MultiReaderT '[] m a
    k = m (a, HList '[]) -> m ()
    forall (f :: * -> *) a. Functor f => f a -> f ()
    void (m (a, HList '[]) -> m ()) -> m (a, HList '[]) -> m ()
    forall a b. (a -> b) -> a -> b
    $ StateT (HList '[]) m a -> HList '[] -> m (a, HList '[])
    forall s (m :: * -> *) a. StateT s m a -> s -> m (a, s)
    runStateT (MultiReaderT '[] m a -> StateT (HList '[]) m a
    forall (x :: [*]) (m :: * -> *) a.
    MultiReaderT x m a -> StateT (HList x) m a
    runMultiReaderTRaw MultiReaderT '[] m a
    k) HList '[]
    HNil

    withMultiReader   :: Monad m => r -> MultiReaderT (r ': rs) m a -> MultiReaderT rs m a
    withMultiReader_  :: (Functor m, Monad m) => r -> MultiReaderT (r ': rs) m a -> MultiReaderT rs m ()
    withMultiReader :: r -> MultiReaderT (r : rs) m a -> MultiReaderT rs m a
    withMultiReader  x :: r
    x k :: MultiReaderT (r : rs) m a
    k = StateT (HList rs) m a -> MultiReaderT rs m a
    forall (x :: [*]) (m :: * -> *) a.
    StateT (HList x) m a -> MultiReaderT x m a
    MultiReaderT (StateT (HList rs) m a -> MultiReaderT rs m a)
    -> StateT (HList rs) m a -> MultiReaderT rs m a
    forall a b. (a -> b) -> a -> b
    $
      StateT (HList rs) m (HList rs)
    forall s (m :: * -> *). MonadState s m => m s
    get StateT (HList rs) m (HList rs)
    -> (HList rs -> StateT (HList rs) m a) -> StateT (HList rs) m a
    forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
    >>= m a -> StateT (HList rs) m a
    forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
    (MonadTrans t, Monad m) =>
    m a -> t m a
    lift (m a -> StateT (HList rs) m a)
    -> (HList rs -> m a) -> HList rs -> StateT (HList rs) m a
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . StateT (HList (r : rs)) m a -> HList (r : rs) -> m a
    forall (m :: * -> *) s a. Monad m => StateT s m a -> s -> m a
    evalStateT (MultiReaderT (r : rs) m a -> StateT (HList (r : rs)) m a
    forall (x :: [*]) (m :: * -> *) a.
    MultiReaderT x m a -> StateT (HList x) m a
    runMultiReaderTRaw MultiReaderT (r : rs) m a
    k) (HList (r : rs) -> m a)
    -> (HList rs -> HList (r : rs)) -> HList rs -> m a
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . (r
    x r -> HList rs -> HList (r : rs)
    forall x (xs :: [*]). x -> HList xs -> HList (x : xs)
    :+:)
    withMultiReader_ :: r -> MultiReaderT (r : rs) m a -> MultiReaderT rs m ()
    withMultiReader_ x :: r
    x k :: MultiReaderT (r : rs) m a
    k = MultiReaderT rs m a -> MultiReaderT rs m ()
    forall (f :: * -> *) a. Functor f => f a -> f ()
    void (MultiReaderT rs m a -> MultiReaderT rs m ())
    -> MultiReaderT rs m a -> MultiReaderT rs m ()
    forall a b. (a -> b) -> a -> b
    $ r -> MultiReaderT (r : rs) m a -> MultiReaderT rs m a
    forall (m :: * -> *) r (rs :: [*]) a.
    Monad m =>
    r -> MultiReaderT (r : rs) m a -> MultiReaderT rs m a
    withMultiReader r
    x MultiReaderT (r : rs) m a
    k

    withMultiReaders  :: Monad m => HList r1 -> MultiReaderT (Append r1 r2) m a -> MultiReaderT r2 m a
    withMultiReaders_ :: (Functor m, Monad m) => HList r1 -> MultiReaderT (Append r1 r2) m a -> MultiReaderT r2 m ()
    withMultiReaders :: HList r1 -> MultiReaderT (Append r1 r2) m a -> MultiReaderT r2 m a
    withMultiReaders  HNil       = MultiReaderT (Append r1 r2) m a -> MultiReaderT r2 m a
    forall a. a -> a
    id
    withMultiReaders  (x :: x
    x :+: xs :: HList xs
    xs) = HList xs -> MultiReaderT (Append xs r2) m a -> MultiReaderT r2 m a
    forall (m :: * -> *) (r1 :: [*]) (r2 :: [*]) a.
    Monad m =>
    HList r1 -> MultiReaderT (Append r1 r2) m a -> MultiReaderT r2 m a
    withMultiReaders HList xs
    xs (MultiReaderT (Append xs r2) m a -> MultiReaderT r2 m a)
    -> (MultiReaderT (x : Append xs r2) m a
        -> MultiReaderT (Append xs r2) m a)
    -> MultiReaderT (x : Append xs r2) m a
    -> MultiReaderT r2 m a
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . x
    -> MultiReaderT (x : Append xs r2) m a
    -> MultiReaderT (Append xs r2) m a
    forall (m :: * -> *) r (rs :: [*]) a.
    Monad m =>
    r -> MultiReaderT (r : rs) m a -> MultiReaderT rs m a
    withMultiReader x
    x
    withMultiReaders_ :: HList r1 -> MultiReaderT (Append r1 r2) m a -> MultiReaderT r2 m ()
    withMultiReaders_ HNil       = (a -> ()) -> MultiReaderT r2 m a -> MultiReaderT r2 m ()
    forall (m :: * -> *) a1 r. Monad m => (a1 -> r) -> m a1 -> m r
    liftM (() -> a -> ()
    forall a b. a -> b -> a
    const ())
    withMultiReaders_ (x :: x
    x :+: xs :: HList xs
    xs) = HList xs
    -> MultiReaderT (Append xs r2) m () -> MultiReaderT r2 m ()
    forall (m :: * -> *) (r1 :: [*]) (r2 :: [*]) a.
    (Functor m, Monad m) =>
    HList r1 -> MultiReaderT (Append r1 r2) m a -> MultiReaderT r2 m ()
    withMultiReaders_ HList xs
    xs (MultiReaderT (Append xs r2) m () -> MultiReaderT r2 m ())
    -> (MultiReaderT (x : Append xs r2) m a
        -> MultiReaderT (Append xs r2) m ())
    -> MultiReaderT (x : Append xs r2) m a
    -> MultiReaderT r2 m ()
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . x
    -> MultiReaderT (x : Append xs r2) m a
    -> MultiReaderT (Append xs r2) m ()
    forall (m :: * -> *) r (rs :: [*]) a.
    (Functor m, Monad m) =>
    r -> MultiReaderT (r : rs) m a -> MultiReaderT rs m ()
    withMultiReader_ x
    x

    withoutMultiReader :: Monad m => MultiReaderT rs m a -> MultiReaderT (r ': rs) m a
    withoutMultiReader :: MultiReaderT rs m a -> MultiReaderT (r : rs) m a
    withoutMultiReader k :: MultiReaderT rs m a
    k = StateT (HList (r : rs)) m a -> MultiReaderT (r : rs) m a
    forall (x :: [*]) (m :: * -> *) a.
    StateT (HList x) m a -> MultiReaderT x m a
    MultiReaderT (StateT (HList (r : rs)) m a -> MultiReaderT (r : rs) m a)
    -> StateT (HList (r : rs)) m a -> MultiReaderT (r : rs) m a
    forall a b. (a -> b) -> a -> b
    $ StateT (HList (r : rs)) m (HList (r : rs))
    forall s (m :: * -> *). MonadState s m => m s
    get StateT (HList (r : rs)) m (HList (r : rs))
    -> (HList (r : rs) -> StateT (HList (r : rs)) m a)
    -> StateT (HList (r : rs)) m a
    forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
    >>= \case
      (_ :+: rr :: HList xs
    rr) -> m a -> StateT (HList (r : rs)) m a
    forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
    (MonadTrans t, Monad m) =>
    m a -> t m a
    lift (m a -> StateT (HList (r : rs)) m a)
    -> m a -> StateT (HList (r : rs)) m a
    forall a b. (a -> b) -> a -> b
    $ HList xs -> MultiReaderT xs m a -> m a
    forall (m :: * -> *) (r :: [*]) a.
    Monad m =>
    HList r -> MultiReaderT r m a -> m a
    runMultiReaderT HList xs
    rr MultiReaderT rs m a
    MultiReaderT xs m a
    k

    inflateReader :: (Monad m, ContainsType r rs)
                  => ReaderT r m a
                  -> MultiReaderT rs m a
    inflateReader :: ReaderT r m a -> MultiReaderT rs m a
    inflateReader k :: ReaderT r m a
    k = MultiReaderT rs m r
    forall a (m :: * -> *). MonadMultiReader a m => m a
    mAsk MultiReaderT rs m r
    -> (r -> MultiReaderT rs m a) -> MultiReaderT rs m a
    forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
    >>= m a -> MultiReaderT rs m a
    forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
    (MonadTrans t, Monad m) =>
    m a -> t m a
    lift (m a -> MultiReaderT rs m a)
    -> (r -> m a) -> r -> MultiReaderT rs m a
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . ReaderT r m a -> r -> m a
    forall r (m :: * -> *) a. ReaderT r m a -> r -> m a
    runReaderT ReaderT r m a
    k

    -- foreign lifting instances

    instance (MonadState s m) => MonadState s (MultiReaderT c m) where
      put :: s -> MultiReaderT c m ()
    put   = m () -> MultiReaderT c m ()
    forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
    (MonadTrans t, Monad m) =>
    m a -> t m a
    lift (m () -> MultiReaderT c m ())
    -> (s -> m ()) -> s -> MultiReaderT c m ()
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . s -> m ()
    forall s (m :: * -> *). MonadState s m => s -> m ()
    put
      get :: MultiReaderT c m s
    get   = m s -> MultiReaderT c m s
    forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
    (MonadTrans t, Monad m) =>
    m a -> t m a
    lift (m s -> MultiReaderT c m s) -> m s -> MultiReaderT c m s
    forall a b. (a -> b) -> a -> b
    $ m s
    forall s (m :: * -> *). MonadState s m => m s
    get
      state :: (s -> (a, s)) -> MultiReaderT c m a
    state = m a -> MultiReaderT c m a
    forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
    (MonadTrans t, Monad m) =>
    m a -> t m a
    lift (m a -> MultiReaderT c m a)
    -> ((s -> (a, s)) -> m a) -> (s -> (a, s)) -> MultiReaderT c m a
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . (s -> (a, s)) -> m a
    forall s (m :: * -> *) a. MonadState s m => (s -> (a, s)) -> m a
    state

    instance (MonadWriter w m) => MonadWriter w (MultiReaderT c m) where
      writer :: (a, w) -> MultiReaderT c m a
    writer = m a -> MultiReaderT c m a
    forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
    (MonadTrans t, Monad m) =>
    m a -> t m a
    lift (m a -> MultiReaderT c m a)
    -> ((a, w) -> m a) -> (a, w) -> MultiReaderT c m a
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . (a, w) -> m a
    forall w (m :: * -> *) a. MonadWriter w m => (a, w) -> m a
    writer
      tell :: w -> MultiReaderT c m ()
    tell   = m () -> MultiReaderT c m ()
    forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
    (MonadTrans t, Monad m) =>
    m a -> t m a
    lift (m () -> MultiReaderT c m ())
    -> (w -> m ()) -> w -> MultiReaderT c m ()
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . w -> m ()
    forall w (m :: * -> *). MonadWriter w m => w -> m ()
    tell
      listen :: MultiReaderT c m a -> MultiReaderT c m (a, w)
    listen = StateT (HList c) m (a, w) -> MultiReaderT c m (a, w)
    forall (x :: [*]) (m :: * -> *) a.
    StateT (HList x) m a -> MultiReaderT x m a
    MultiReaderT (StateT (HList c) m (a, w) -> MultiReaderT c m (a, w))
    -> (MultiReaderT c m a -> StateT (HList c) m (a, w))
    -> MultiReaderT c m a
    -> MultiReaderT c m (a, w)
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    .
        (m (a, HList c) -> m ((a, w), HList c))
    -> StateT (HList c) m a -> StateT (HList c) m (a, w)
    forall (m :: * -> *) a s (n :: * -> *) b.
    (m (a, s) -> n (b, s)) -> StateT s m a -> StateT s n b
    mapStateT ((((a, HList c), w) -> ((a, w), HList c))
    -> m ((a, HList c), w) -> m ((a, w), HList c)
    forall (m :: * -> *) a1 r. Monad m => (a1 -> r) -> m a1 -> m r
    liftM (\((a :: a
    a,w :: HList c
    w), w' :: w
    w') -> ((a
    a, w
    w'), HList c
    w)) (m ((a, HList c), w) -> m ((a, w), HList c))
    -> (m (a, HList c) -> m ((a, HList c), w))
    -> m (a, HList c)
    -> m ((a, w), HList c)
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . m (a, HList c) -> m ((a, HList c), w)
    forall w (m :: * -> *) a. MonadWriter w m => m a -> m (a, w)
    listen) (StateT (HList c) m a -> StateT (HList c) m (a, w))
    -> (MultiReaderT c m a -> StateT (HList c) m a)
    -> MultiReaderT c m a
    -> StateT (HList c) m (a, w)
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    .
        MultiReaderT c m a -> StateT (HList c) m a
    forall (x :: [*]) (m :: * -> *) a.
    MultiReaderT x m a -> StateT (HList x) m a
    runMultiReaderTRaw
      pass :: MultiReaderT c m (a, w -> w) -> MultiReaderT c m a
    pass = StateT (HList c) m a -> MultiReaderT c m a
    forall (x :: [*]) (m :: * -> *) a.
    StateT (HList x) m a -> MultiReaderT x m a
    MultiReaderT (StateT (HList c) m a -> MultiReaderT c m a)
    -> (MultiReaderT c m (a, w -> w) -> StateT (HList c) m a)
    -> MultiReaderT c m (a, w -> w)
    -> MultiReaderT c m a
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    .
        (m ((a, w -> w), HList c) -> m (a, HList c))
    -> StateT (HList c) m (a, w -> w) -> StateT (HList c) m a
    forall (m :: * -> *) a s (n :: * -> *) b.
    (m (a, s) -> n (b, s)) -> StateT s m a -> StateT s n b
    mapStateT (m ((a, HList c), w -> w) -> m (a, HList c)
    forall w (m :: * -> *) a. MonadWriter w m => m (a, w -> w) -> m a
    pass (m ((a, HList c), w -> w) -> m (a, HList c))
    -> (m ((a, w -> w), HList c) -> m ((a, HList c), w -> w))
    -> m ((a, w -> w), HList c)
    -> m (a, HList c)
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . (((a, w -> w), HList c) -> ((a, HList c), w -> w))
    -> m ((a, w -> w), HList c) -> m ((a, HList c), w -> w)
    forall (m :: * -> *) a1 r. Monad m => (a1 -> r) -> m a1 -> m r
    liftM (\((a :: a
    a, f :: w -> w
    f), w :: HList c
    w) -> ((a
    a, HList c
    w), w -> w
    f))) (StateT (HList c) m (a, w -> w) -> StateT (HList c) m a)
    -> (MultiReaderT c m (a, w -> w) -> StateT (HList c) m (a, w -> w))
    -> MultiReaderT c m (a, w -> w)
    -> StateT (HList c) m a
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    .
        MultiReaderT c m (a, w -> w) -> StateT (HList c) m (a, w -> w)
    forall (x :: [*]) (m :: * -> *) a.
    MultiReaderT x m a -> StateT (HList x) m a
    runMultiReaderTRaw

    instance MonadIO m => MonadIO (MultiReaderT c m) where
      liftIO :: IO a -> MultiReaderT c m a
    liftIO = m a -> MultiReaderT c m a
    forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
    (MonadTrans t, Monad m) =>
    m a -> t m a
    lift (m a -> MultiReaderT c m a)
    -> (IO a -> m a) -> IO a -> MultiReaderT c m a
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . IO a -> m a
    forall (m :: * -> *) a. MonadIO m => IO a -> m a
    liftIO

    instance (Functor m, Applicative m, MonadPlus m) => Alternative (MultiReaderT c m) where
      empty :: MultiReaderT c m a
    empty = m a -> MultiReaderT c m a
    forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
    (MonadTrans t, Monad m) =>
    m a -> t m a
    lift m a
    forall (m :: * -> *) a. MonadPlus m => m a
    mzero
      MultiReaderT m :: StateT (HList c) m a
    m <|> :: MultiReaderT c m a -> MultiReaderT c m a -> MultiReaderT c m a
    <|> MultiReaderT n :: StateT (HList c) m a
    n = StateT (HList c) m a -> MultiReaderT c m a
    forall (x :: [*]) (m :: * -> *) a.
    StateT (HList x) m a -> MultiReaderT x m a
    MultiReaderT (StateT (HList c) m a -> MultiReaderT c m a)
    -> StateT (HList c) m a -> MultiReaderT c m a
    forall a b. (a -> b) -> a -> b
    $ StateT (HList c) m a
    m StateT (HList c) m a
    -> StateT (HList c) m a -> StateT (HList c) m a
    forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
    <|> StateT (HList c) m a
    n

    instance MonadPlus m => MonadPlus (MultiReaderT c m) where
      mzero :: MultiReaderT c m a
    mzero = StateT (HList c) m a -> MultiReaderT c m a
    forall (x :: [*]) (m :: * -> *) a.
    StateT (HList x) m a -> MultiReaderT x m a
    MultiReaderT (StateT (HList c) m a -> MultiReaderT c m a)
    -> StateT (HList c) m a -> MultiReaderT c m a
    forall a b. (a -> b) -> a -> b
    $ StateT (HList c) m a
    forall (m :: * -> *) a. MonadPlus m => m a
    mzero
      MultiReaderT m :: StateT (HList c) m a
    m mplus :: MultiReaderT c m a -> MultiReaderT c m a -> MultiReaderT c m a
    `mplus` MultiReaderT n :: StateT (HList c) m a
    n = StateT (HList c) m a -> MultiReaderT c m a
    forall (x :: [*]) (m :: * -> *) a.
    StateT (HList x) m a -> MultiReaderT x m a
    MultiReaderT (StateT (HList c) m a -> MultiReaderT c m a)
    -> StateT (HList c) m a -> MultiReaderT c m a
    forall a b. (a -> b) -> a -> b
    $ StateT (HList c) m a
    m StateT (HList c) m a
    -> StateT (HList c) m a -> StateT (HList c) m a
    forall (m :: * -> *) a. MonadPlus m => m a -> m a -> m a
    `mplus` StateT (HList c) m a
    n

    instance MonadBase b m => MonadBase b (MultiReaderT r m) where
      liftBase :: b α -> MultiReaderT r m α
    liftBase = b α -> MultiReaderT r m α
    forall (t :: (* -> *) -> * -> *) (b :: * -> *) (m :: * -> *) α.
    (MonadTrans t, MonadBase b m) =>
    b α -> t m α
    liftBaseDefault

    instance MonadTransControl (MultiReaderT r) where
      type StT (MultiReaderT r) a = (a, HList r)
      liftWith :: (Run (MultiReaderT r) -> m a) -> MultiReaderT r m a
    liftWith f :: Run (MultiReaderT r) -> m a
    f = StateT (HList r) m a -> MultiReaderT r m a
    forall (x :: [*]) (m :: * -> *) a.
    StateT (HList x) m a -> MultiReaderT x m a
    MultiReaderT (StateT (HList r) m a -> MultiReaderT r m a)
    -> StateT (HList r) m a -> MultiReaderT r m a
    forall a b. (a -> b) -> a -> b
    $ (Run (StateT (HList r)) -> m a) -> StateT (HList r) m a
    forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
    (MonadTransControl t, Monad m) =>
    (Run t -> m a) -> t m a
    liftWith ((Run (StateT (HList r)) -> m a) -> StateT (HList r) m a)
    -> (Run (StateT (HList r)) -> m a) -> StateT (HList r) m a
    forall a b. (a -> b) -> a -> b
    $ \s :: Run (StateT (HList r))
    s -> Run (MultiReaderT r) -> m a
    f (Run (MultiReaderT r) -> m a) -> Run (MultiReaderT r) -> m a
    forall a b. (a -> b) -> a -> b
    $ \r :: MultiReaderT r n b
    r -> StateT (HList r) n b -> n (StT (MultiReaderT r) b)
    Run (StateT (HList r))
    s (StateT (HList r) n b -> n (StT (MultiReaderT r) b))
    -> StateT (HList r) n b -> n (StT (MultiReaderT r) b)
    forall a b. (a -> b) -> a -> b
    $ MultiReaderT r n b -> StateT (HList r) n b
    forall (x :: [*]) (m :: * -> *) a.
    MultiReaderT x m a -> StateT (HList x) m a
    runMultiReaderTRaw MultiReaderT r n b
    r
      restoreT :: m (StT (MultiReaderT r) a) -> MultiReaderT r m a
    restoreT = StateT (HList r) m a -> MultiReaderT r m a
    forall (x :: [*]) (m :: * -> *) a.
    StateT (HList x) m a -> MultiReaderT x m a
    MultiReaderT (StateT (HList r) m a -> MultiReaderT r m a)
    -> (m (a, HList r) -> StateT (HList r) m a)
    -> m (a, HList r)
    -> MultiReaderT r m a
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . m (a, HList r) -> StateT (HList r) m a
    forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
    (MonadTransControl t, Monad m) =>
    m (StT t a) -> t m a
    restoreT

    instance MonadBaseControl b m => MonadBaseControl b (MultiReaderT r m) where
      type StM (MultiReaderT r m) a = ComposeSt (MultiReaderT r) m a
      liftBaseWith :: (RunInBase (MultiReaderT r m) b -> b a) -> MultiReaderT r m a
    liftBaseWith = (RunInBase (MultiReaderT r m) b -> b a) -> MultiReaderT r m a
    forall (t :: (* -> *) -> * -> *) (b :: * -> *) (m :: * -> *) a.
    (MonadTransControl t, MonadBaseControl b m) =>
    (RunInBaseDefault t m b -> b a) -> t m a
    defaultLiftBaseWith
      restoreM :: StM (MultiReaderT r m) a -> MultiReaderT r m a
    restoreM = StM (MultiReaderT r m) a -> MultiReaderT r m a
    forall (t :: (* -> *) -> * -> *) (b :: * -> *) (m :: * -> *) a.
    (MonadTransControl t, MonadBaseControl b m) =>
    ComposeSt t m a -> t m a
    defaultRestoreM