{-# LANGUAGE DeriveFunctor, ExistentialQuantification, FlexibleContexts, StandaloneDeriving #-}
-- | An effect providing the ability to throw exceptions from a context. If an exception is
-- thrown, the calling context may choose to resume the computation. Type safety of the
-- resumed operation is preserved by parametricity achieved from the @-XGADTs@ extension.
--
-- Predefined carriers:
--
-- * "Control.Carrier.Resumable.Resume", which provides full resumption semantics.
-- * "Control.Carrier.Resumable.Either", which elides resumption support (like @Control.Effect.Error@).
module Control.Effect.Resumable
( -- * Resumable effect
Resumable(..)
, throwResumable
-- * Re-exports
, Has
, run
) where
import Control.Algebra
-- | Errors which can be resumed with values of some existentially-quantified type.
--
-- @since 0.1.0.0
data Resumable err m k
= forall a . Resumable (err a) (a -> m k)
deriving instance Functor m => Functor (Resumable err m)
instance HFunctor (Resumable err) where
hmap f (Resumable err k) = Resumable err (f . k)
instance Effect (Resumable err) where
thread state handler (Resumable err k) = Resumable err (handler . (<$ state) . k)
-- | Throw an error which can be resumed with a value of its result type. Note that the type parameters in the @err a@ paramater and @m a@ parameter must match up; this indicates the type with which the error must be resumed.
--
-- @since 0.1.0.0
throwResumable :: Has (Resumable err) sig m => err a -> m a
throwResumable err = send (Resumable err pure)