{-# LANGUAGE CPP #-}
{-# OPTIONS_HADDOCK not-home #-}
module Control.Effect.Carrier.Internal.Compose where
import Control.Applicative
import Control.Monad
import qualified Control.Monad.Fail as Fail
import Control.Monad.Trans
import Control.Monad.Trans.Identity
import Control.Monad.Fix
import Control.Effect.Internal
import Control.Effect.Internal.Derive
import Control.Effect.Internal.Utils
import Control.Monad.Trans.Control
import Unsafe.Coerce
newtype ComposeT t (u :: (* -> *) -> * -> *) m a = ComposeT {
getComposeT :: t (u m) a
}
deriving ( Functor, Applicative, Monad
, Alternative, MonadPlus
, MonadFix, MonadFail, MonadIO
, MonadThrow, MonadCatch, MonadMask
, MonadBase b, MonadBaseControl b
, Carrier
)
instance ( MonadTrans t
, MonadTrans u
, forall m. Monad m => Monad (u m)
)
=> MonadTrans (ComposeT t u) where
lift m = ComposeT (lift (lift m))
{-# INLINEABLE lift #-}
instance ( MonadTransControl t
, MonadTransControl u
, forall m. Monad m => Monad (u m)
)
=> MonadTransControl (ComposeT t u) where
type StT (ComposeT t u) a = StT u (StT t a)
liftWith main = ComposeT $
liftWith $ \lowerT ->
liftWith $ \lowerU ->
main (lowerU . lowerT .# getComposeT)
{-# INLINEABLE liftWith #-}
restoreT m = ComposeT (restoreT (restoreT m))
{-# INLINEABLE restoreT #-}
newtype CompositionC ts m a = CompositionC {
unCompositionC :: CompositionBaseT ts m a
}
#define DERIVE_COMP_M(ctx) \
deriving newtype instance ctx (CompositionBaseT ts m) \
=> ctx (CompositionC ts m)
#define DERIVE_COMP_T(ctx) \
deriving newtype instance ctx (CompositionBaseT ts) \
=> ctx (CompositionC ts)
DERIVE_COMP_M(Functor)
DERIVE_COMP_M(Applicative)
DERIVE_COMP_M(Monad)
DERIVE_COMP_M(Alternative)
DERIVE_COMP_M(MonadPlus)
DERIVE_COMP_M(MonadFix)
DERIVE_COMP_M(Fail.MonadFail)
DERIVE_COMP_M(MonadIO)
DERIVE_COMP_M(MonadThrow)
DERIVE_COMP_M(MonadCatch)
DERIVE_COMP_M(MonadMask)
deriving newtype instance (Monad b, MonadBase b (CompositionBaseT ts m))
=> MonadBase b (CompositionC ts m)
DERIVE_COMP_M(MonadBaseControl b)
DERIVE_COMP_M(Carrier)
DERIVE_COMP_T(MonadTrans)
DERIVE_COMP_T(MonadTransControl)
type family CompositionBaseT' acc ts :: (* -> *) -> * -> * where
CompositionBaseT' acc '[] = acc
CompositionBaseT' acc (t ': ts) = CompositionBaseT' (ComposeT acc t) ts
type CompositionBaseT ts = CompositionBaseT' IdentityT ts
type family CompositionBaseM (ts :: [(* -> *) -> * -> *]) (m :: * -> *) where
CompositionBaseM '[] m = m
CompositionBaseM (t ': ts) m = t (CompositionBaseM ts m)
runComposition :: CompositionC ts m a
-> CompositionBaseM ts m a
runComposition = unsafeCoerce
{-# INLINE runComposition #-}