module Control.Effect.Optional
(
Optional(..)
, HoistOption
, HoistOptionCall(..)
, optionally
, hoistOption
, runHoistOption
, hoistOptionToFinal
, threadOptionalViaBaseControl
, powerAlgHoistOption
, powerAlgHoistOptionFinal
, HoistOptionC
, HoistOptionToFinalC
) where
import Control.Monad
import Control.Monad.Trans.Control
import Control.Effect
import Control.Effect.Carrier
import Control.Effect.Internal.Optional
import Control.Effect.Type.Internal.BaseControl
import Control.Effect.Type.Optional
optionally :: Eff (Optional s) m => s a -> m a -> m a
optionally s m = send (Optionally s m)
{-# INLINE optionally #-}
hoistOption :: Eff (HoistOption b) m
=> (forall x. (a -> x) -> b x -> b x)
-> m a -> m a
hoistOption n = optionally (HoistOptionCall n)
{-# INLINE hoistOption #-}
runHoistOption :: Carrier m
=> HoistOptionC m a
-> m a
runHoistOption = unHoistOptionC
{-# INLINE runHoistOption #-}
data HoistOptionToFinalH
instance ( Carrier m
, MonadBaseControl b m
)
=> PrimHandler HoistOptionToFinalH (HoistOption b) m where
effPrimHandler (Optionally (HoistOptionCall b) m) =
join $ liftBaseWith $ \lower ->
b pure (restoreM <$> lower m)
{-# INLINEABLE effPrimHandler #-}
type HoistOptionToFinalC b = InterpretPrimC HoistOptionToFinalH (HoistOption b)
hoistOptionToFinal :: ( MonadBaseControl b m
, Carrier m
)
=> HoistOptionToFinalC b m a
-> m a
hoistOptionToFinal = interpretPrimViaHandler
{-# INLINE hoistOptionToFinal #-}
powerAlgHoistOption :: forall m p a
. Algebra' p m a
-> Algebra' (HoistOption m ': p) m a
powerAlgHoistOption alg = powerAlg alg $ \case
Optionally (HoistOptionCall b) m -> b id m
{-# INLINE powerAlgHoistOption #-}
powerAlgHoistOptionFinal :: forall b m p a
. MonadBaseControl b m
=> Algebra' p m a
-> Algebra' (HoistOption b ': p) m a
powerAlgHoistOptionFinal alg = powerAlg alg $ \case
Optionally (HoistOptionCall b) m -> join $ liftBaseWith $ \lower ->
b pure (restoreM <$> lower m)
{-# INLINE powerAlgHoistOptionFinal #-}