{-# LANGUAGE ConstraintKinds #-}
{-# LANGUAGE Safe #-}
module Control.Eff.Lift ( Lift (..)
, Lifted
, LiftedBase
, lift
, runLift
, catchDynE
) where
import Control.Eff.Internal
import qualified Control.Exception as Exc
import Data.OpenUnion
import Control.Monad.Trans.Control (MonadBaseControl)
type Lifted m r = SetMember Lift (Lift m) r
type LiftedBase m r = ( SetMember Lift (Lift m) r
, MonadBaseControl m (Eff r)
)
catchDynE :: forall e a r.
(Lifted IO r, Exc.Exception e) =>
Eff r a -> (e -> Eff r a) -> Eff r a
catchDynE m eh = interpose return h m
where
h :: Lift IO v -> Arr r v a -> Eff r a
h (Lift em) k = lift (Exc.try em) >>= \x -> case x of
Right x0 -> k x0
Left e -> eh e