module Control.Monad.Trans.Extended
  ( TransT (..),
  )
where

import Control.Monad.Morph
import Data.Kind
import Prelude

-- | Utility newtype that can be used to derive type class instances just using
-- `MonadTrans`.
--
-- We often derive some `MonadBlaBla` instance for `ReaderT` by using `lift`
-- from `MonadTrans`.  Which is fine, but it gets laborious if you do the same
-- for `ExceptT`, `StateT` and `WriterT`, even though the method implementations
-- are exactly the same.  `TransT` allows you to write one `MonadTrans`-based
-- instance, which can then be used with `DerivingVia` to use that one
-- implementation for all monad transformers that use that same lifting
-- implementation.
newtype TransT t (m :: Type -> Type) a = TransT (t m a)
  deriving ((forall a b. (a -> b) -> TransT t m a -> TransT t m b)
-> (forall a b. a -> TransT t m b -> TransT t m a)
-> Functor (TransT t m)
forall a b. a -> TransT t m b -> TransT t m a
forall a b. (a -> b) -> TransT t m a -> TransT t m b
forall (f :: * -> *).
(forall a b. (a -> b) -> f a -> f b)
-> (forall a b. a -> f b -> f a) -> Functor f
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a b.
Functor (t m) =>
a -> TransT t m b -> TransT t m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a b.
Functor (t m) =>
(a -> b) -> TransT t m a -> TransT t m b
$cfmap :: forall (t :: (* -> *) -> * -> *) (m :: * -> *) a b.
Functor (t m) =>
(a -> b) -> TransT t m a -> TransT t m b
fmap :: forall a b. (a -> b) -> TransT t m a -> TransT t m b
$c<$ :: forall (t :: (* -> *) -> * -> *) (m :: * -> *) a b.
Functor (t m) =>
a -> TransT t m b -> TransT t m a
<$ :: forall a b. a -> TransT t m b -> TransT t m a
Functor, Functor (TransT t m)
Functor (TransT t m)
-> (forall a. a -> TransT t m a)
-> (forall a b.
    TransT t m (a -> b) -> TransT t m a -> TransT t m b)
-> (forall a b c.
    (a -> b -> c) -> TransT t m a -> TransT t m b -> TransT t m c)
-> (forall a b. TransT t m a -> TransT t m b -> TransT t m b)
-> (forall a b. TransT t m a -> TransT t m b -> TransT t m a)
-> Applicative (TransT t m)
forall a. a -> TransT t m a
forall a b. TransT t m a -> TransT t m b -> TransT t m a
forall a b. TransT t m a -> TransT t m b -> TransT t m b
forall a b. TransT t m (a -> b) -> TransT t m a -> TransT t m b
forall a b c.
(a -> b -> c) -> TransT t m a -> TransT t m b -> TransT t m c
forall (f :: * -> *).
Functor f
-> (forall a. a -> f a)
-> (forall a b. f (a -> b) -> f a -> f b)
-> (forall a b c. (a -> b -> c) -> f a -> f b -> f c)
-> (forall a b. f a -> f b -> f b)
-> (forall a b. f a -> f b -> f a)
-> Applicative f
forall {t :: (* -> *) -> * -> *} {m :: * -> *}.
Applicative (t m) =>
Functor (TransT t m)
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
Applicative (t m) =>
a -> TransT t m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a b.
Applicative (t m) =>
TransT t m a -> TransT t m b -> TransT t m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a b.
Applicative (t m) =>
TransT t m a -> TransT t m b -> TransT t m b
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a b.
Applicative (t m) =>
TransT t m (a -> b) -> TransT t m a -> TransT t m b
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a b c.
Applicative (t m) =>
(a -> b -> c) -> TransT t m a -> TransT t m b -> TransT t m c
$cpure :: forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
Applicative (t m) =>
a -> TransT t m a
pure :: forall a. a -> TransT t m a
$c<*> :: forall (t :: (* -> *) -> * -> *) (m :: * -> *) a b.
Applicative (t m) =>
TransT t m (a -> b) -> TransT t m a -> TransT t m b
<*> :: forall a b. TransT t m (a -> b) -> TransT t m a -> TransT t m b
$cliftA2 :: forall (t :: (* -> *) -> * -> *) (m :: * -> *) a b c.
Applicative (t m) =>
(a -> b -> c) -> TransT t m a -> TransT t m b -> TransT t m c
liftA2 :: forall a b c.
(a -> b -> c) -> TransT t m a -> TransT t m b -> TransT t m c
$c*> :: forall (t :: (* -> *) -> * -> *) (m :: * -> *) a b.
Applicative (t m) =>
TransT t m a -> TransT t m b -> TransT t m b
*> :: forall a b. TransT t m a -> TransT t m b -> TransT t m b
$c<* :: forall (t :: (* -> *) -> * -> *) (m :: * -> *) a b.
Applicative (t m) =>
TransT t m a -> TransT t m b -> TransT t m a
<* :: forall a b. TransT t m a -> TransT t m b -> TransT t m a
Applicative, Applicative (TransT t m)
Applicative (TransT t m)
-> (forall a b.
    TransT t m a -> (a -> TransT t m b) -> TransT t m b)
-> (forall a b. TransT t m a -> TransT t m b -> TransT t m b)
-> (forall a. a -> TransT t m a)
-> Monad (TransT t m)
forall a. a -> TransT t m a
forall a b. TransT t m a -> TransT t m b -> TransT t m b
forall a b. TransT t m a -> (a -> TransT t m b) -> TransT t m b
forall (m :: * -> *).
Applicative m
-> (forall a b. m a -> (a -> m b) -> m b)
-> (forall a b. m a -> m b -> m b)
-> (forall a. a -> m a)
-> Monad m
forall {t :: (* -> *) -> * -> *} {m :: * -> *}.
Monad (t m) =>
Applicative (TransT t m)
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
Monad (t m) =>
a -> TransT t m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a b.
Monad (t m) =>
TransT t m a -> TransT t m b -> TransT t m b
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a b.
Monad (t m) =>
TransT t m a -> (a -> TransT t m b) -> TransT t m b
$c>>= :: forall (t :: (* -> *) -> * -> *) (m :: * -> *) a b.
Monad (t m) =>
TransT t m a -> (a -> TransT t m b) -> TransT t m b
>>= :: forall a b. TransT t m a -> (a -> TransT t m b) -> TransT t m b
$c>> :: forall (t :: (* -> *) -> * -> *) (m :: * -> *) a b.
Monad (t m) =>
TransT t m a -> TransT t m b -> TransT t m b
>> :: forall a b. TransT t m a -> TransT t m b -> TransT t m b
$creturn :: forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
Monad (t m) =>
a -> TransT t m a
return :: forall a. a -> TransT t m a
Monad, (forall (m :: * -> *) a. Monad m => m a -> TransT t m a)
-> MonadTrans (TransT t)
forall (m :: * -> *) a. Monad m => m a -> TransT t m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> TransT t m a
forall (t :: (* -> *) -> * -> *).
(forall (m :: * -> *) a. Monad m => m a -> t m a) -> MonadTrans t
$clift :: forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> TransT t m a
lift :: forall (m :: * -> *) a. Monad m => m a -> TransT t m a
MonadTrans, (forall (m :: * -> *) (n :: * -> *) b.
 Monad m =>
 (forall a. m a -> n a) -> TransT t m b -> TransT t n b)
-> MFunctor (TransT t)
forall {k} (t :: (* -> *) -> k -> *).
(forall (m :: * -> *) (n :: * -> *) (b :: k).
 Monad m =>
 (forall a. m a -> n a) -> t m b -> t n b)
-> MFunctor t
forall (m :: * -> *) (n :: * -> *) b.
Monad m =>
(forall a. m a -> n a) -> TransT t m b -> TransT t n b
forall (t :: (* -> *) -> * -> *) (m :: * -> *) (n :: * -> *) b.
(MFunctor t, Monad m) =>
(forall a. m a -> n a) -> TransT t m b -> TransT t n b
$choist :: forall (t :: (* -> *) -> * -> *) (m :: * -> *) (n :: * -> *) b.
(MFunctor t, Monad m) =>
(forall a. m a -> n a) -> TransT t m b -> TransT t n b
hoist :: forall (m :: * -> *) (n :: * -> *) b.
Monad m =>
(forall a. m a -> n a) -> TransT t m b -> TransT t n b
MFunctor, MonadTrans (TransT t)
MFunctor (TransT t)
MFunctor (TransT t)
-> MonadTrans (TransT t)
-> (forall (n :: * -> *) (m :: * -> *) b.
    Monad n =>
    (forall a. m a -> TransT t n a) -> TransT t m b -> TransT t n b)
-> MMonad (TransT t)
forall (n :: * -> *) (m :: * -> *) b.
Monad n =>
(forall a. m a -> TransT t n a) -> TransT t m b -> TransT t n b
forall {t :: (* -> *) -> * -> *}. MMonad t => MonadTrans (TransT t)
forall {t :: (* -> *) -> * -> *}. MMonad t => MFunctor (TransT t)
forall (t :: (* -> *) -> * -> *) (n :: * -> *) (m :: * -> *) b.
(MMonad t, Monad n) =>
(forall a. m a -> TransT t n a) -> TransT t m b -> TransT t n b
forall (t :: (* -> *) -> * -> *).
MFunctor t
-> MonadTrans t
-> (forall (n :: * -> *) (m :: * -> *) b.
    Monad n =>
    (forall a. m a -> t n a) -> t m b -> t n b)
-> MMonad t
$cembed :: forall (t :: (* -> *) -> * -> *) (n :: * -> *) (m :: * -> *) b.
(MMonad t, Monad n) =>
(forall a. m a -> TransT t n a) -> TransT t m b -> TransT t n b
embed :: forall (n :: * -> *) (m :: * -> *) b.
Monad n =>
(forall a. m a -> TransT t n a) -> TransT t m b -> TransT t n b
MMonad)