{-# LANGUAGE DerivingVia #-}
module Control.Effect.Regional
(
Regional(..)
, Hoist
, regionally
, hoist
, runHoist
, hoistToFinal
, threadRegionalViaOptional
, powerAlgHoist
, powerAlgHoistFinal
, HoistC
, HoistToFinalC
) where
import Control.Effect
import Control.Effect.Carrier
import Control.Effect.Type.Regional
import Control.Effect.Type.Optional
import Control.Effect.Internal.Regional
import Control.Monad.Trans.Control (control)
regionally :: Eff (Regional s) m => s -> m a -> m a
regionally s m = send (Regionally s m)
{-# INLINE regionally #-}
hoist :: Eff (Hoist b) m => (forall x. b x -> b x) -> m a -> m a
hoist n = regionally (HoistCall n)
{-# INLINE hoist #-}
type HoistToFinalC b = InterpretPrimC HoistToFinalH (Hoist b)
runHoist :: Carrier m
=> HoistC m a
-> m a
runHoist = unHoistC
{-# INLINE runHoist #-}
hoistToFinal :: ( MonadBaseControl b m
, Carrier m
)
=> HoistToFinalC b m a
-> m a
hoistToFinal = interpretPrimViaHandler
{-# INLINE hoistToFinal #-}
powerAlgHoist :: forall m p a
. Algebra' p m a
-> Algebra' (Hoist m ': p) m a
powerAlgHoist alg = powerAlg alg $ \(Regionally (HoistCall n) m) -> n m
{-# INLINE powerAlgHoist #-}
powerAlgHoistFinal :: forall b m p a
. MonadBaseControl b m
=> Algebra' p m a
-> Algebra' (Hoist b ': p) m a
powerAlgHoistFinal alg = powerAlg alg $ \case
Regionally (HoistCall n) m -> control $ \lower -> n (lower m)
{-# INLINE powerAlgHoistFinal #-}