{-# LANGUAGE DerivingVia #-}
{-# OPTIONS_HADDOCK not-home #-}
module Control.Effect.Carrier.Internal.Intro where
import Data.Coerce
import Control.Applicative
import Control.Monad
import Control.Monad.Trans
import Control.Monad.Catch
import Control.Monad.Fix
import Control.Effect.Internal
import Control.Effect.Internal.Derive
import Control.Effect.Internal.Union
import Control.Effect.Internal.Utils
import Control.Effect.Internal.KnownList
import Control.Monad.Trans.Identity
newtype IntroC (top :: [Effect])
(new :: [Effect])
(m :: * -> *)
a
= IntroC { runIntroC :: m a }
deriving ( Functor, Applicative, Monad
, Alternative, MonadPlus
, MonadFix, MonadFail, MonadIO
, MonadThrow, MonadCatch, MonadMask
, MonadBase b, MonadBaseControl b
)
deriving (MonadTrans, MonadTransControl) via IdentityT
type RestDerivs top new m = StripPrefix new (StripPrefix top (Derivs m))
instance ( Carrier m
, KnownList top
, KnownList new
, IntroConsistent top new m
) => Carrier (IntroC top new m) where
type Derivs (IntroC top new m) = Append top (RestDerivs top new m)
type Prims (IntroC top new m) = Prims m
algPrims = coerce (algPrims @m)
{-# INLINEABLE algPrims #-}
reformulate n alg =
weakenAlgMid
@(RestDerivs top new m)
(singList @top)
(singList @new)
(reformulate (n .# IntroC) alg)
{-# INLINEABLE reformulate #-}
algDerivs =
weakenAlgMid
@(RestDerivs top new m)
(singList @top)
(singList @new)
(coerce (algDerivs @m))
{-# INLINEABLE algDerivs #-}
type IntroTopC = IntroC '[]
type IntroUnderC e = IntroC '[e]
type IntroUnderManyC = IntroC
type HeadEff e m = (IntroConsistent '[] '[e] m, Carrier m)
type HeadEffs new m = (IntroConsistent '[] new m, Carrier m)
type IntroConsistent top new m
= (Append top (Append new (StripPrefix new (StripPrefix top (Derivs m)))) ~ Derivs m)
introUnderMany :: forall top new m a
. ( KnownList top
, KnownList new
, IntroConsistent top new m
)
=> IntroUnderManyC top new m a
-> m a
introUnderMany = runIntroC
{-# INLINE introUnderMany #-}
introUnder :: forall new e m a
. ( KnownList new
, IntroConsistent '[e] new m
)
=> IntroUnderC e new m a
-> m a
introUnder = runIntroC
{-# INLINE introUnder #-}
introUnder1 :: forall new e m a
. IntroConsistent '[e] '[new] m
=> IntroUnderC e '[new] m a
-> m a
introUnder1 = runIntroC
{-# INLINE introUnder1 #-}
intro :: forall new m a
. ( KnownList new
, IntroConsistent '[] new m
)
=> IntroTopC new m a
-> m a
intro = runIntroC
{-# INLINE intro #-}
intro1 :: forall e m a
. IntroConsistent '[] '[e] m
=> IntroTopC '[e] m a
-> m a
intro1 = runIntroC
{-# INLINE intro1 #-}