Safe Haskell | Safe-Inferred |
---|---|

Language | GHC2021 |

## Synopsis

- data Stop e :: Effect where
- stop :: forall e r a. Member (Stop e) r => e -> Sem r a
- type (!!) eff err = Resumable err eff
- data Resumable err eff :: Effect
- resume :: forall err eff r a. Member (Resumable err eff) r => Sem (eff : r) a -> (err -> Sem r a) -> Sem r a
- (!!) :: forall err eff r a. Member (Resumable err eff) r => Sem (eff : r) a -> (err -> Sem r a) -> Sem r a
- interpretResumable :: forall (err :: Type) (eff :: Effect) r. FirstOrder eff "interpretResumable" => (forall x r0. eff (Sem r0) x -> Sem (Stop err : r) x) -> InterpreterFor (Resumable err eff) r
- interpretResumableH :: forall (err :: Type) (eff :: Effect) (r :: EffectRow). (forall x r0. eff (Sem r0) x -> Tactical (Resumable err eff) (Sem r0) (Stop err : r) x) -> InterpreterFor (Resumable err eff) r
- interceptResumable :: forall (err :: Type) (eff :: Effect) (r :: EffectRow) (a :: Type). Member (Resumable err eff) r => FirstOrder eff "interceptResumable" => (forall x r0. eff (Sem r0) x -> Sem (Stop err : r) x) -> Sem r a -> Sem r a
- interceptResumableH :: forall (err :: Type) (eff :: Effect) (r :: EffectRow) (a :: Type). Member (Resumable err eff) r => (forall x r0. eff (Sem r0) x -> Tactical (Resumable err eff) (Sem r0) (Stop err : r) x) -> Sem r a -> Sem r a
- interceptResumableUsing :: forall (err :: Type) (eff :: Effect) (r :: EffectRow) (a :: Type). FirstOrder eff "interceptResumableUsing" => ElemOf (Resumable err eff) r -> (forall x r0. eff (Sem r0) x -> Sem (Stop err : r) x) -> Sem r a -> Sem r a
- interceptResumableUsingH :: forall (err :: Type) (eff :: Effect) (r :: EffectRow) (a :: Type). ElemOf (Resumable err eff) r -> (forall x r0. eff (Sem r0) x -> Tactical (Resumable err eff) (Sem r0) (Stop err : r) x) -> Sem r a -> Sem r a
- resumable :: forall (err :: Type) (eff :: Effect) (r :: EffectRow). InterpreterFor eff (Stop err : r) -> InterpreterFor (Resumable err eff) r
- raiseResumable :: forall (err :: Type) (eff :: Effect) (r :: EffectRow). InterpreterTrans (Resumable err eff) eff r
- resumableIO :: forall (err :: Type) (eff :: Effect) (r :: EffectRow). Exception (StopExc err) => Member (Final IO) r => InterpreterFor eff (Stop err : r) -> InterpreterFor (Resumable err eff) r
- interpretScopedResumable :: forall param resource effect err r. (forall q x. param -> (resource -> Sem (Stop err : (Opaque q : r)) x) -> Sem (Stop err : (Opaque q : r)) x) -> (forall q r0 x. resource -> effect (Sem r0) x -> Sem (Stop err : (Opaque q : r)) x) -> InterpreterFor (Scoped param effect !! err) r
- interpretScopedResumableH :: forall param resource effect err r. (forall q x. param -> (resource -> Sem (Stop err : (Opaque q : r)) x) -> Sem (Stop err : (Opaque q : r)) x) -> (forall q r0 x. resource -> effect (Sem r0) x -> Tactical effect (Sem r0) (Stop err : (Opaque q : r)) x) -> InterpreterFor (Scoped param effect !! err) r
- interpretScopedResumable_ :: forall param resource effect err r. (forall q. param -> Sem (Stop err : (Opaque q : r)) resource) -> (forall q r0 x. resource -> effect (Sem r0) x -> Sem (Stop err : (Opaque q : r)) x) -> InterpreterFor (Scoped param effect !! err) r
- interpretScopedResumableWith :: forall extra param resource effect err r. KnownList extra => (forall q x. param -> (resource -> Sem (extra ++ (Stop err : (Opaque q : r))) x) -> Sem (Stop err : (Opaque q : r)) x) -> (forall q r0 x. resource -> effect (Sem r0) x -> Sem (extra ++ (Stop err : (Opaque q : r))) x) -> InterpreterFor (Scoped param effect !! err) r
- interpretScopedResumableWithH :: forall extra param resource effect err r. KnownList extra => (forall q x. param -> (resource -> Sem (extra ++ (Stop err : (Opaque q : r))) x) -> Sem (Stop err : (Opaque q : r)) x) -> (forall q r0 x. resource -> effect (Sem r0) x -> Tactical effect (Sem r0) (extra ++ ([Stop err, Opaque q] ++ r)) x) -> InterpreterFor (Scoped param effect !! err) r
- interpretScopedResumableWith_ :: forall extra param effect err r. KnownList extra => (forall q x. param -> Sem (extra ++ (Stop err : (Opaque q : r))) x -> Sem (Stop err : (Opaque q : r)) x) -> (forall q r0 x. effect (Sem r0) x -> Sem (extra ++ (Stop err : (Opaque q : r))) x) -> InterpreterFor (Scoped param effect !! err) r
- interpretResumableScoped :: forall param resource effect err r. (forall q x. param -> (resource -> Sem (Opaque q : r) x) -> Sem (Opaque q : r) x) -> (forall q r0 x. resource -> effect (Sem r0) x -> Sem (Stop err : (Opaque q : r)) x) -> InterpreterFor (Scoped param (effect !! err)) r
- interpretResumableScopedH :: forall param resource effect err r. (forall q x. param -> (resource -> Sem (Opaque q : r) x) -> Sem (Opaque q : r) x) -> (forall q r0 x. resource -> effect (Sem r0) x -> Tactical (effect !! err) (Sem r0) (Stop err : (Opaque q : r)) x) -> InterpreterFor (Scoped param (effect !! err)) r
- interpretResumableScoped_ :: forall param resource effect err r. (param -> Sem r resource) -> (forall q r0 x. resource -> effect (Sem r0) x -> Sem (Stop err : (Opaque q : r)) x) -> InterpreterFor (Scoped param (effect !! err)) r
- interpretResumableScopedWith :: forall extra param resource effect err r. KnownList extra => (forall q x. param -> (resource -> Sem (extra ++ (Opaque q : r)) x) -> Sem (Opaque q : r) x) -> (forall r0 x. resource -> effect (Sem r0) x -> Sem (Stop err : (extra ++ r)) x) -> InterpreterFor (Scoped param (effect !! err)) r
- interpretResumableScopedWithH :: forall extra param resource effect err r. KnownList extra => (forall q x. param -> (resource -> Sem (extra ++ (Opaque q : r)) x) -> Sem (Opaque q : r) x) -> (forall q r0 x. resource -> effect (Sem r0) x -> Tactical (effect !! err) (Sem r0) (Stop err : (extra ++ (Opaque q : r))) x) -> InterpreterFor (Scoped param (effect !! err)) r
- interpretResumableScopedWith_ :: forall extra param effect err r. KnownList extra => (forall q x. param -> Sem (extra ++ (Opaque q : r)) x -> Sem (Opaque q : r) x) -> (forall r0 x. effect (Sem r0) x -> Sem (Stop err : (extra ++ r)) x) -> InterpreterFor (Scoped param (effect !! err)) r
- interpretScopedR :: forall param resource effect eo ei r. (forall q x. param -> (resource -> Sem (Stop eo : (Opaque q : r)) x) -> Sem (Stop eo : (Opaque q : r)) x) -> (forall q r0 x. resource -> effect (Sem r0) x -> Sem (Stop ei : (Stop eo : (Opaque q : r))) x) -> InterpreterFor (Scoped param (effect !! ei) !! eo) r
- interpretScopedRH :: forall param resource effect eo ei r. (forall q x. param -> (resource -> Sem (Stop eo : (Opaque q : r)) x) -> Sem (Stop eo : (Opaque q : r)) x) -> (forall q r0 x. resource -> effect (Sem r0) x -> Tactical (effect !! ei) (Sem r0) (Stop ei : (Stop eo : (Opaque q : r))) x) -> InterpreterFor (Scoped param (effect !! ei) !! eo) r
- interpretScopedR_ :: forall param resource effect eo ei r. (param -> Sem (Stop eo : r) resource) -> (forall q r0 x. resource -> effect (Sem r0) x -> Sem (Stop ei : (Stop eo : (Opaque q : r))) x) -> InterpreterFor (Scoped param (effect !! ei) !! eo) r
- interpretScopedRWith :: forall extra param resource effect eo ei r. KnownList extra => (forall q x. param -> (resource -> Sem (extra ++ (Stop eo : (Opaque q : r))) x) -> Sem (Stop eo : (Opaque q : r)) x) -> (forall q r0 x. resource -> effect (Sem r0) x -> Sem (Stop ei : (extra ++ (Stop eo : (Opaque q : r)))) x) -> InterpreterFor (Scoped param (effect !! ei) !! eo) r
- interpretScopedRWithH :: forall extra param resource effect eo ei r. KnownList extra => (forall q x. param -> (resource -> Sem (extra ++ (Stop eo : (Opaque q : r))) x) -> Sem (Stop eo : (Opaque q : r)) x) -> (forall q r0 x. resource -> effect (Sem r0) x -> Tactical (effect !! ei) (Sem r0) (Stop ei : (extra ++ (Stop eo : (Opaque q : r)))) x) -> InterpreterFor (Scoped param (effect !! ei) !! eo) r
- interpretScopedRWith_ :: forall extra param effect eo ei r. KnownList extra => (forall q x. param -> Sem (extra ++ (Stop eo : (Opaque q : r))) x -> Sem (Stop eo : (Opaque q : r)) x) -> (forall q r0 x. effect (Sem r0) x -> Sem (Stop ei : (extra ++ (Stop eo : (Opaque q : r)))) x) -> InterpreterFor (Scoped param (effect !! ei) !! eo) r
- resumableOr :: forall (err :: Type) (eff :: Effect) unhandled handled r. Member (Error unhandled) r => (err -> Either unhandled handled) -> InterpreterFor eff (Stop err : r) -> InterpreterFor (Resumable handled eff) r
- resumeAs :: forall err eff r a. Member (Resumable err eff) r => a -> Sem (eff : r) a -> Sem r a
- (<!) :: forall err eff r a. Member (Resumable err eff) r => a -> Sem (eff : r) a -> Sem r a
- (!>) :: forall err eff r a. Member (Resumable err eff) r => Sem (eff : r) a -> a -> Sem r a
- resumeWith :: forall err eff r a. Member (Resumable err eff) r => Sem (eff : r) a -> Sem r a -> Sem r a
- (!>>) :: forall err eff r a. Member (Resumable err eff) r => Sem (eff : r) a -> Sem r a -> Sem r a
- resumingWith :: forall err eff r a. Member (Resumable err eff) r => Sem r a -> Sem (eff : r) a -> Sem r a
- (<<!) :: forall err eff r a. Member (Resumable err eff) r => Sem r a -> Sem (eff : r) a -> Sem r a
- resume_ :: forall err eff r. Member (Resumable err eff) r => Sem (eff : r) () -> Sem r ()
- resumeHoist :: forall err eff err' r a. Members [Resumable err eff, Stop err'] r => (err -> err') -> Sem (eff : r) a -> Sem r a
- resumeHoistAs :: forall err eff err' r. Members [Resumable err eff, Stop err'] r => err' -> InterpreterFor eff r
- resuming :: forall err eff r a. Member (Resumable err eff) r => (err -> Sem r a) -> Sem (eff : r) a -> Sem r a
- resumeHoistError :: forall err eff err' r a. Members [Resumable err eff, Error err'] r => (err -> err') -> Sem (eff : r) a -> Sem r a
- resumeHoistErrorAs :: forall err eff err' r a. Members [Resumable err eff, Error err'] r => err' -> Sem (eff : r) a -> Sem r a
- restop :: forall err eff r. Members [Resumable err eff, Stop err] r => InterpreterFor eff r
- resumeEither :: forall err eff r a. Member (Resumable err eff) r => Sem (eff : r) a -> Sem r (Either err a)
- resumeMaybe :: forall err eff r a. Member (Resumable err eff) r => Sem (eff : r) a -> Sem r (Maybe a)
- resumeOr :: forall err eff r a b. Member (Resumable err eff) r => Sem (eff : r) a -> (a -> Sem r b) -> (err -> Sem r b) -> Sem r b
- resumingOr :: forall err eff r a b. Member (Resumable err eff) r => (err -> Sem r b) -> Sem (eff : r) a -> (a -> Sem r b) -> Sem r b
- resumeError :: forall err eff r a. Members [Resumable err eff, Error err] r => Sem (eff : r) a -> Sem r a
- resumableError :: forall (err :: Type) (eff :: Effect) r. InterpreterFor eff (Error err : (Stop err : r)) -> InterpreterFor (Resumable err eff) r
- resumableFor :: forall (err :: Type) (eff :: Effect) handled r. Member (Error err) r => (err -> Maybe handled) -> InterpreterFor eff (Stop err : r) -> InterpreterFor (Resumable handled eff) r
- runAsResumable :: forall (err :: Type) (eff :: Effect) r. Members [Resumable err eff, Stop err] r => InterpreterFor eff r
- catchResumable :: forall (err :: Type) (eff :: Effect) handled r. Members [eff, Error err] r => (err -> Maybe handled) -> InterpreterFor (Resumable handled eff) r
- stopToFailWith :: forall err r. Member Fail r => (err -> Text) -> InterpreterFor (Stop err) r
- stopToFail :: forall err r. Show err => Member Fail r => InterpreterFor (Stop err) r
- resumeFailWith :: forall err eff r. Members [Fail, Resumable err eff] r => (err -> Text) -> InterpreterFor eff r
- resumeFail :: forall err eff r. Show err => Members [Fail, Resumable err eff] r => InterpreterFor eff r
- mapStop :: forall err e' r a. Member (Stop e') r => (err -> e') -> Sem (Stop err : r) a -> Sem r a
- replaceStop :: forall err e' r a. Member (Stop e') r => e' -> Sem (Stop err : r) a -> Sem r a
- runStop :: Sem (Stop err : r) a -> Sem r (Either err a)
- showStop :: forall err r a. Show err => Member (Stop Text) r => Sem (Stop err : r) a -> Sem r a
- stopEither :: forall err r a. Member (Stop err) r => Either err a -> Sem r a
- stopEitherAs :: forall err err' r a. Member (Stop err') r => err' -> Either err a -> Sem r a
- stopEitherWith :: forall err err' r a. Member (Stop err') r => (err -> err') -> Either err a -> Sem r a
- stopNote :: forall err r a. Member (Stop err) r => err -> Maybe a -> Sem r a
- stopOnError :: forall err r a. Member (Stop err) r => Sem (Error err : r) a -> Sem r a
- stopOnErrorWith :: forall err err' r a. Member (Stop err') r => (err -> err') -> Sem (Error err : r) a -> Sem r a
- stopToError :: forall err r a. Member (Error err) r => Sem (Stop err : r) a -> Sem r a
- stopToErrorIO :: forall err r a. Exception (StopExc err) => Members [Error err, Final IO] r => Sem (Stop err : r) a -> Sem r a
- stopToErrorWith :: forall err err' r a. Member (Error err') r => (err -> err') -> Sem (Stop err : r) a -> Sem r a
- stopToIOFinal :: forall err r a. Exception (StopExc err) => Member (Final IO) r => Sem (Stop err : r) a -> Sem r (Either err a)
- stopTryAny :: forall err r a. Members [Stop err, Embed IO] r => (Text -> err) -> IO a -> Sem r a
- stopTryIO :: forall exc err r a. Exception exc => Members [Stop err, Embed IO] r => (Text -> err) -> IO a -> Sem r a
- stopTryIOE :: forall exc err r a. Exception exc => Members [Stop err, Embed IO] r => (exc -> err) -> IO a -> Sem r a
- stopTryIOError :: forall err r a. Members [Stop err, Embed IO] r => (Text -> err) -> IO a -> Sem r a

# Introduction

This library provides the Polysemy effects `Resumable`

and `Stop`

for the purpose of safely connecting throwing and
catching errors across different interpreters.

Consider the effect:

data Stopper :: Effect where StopBang :: Stopper m () StopBoom :: Stopper m () makeSem ''Stopper data Boom = Boom { unBoom :: Text } | Bang { unBang :: Int } deriving stock (Eq, Show) interpretStopper :: Member (Error Boom) r => InterpreterFor Stopper r interpretStopper = interpret \case StopBang -> throw (Bang 13) StopBoom -> throw (Boom "ouch")

If we want to use `Stopper`

in the interpreter of another effect, we have no way of knowing about the errors thrown
by its interpreter, even though we can catch `Boom`

!
This library makes the connection explicit by changing `Error`

to `Stop`

and wrapping `Stopper`

in
`Resumable`

when using it in an effect stack:

data Stop e :: Effect where Source #

An effect similar to `Error`

without the ability to be caught.
Used to signal that an error is supposed to be expected by dependent programs.

interpretStopper :: Member (Stop Boom) r => InterpreterFor Stopper r interpretStopper = interpret \case StopBang -> stop (Bang 13) StopBoom -> stop (Boom "ouch")

stop :: forall e r a. Member (Stop e) r => e -> Sem r a Source #

Abort a computation with an error value.

type (!!) eff err = Resumable err eff Source #

Infix alias for `Resumable`

.

Member (Stopper !! Boom) r =>

data Resumable err eff :: Effect Source #

Effect that wraps another effect `eff`

, marking it as throwing errors of type `err`

using
`Stop`

.

# Resuming a Stopped Computation

resume :: forall err eff r a. Member (Resumable err eff) r => Sem (eff : r) a -> (err -> Sem r a) -> Sem r a Source #

Execute the action of a regular effect `eff`

so that any error of type `err`

that maybe be thrown by the (unknown)
interpreter used for `eff`

will be caught here and handled by the `handler`

argument.
This is similar to `catch`

with the additional guarantee that the error will have to be explicitly
matched, therefore preventing accidental failure to handle an error and bubbling it up to `main`

.
It also imposes a membership of `Resumable err eff`

on the program, requiring the interpreter for `eff`

to be adapted
with `resumable`

.

data Resumer :: Effect where MainProgram :: Resumer m Int makeSem ''Resumer interpretResumer :: Member (Resumable Boom Stopper) r => InterpreterFor Resumer r interpretResumer = interpret \ MainProgram -> resume (192 <$ stopBang) \ _ -> pure 237

(!!) :: forall err eff r a. Member (Resumable err eff) r => Sem (eff : r) a -> (err -> Sem r a) -> Sem r a Source #

Operator version of `resume`

.

*Since: 0.2.0.0*

interpretResumable :: forall (err :: Type) (eff :: Effect) r. FirstOrder eff "interpretResumable" => (forall x r0. eff (Sem r0) x -> Sem (Stop err : r) x) -> InterpreterFor (Resumable err eff) r Source #

Create an interpreter for

by supplying a handler function for `Resumable`

err eff`eff`

, analogous to
`interpret`

.
If the handler throws errors with `Stop`

, they will be absorbed into `Resumable`

, to be caught by
`resume`

in a downstream interpreter.

interpretStopperResumable :: InterpreterFor Stopper r interpretStopperResumable = interpretResumable \case StopBang -> stop (Bang 13) StopBoom -> stop (Boom "ouch")

`>>>`

237`run $ interpretStopperResumable (interpretResumer mainProgram)`

:: forall (err :: Type) (eff :: Effect) (r :: EffectRow). (forall x r0. eff (Sem r0) x -> Tactical (Resumable err eff) (Sem r0) (Stop err : r) x) | This handler function has |

-> InterpreterFor (Resumable err eff) r |

Like `interpretResumable`

, but for higher-order effects.

interceptResumable :: forall (err :: Type) (eff :: Effect) (r :: EffectRow) (a :: Type). Member (Resumable err eff) r => FirstOrder eff "interceptResumable" => (forall x r0. eff (Sem r0) x -> Sem (Stop err : r) x) -> Sem r a -> Sem r a Source #

Interceptor variant of `interpretResumable`

.

interceptResumableH :: forall (err :: Type) (eff :: Effect) (r :: EffectRow) (a :: Type). Member (Resumable err eff) r => (forall x r0. eff (Sem r0) x -> Tactical (Resumable err eff) (Sem r0) (Stop err : r) x) -> Sem r a -> Sem r a Source #

Interceptor variant of `interpretResumableH`

.

interceptResumableUsing :: forall (err :: Type) (eff :: Effect) (r :: EffectRow) (a :: Type). FirstOrder eff "interceptResumableUsing" => ElemOf (Resumable err eff) r -> (forall x r0. eff (Sem r0) x -> Sem (Stop err : r) x) -> Sem r a -> Sem r a Source #

Interceptor variant of `interpretResumable`

.

interceptResumableUsingH :: forall (err :: Type) (eff :: Effect) (r :: EffectRow) (a :: Type). ElemOf (Resumable err eff) r -> (forall x r0. eff (Sem r0) x -> Tactical (Resumable err eff) (Sem r0) (Stop err : r) x) -> Sem r a -> Sem r a Source #

Interceptor variant of `interpretResumableH`

.

resumable :: forall (err :: Type) (eff :: Effect) (r :: EffectRow). InterpreterFor eff (Stop err : r) -> InterpreterFor (Resumable err eff) r Source #

Convert a bare interpreter for `eff`

, which (potentially) uses `Stop`

to signal errors, into an interpreter for
`Resumable`

.
*Beware*: This will display unsound behaviour if:
* the interpreter is wrapped with actions of another effect, as in:

```
interpretEff :: InterpreterFor Eff r
...
interpretEffResumable :: InterpreterFor (Resumable Text Eff) r
interpretEffResumable sem =
resumable (interpretEff (sem
````finally`

releaseResources))

In this case, `releaseResources`

will be called after *every* use of `Eff`

in `sem`

, not after the entire thunk.

- the interpreter of a higher-order effect uses a different interpreter after using
`runT`

/`bindT`

. In this case, it will use the original interpreter instead.

If your use case matches one of these conditions, you'll need to use `interpretResumable`

.

`>>>`

237`run $ resumable interpretStopper (interpretResumer mainProgram)`

raiseResumable :: forall (err :: Type) (eff :: Effect) (r :: EffectRow). InterpreterTrans (Resumable err eff) eff r Source #

resumableIO :: forall (err :: Type) (eff :: Effect) (r :: EffectRow). Exception (StopExc err) => Member (Final IO) r => InterpreterFor eff (Stop err : r) -> InterpreterFor (Resumable err eff) r Source #

interpretScopedResumable :: forall param resource effect err r. (forall q x. param -> (resource -> Sem (Stop err : (Opaque q : r)) x) -> Sem (Stop err : (Opaque q : r)) x) -> (forall q r0 x. resource -> effect (Sem r0) x -> Sem (Stop err : (Opaque q : r)) x) -> InterpreterFor (Scoped param effect !! err) r Source #

interpretScopedResumableH :: forall param resource effect err r. (forall q x. param -> (resource -> Sem (Stop err : (Opaque q : r)) x) -> Sem (Stop err : (Opaque q : r)) x) -> (forall q r0 x. resource -> effect (Sem r0) x -> Tactical effect (Sem r0) (Stop err : (Opaque q : r)) x) -> InterpreterFor (Scoped param effect !! err) r Source #

interpretScopedResumable_ :: forall param resource effect err r. (forall q. param -> Sem (Stop err : (Opaque q : r)) resource) -> (forall q r0 x. resource -> effect (Sem r0) x -> Sem (Stop err : (Opaque q : r)) x) -> InterpreterFor (Scoped param effect !! err) r Source #

interpretScopedResumableWith :: forall extra param resource effect err r. KnownList extra => (forall q x. param -> (resource -> Sem (extra ++ (Stop err : (Opaque q : r))) x) -> Sem (Stop err : (Opaque q : r)) x) -> (forall q r0 x. resource -> effect (Sem r0) x -> Sem (extra ++ (Stop err : (Opaque q : r))) x) -> InterpreterFor (Scoped param effect !! err) r Source #

interpretScopedResumableWithH :: forall extra param resource effect err r. KnownList extra => (forall q x. param -> (resource -> Sem (extra ++ (Stop err : (Opaque q : r))) x) -> Sem (Stop err : (Opaque q : r)) x) -> (forall q r0 x. resource -> effect (Sem r0) x -> Tactical effect (Sem r0) (extra ++ ([Stop err, Opaque q] ++ r)) x) -> InterpreterFor (Scoped param effect !! err) r Source #

interpretScopedResumableWith_ :: forall extra param effect err r. KnownList extra => (forall q x. param -> Sem (extra ++ (Stop err : (Opaque q : r))) x -> Sem (Stop err : (Opaque q : r)) x) -> (forall q r0 x. effect (Sem r0) x -> Sem (extra ++ (Stop err : (Opaque q : r))) x) -> InterpreterFor (Scoped param effect !! err) r Source #

Combined interpreter for `Scoped`

and `Resumable`

that allows the handler to use additional effects that are
interpreted by the resource allocator.
This allows `Stop`

to be sent from within the resource allocator so that the consumer receives it, terminating the
entire scope.
In this variant, no resource is used and the allocator is a plain interpreter.

interpretResumableScoped :: forall param resource effect err r. (forall q x. param -> (resource -> Sem (Opaque q : r) x) -> Sem (Opaque q : r) x) -> (forall q r0 x. resource -> effect (Sem r0) x -> Sem (Stop err : (Opaque q : r)) x) -> InterpreterFor (Scoped param (effect !! err)) r Source #

interpretResumableScopedH :: forall param resource effect err r. (forall q x. param -> (resource -> Sem (Opaque q : r) x) -> Sem (Opaque q : r) x) -> (forall q r0 x. resource -> effect (Sem r0) x -> Tactical (effect !! err) (Sem r0) (Stop err : (Opaque q : r)) x) -> InterpreterFor (Scoped param (effect !! err)) r Source #

interpretResumableScoped_ :: forall param resource effect err r. (param -> Sem r resource) -> (forall q r0 x. resource -> effect (Sem r0) x -> Sem (Stop err : (Opaque q : r)) x) -> InterpreterFor (Scoped param (effect !! err)) r Source #

interpretResumableScopedWith :: forall extra param resource effect err r. KnownList extra => (forall q x. param -> (resource -> Sem (extra ++ (Opaque q : r)) x) -> Sem (Opaque q : r) x) -> (forall r0 x. resource -> effect (Sem r0) x -> Sem (Stop err : (extra ++ r)) x) -> InterpreterFor (Scoped param (effect !! err)) r Source #

interpretResumableScopedWithH :: forall extra param resource effect err r. KnownList extra => (forall q x. param -> (resource -> Sem (extra ++ (Opaque q : r)) x) -> Sem (Opaque q : r) x) -> (forall q r0 x. resource -> effect (Sem r0) x -> Tactical (effect !! err) (Sem r0) (Stop err : (extra ++ (Opaque q : r))) x) -> InterpreterFor (Scoped param (effect !! err)) r Source #

interpretResumableScopedWith_ :: forall extra param effect err r. KnownList extra => (forall q x. param -> Sem (extra ++ (Opaque q : r)) x -> Sem (Opaque q : r) x) -> (forall r0 x. effect (Sem r0) x -> Sem (Stop err : (extra ++ r)) x) -> InterpreterFor (Scoped param (effect !! err)) r Source #

Combined interpreter for `Resumable`

and `Scoped`

that allows the handler to use additional effects that are
interpreted by the resource allocator.
In this variant:
- Only the handler may send `Stop`

, but this allows resumption to happen on each action inside of the scope.
- No resource is used and the allocator is a plain interpreter.

interpretScopedR :: forall param resource effect eo ei r. (forall q x. param -> (resource -> Sem (Stop eo : (Opaque q : r)) x) -> Sem (Stop eo : (Opaque q : r)) x) -> (forall q r0 x. resource -> effect (Sem r0) x -> Sem (Stop ei : (Stop eo : (Opaque q : r))) x) -> InterpreterFor (Scoped param (effect !! ei) !! eo) r Source #

Combined interpreter for `Scoped`

and `Resumable`

.
In this variant, both the handler and the scope may send different errors via `Stop`

, encoding the concept that the
resource allocation may fail to prevent the scope from being executed, and each individual scoped action may fail,
continuing the scope execution on resumption.

interpretScopedRH :: forall param resource effect eo ei r. (forall q x. param -> (resource -> Sem (Stop eo : (Opaque q : r)) x) -> Sem (Stop eo : (Opaque q : r)) x) -> (forall q r0 x. resource -> effect (Sem r0) x -> Tactical (effect !! ei) (Sem r0) (Stop ei : (Stop eo : (Opaque q : r))) x) -> InterpreterFor (Scoped param (effect !! ei) !! eo) r Source #

Combined higher-order interpreter for `Resumable`

and `Scoped`

.
In this variant, both the handler and the scope may send different errors via `Stop`

, encoding the concept that the
resource allocation may fail to prevent the scope from being executed, and each individual scoped action may fail,
continuing the scope execution on resumption.

interpretScopedR_ :: forall param resource effect eo ei r. (param -> Sem (Stop eo : r) resource) -> (forall q r0 x. resource -> effect (Sem r0) x -> Sem (Stop ei : (Stop eo : (Opaque q : r))) x) -> InterpreterFor (Scoped param (effect !! ei) !! eo) r Source #

Combined interpreter for `Scoped`

and `Resumable`

.
In this variant:
- Both the handler and the scope may send different errors via `Stop`

, encoding the concept that the
resource allocation may fail to prevent the scope from being executed, and each individual scoped action may fail,
continuing the scope execution on resumption.
- The resource allocator is a plain action.

interpretScopedRWith :: forall extra param resource effect eo ei r. KnownList extra => (forall q x. param -> (resource -> Sem (extra ++ (Stop eo : (Opaque q : r))) x) -> Sem (Stop eo : (Opaque q : r)) x) -> (forall q r0 x. resource -> effect (Sem r0) x -> Sem (Stop ei : (extra ++ (Stop eo : (Opaque q : r)))) x) -> InterpreterFor (Scoped param (effect !! ei) !! eo) r Source #

Combined interpreter for `Scoped`

and `Resumable`

that allows the handler to use additional effects that are
interpreted by the resource allocator.
In this variant, both the handler and the scope may send different errors via `Stop`

, encoding the concept that the
resource allocation may fail to prevent the scope from being executed, and each individual scoped action may fail,
continuing the scope execution on resumption.

interpretScopedRWithH :: forall extra param resource effect eo ei r. KnownList extra => (forall q x. param -> (resource -> Sem (extra ++ (Stop eo : (Opaque q : r))) x) -> Sem (Stop eo : (Opaque q : r)) x) -> (forall q r0 x. resource -> effect (Sem r0) x -> Tactical (effect !! ei) (Sem r0) (Stop ei : (extra ++ (Stop eo : (Opaque q : r)))) x) -> InterpreterFor (Scoped param (effect !! ei) !! eo) r Source #

Combined higher-order interpreter for `Scoped`

and `Resumable`

that allows the handler to use additional effects
that are interpreted by the resource allocator.
In this variant, both the handler and the scope may send different errors via `Stop`

, encoding the concept that the
resource allocation may fail to prevent the scope from being executed, and each individual scoped action may fail,
continuing the scope execution on resumption.

interpretScopedRWith_ :: forall extra param effect eo ei r. KnownList extra => (forall q x. param -> Sem (extra ++ (Stop eo : (Opaque q : r))) x -> Sem (Stop eo : (Opaque q : r)) x) -> (forall q r0 x. effect (Sem r0) x -> Sem (Stop ei : (extra ++ (Stop eo : (Opaque q : r)))) x) -> InterpreterFor (Scoped param (effect !! ei) !! eo) r Source #

Combined interpreter for `Scoped`

and `Resumable`

that allows the handler to use additional effects that are
interpreted by the resource allocator.
- Both the handler and the scope may send different errors via `Stop`

, encoding the concept that the
resource allocation may fail to prevent the scope from being executed, and each individual scoped action may fail,
continuing the scope execution on resumption.
- The resource allocator is a plain action.

# Partial Handlers

In some cases, the errors thrown by an interpreter contain details about the implementation, which we might want to
hide from dependents; or it may throw fatal errors we don't want to handle at all.
For this purpose, we can create partial `Resumable`

s by transforming errors before handling them:

resumableOr :: forall (err :: Type) (eff :: Effect) unhandled handled r. Member (Error unhandled) r => (err -> Either unhandled handled) -> InterpreterFor eff (Stop err : r) -> InterpreterFor (Resumable handled eff) r Source #

Convert an interpreter for `eff`

that throws errors of type `err`

into a `Resumable`

, but limiting the errors
handled by consumers to the type `handled`

, which rethrowing `Error`

s of type `unhandled`

.

The function `canHandle`

determines how the errors are split.

newtype Blip = Blip { unBlip :: Int } deriving stock (Eq, Show) bangOnly :: Boom -> Either Text Blip bangOnly = \case Bang n -> Right (Blip n) Boom msg -> Left msg interpretResumerPartial :: Member (Resumable Blip Stopper) r => InterpreterFor Resumer r interpretResumerPartial = interpret \ MainProgram -> resume (192 <$ stopBang) \ (Blip num) -> pure (num * 3)

`>>>`

Right 39`runError (resumableFor bangOnly interpretStopper (interpretResumerPartial mainProgram))`

# Various Combinators

resumeAs :: forall err eff r a. Member (Resumable err eff) r => a -> Sem (eff : r) a -> Sem r a Source #

Variant of `resume`

that unconditionally recovers with a constant value.

(<!) :: forall err eff r a. Member (Resumable err eff) r => a -> Sem (eff : r) a -> Sem r a Source #

Operator version of `resumeAs`

.

*Since: 0.2.0.0*

(!>) :: forall err eff r a. Member (Resumable err eff) r => Sem (eff : r) a -> a -> Sem r a Source #

resumeWith :: forall err eff r a. Member (Resumable err eff) r => Sem (eff : r) a -> Sem r a -> Sem r a Source #

Variant of `resume`

that unconditionally recovers with an action.

*Since: 0.2.0.0*

(!>>) :: forall err eff r a. Member (Resumable err eff) r => Sem (eff : r) a -> Sem r a -> Sem r a Source #

Operator variant of `resumeWith`

.

*Since: 0.2.0.0*

resumingWith :: forall err eff r a. Member (Resumable err eff) r => Sem r a -> Sem (eff : r) a -> Sem r a Source #

Variant of `resuming`

that unconditionally recovers with an action.

*Since: 0.2.0.0*

(<<!) :: forall err eff r a. Member (Resumable err eff) r => Sem r a -> Sem (eff : r) a -> Sem r a Source #

Operator variant of `resumingWith`

.

*Since: 0.2.0.0*

resume_ :: forall err eff r. Member (Resumable err eff) r => Sem (eff : r) () -> Sem r () Source #

Convenience specialization of `resume`

that silently discards errors for void programs.

resumeHoist :: forall err eff err' r a. Members [Resumable err eff, Stop err'] r => (err -> err') -> Sem (eff : r) a -> Sem r a Source #

resumeHoistAs :: forall err eff err' r. Members [Resumable err eff, Stop err'] r => err' -> InterpreterFor eff r Source #

Variant of `resumeHoist`

that uses a constant value.

resuming :: forall err eff r a. Member (Resumable err eff) r => (err -> Sem r a) -> Sem (eff : r) a -> Sem r a Source #

Flipped variant of `resume`

.

resumeHoistError :: forall err eff err' r a. Members [Resumable err eff, Error err'] r => (err -> err') -> Sem (eff : r) a -> Sem r a Source #

resumeHoistErrorAs :: forall err eff err' r a. Members [Resumable err eff, Error err'] r => err' -> Sem (eff : r) a -> Sem r a Source #

Variant of `resumeHoistError`

that uses the unchanged error.

restop :: forall err eff r. Members [Resumable err eff, Stop err] r => InterpreterFor eff r Source #

Variant of `resumeHoist`

that uses the unchanged error.

resumeEither :: forall err eff r a. Member (Resumable err eff) r => Sem (eff : r) a -> Sem r (Either err a) Source #

resumeMaybe :: forall err eff r a. Member (Resumable err eff) r => Sem (eff : r) a -> Sem r (Maybe a) Source #

resumeOr :: forall err eff r a b. Member (Resumable err eff) r => Sem (eff : r) a -> (a -> Sem r b) -> (err -> Sem r b) -> Sem r b Source #

Variant of `resume`

that takes a branch for error and success.
This allows the success branch to contain other resumptions.

*Since: 0.2.0.0*

resumingOr :: forall err eff r a b. Member (Resumable err eff) r => (err -> Sem r b) -> Sem (eff : r) a -> (a -> Sem r b) -> Sem r b Source #

Variant of `resuming`

that takes a branch for error and success.
This allows the success branch to contain other resumptions.

*Since: 0.2.0.0*

resumeError :: forall err eff r a. Members [Resumable err eff, Error err] r => Sem (eff : r) a -> Sem r a Source #

Variant of `resumeHoistError`

that uses the unchanged error.

resumableError :: forall (err :: Type) (eff :: Effect) r. InterpreterFor eff (Error err : (Stop err : r)) -> InterpreterFor (Resumable err eff) r Source #

resumableFor :: forall (err :: Type) (eff :: Effect) handled r. Member (Error err) r => (err -> Maybe handled) -> InterpreterFor eff (Stop err : r) -> InterpreterFor (Resumable handled eff) r Source #

Variant of `resumableOr`

that uses `Maybe`

and rethrows the original error.

runAsResumable :: forall (err :: Type) (eff :: Effect) r. Members [Resumable err eff, Stop err] r => InterpreterFor eff r Source #

Interpret an effect `eff`

by wrapping it in `Resumable`

and `Stop`

and leaving the rest up to the user.

catchResumable :: forall (err :: Type) (eff :: Effect) handled r. Members [eff, Error err] r => (err -> Maybe handled) -> InterpreterFor (Resumable handled eff) r Source #

Reinterpreting variant of `resumableFor`

.

stopToFailWith :: forall err r. Member Fail r => (err -> Text) -> InterpreterFor (Stop err) r Source #

stopToFail :: forall err r. Show err => Member Fail r => InterpreterFor (Stop err) r Source #

resumeFailWith :: forall err eff r. Members [Fail, Resumable err eff] r => (err -> Text) -> InterpreterFor eff r Source #

resumeFail :: forall err eff r. Show err => Members [Fail, Resumable err eff] r => InterpreterFor eff r Source #

mapStop :: forall err e' r a. Member (Stop e') r => (err -> e') -> Sem (Stop err : r) a -> Sem r a Source #

Map over the error type in a `Stop`

.

replaceStop :: forall err e' r a. Member (Stop e') r => e' -> Sem (Stop err : r) a -> Sem r a Source #

Replace the error in a `Stop`

with another type.

showStop :: forall err r a. Show err => Member (Stop Text) r => Sem (Stop err : r) a -> Sem r a Source #

stopEither :: forall err r a. Member (Stop err) r => Either err a -> Sem r a Source #

Stop if the argument is `Left`

.

stopEitherAs :: forall err err' r a. Member (Stop err') r => err' -> Either err a -> Sem r a Source #

Stop if the argument is `Left`

, using the supplied error.

stopEitherWith :: forall err err' r a. Member (Stop err') r => (err -> err') -> Either err a -> Sem r a Source #

Stop if the argument is `Left`

, transforming the error with `f`

.

stopNote :: forall err r a. Member (Stop err) r => err -> Maybe a -> Sem r a Source #

Stop with the supplied error if the argument is `Nothing`

.

stopOnErrorWith :: forall err err' r a. Member (Stop err') r => (err -> err') -> Sem (Error err : r) a -> Sem r a Source #

stopToErrorIO :: forall err r a. Exception (StopExc err) => Members [Error err, Final IO] r => Sem (Stop err : r) a -> Sem r a Source #

stopToErrorWith :: forall err err' r a. Member (Error err') r => (err -> err') -> Sem (Stop err : r) a -> Sem r a Source #

stopToIOFinal :: forall err r a. Exception (StopExc err) => Member (Final IO) r => Sem (Stop err : r) a -> Sem r (Either err a) Source #

Run `Stop`

by throwing and catching exceptions.

stopTryAny :: forall err r a. Members [Stop err, Embed IO] r => (Text -> err) -> IO a -> Sem r a Source #

stopTryIO :: forall exc err r a. Exception exc => Members [Stop err, Embed IO] r => (Text -> err) -> IO a -> Sem r a Source #