packages feed

polysemy-resume 0.5.0.0 → 0.6.0.0

raw patch · 14 files changed

+1335/−606 lines, 14 filesdep −hedgehogdep −tasty-hedgehogdep −textdep ~incipit-coredep ~polysemydep ~polysemy-pluginPVP ok

version bump matches the API change (PVP)

Dependencies removed: hedgehog, tasty-hedgehog, text

Dependency ranges changed: incipit-core, polysemy, polysemy-plugin

API changes (from Hackage documentation)

- Polysemy.Resume.Resumable: catchResumable :: forall (err :: Type) (eff :: Effect) handled r. Members [eff, Error err] r => (err -> Maybe handled) -> InterpreterFor (Resumable handled eff) r
- Polysemy.Resume.Resumable: distribEither :: Functor f => f () -> (f (Either err a) -> res) -> Either err (f a) -> res
- Polysemy.Resume.Resumable: 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
- Polysemy.Resume.Resumable: 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
- Polysemy.Resume.Resumable: 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
- Polysemy.Resume.Resumable: 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
- Polysemy.Resume.Resumable: 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
- Polysemy.Resume.Resumable: 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
- Polysemy.Resume.Resumable: raiseResumable :: forall (err :: Type) (eff :: Effect) (r :: EffectRow). InterpreterTrans (Resumable err eff) eff r
- Polysemy.Resume.Resumable: resumable :: forall (err :: Type) (eff :: Effect) (r :: EffectRow). InterpreterFor eff (Stop err : r) -> InterpreterFor (Resumable err eff) r
- Polysemy.Resume.Resumable: resumableError :: forall (err :: Type) (eff :: Effect) r. InterpreterFor eff (Error err : (Stop err : r)) -> InterpreterFor (Resumable err eff) r
- Polysemy.Resume.Resumable: 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
- Polysemy.Resume.Resumable: 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
- Polysemy.Resume.Resumable: 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
- Polysemy.Resume.Resumable: runAsResumable :: forall (err :: Type) (eff :: Effect) r. Members [Resumable err eff, Stop err] r => InterpreterFor eff r
- Polysemy.Resume.Resumable: type InterpreterTrans eff eff' r = InterpreterTrans' eff eff' r r
- Polysemy.Resume.Resumable: type InterpreterTrans' eff eff' r r' = forall a b. (Sem (eff' : r') a -> Sem r b) -> Sem (eff : r) a -> Sem r b
- Polysemy.Resume.Stop: StopExc :: e -> StopExc e
- Polysemy.Resume.Stop: [$sel:unStopExc:StopExc] :: StopExc e -> e
- Polysemy.Resume.Stop: hush :: Either e a -> Maybe a
- Polysemy.Resume.Stop: instance Data.Typeable.Internal.Typeable e => GHC.Exception.Type.Exception (Polysemy.Resume.Stop.StopExc e)
- Polysemy.Resume.Stop: instance Data.Typeable.Internal.Typeable e => GHC.Show.Show (Polysemy.Resume.Stop.StopExc e)
- Polysemy.Resume.Stop: instance GHC.Exception.Type.Exception (Polysemy.Resume.Stop.StopExc Data.Text.Internal.Text)
- Polysemy.Resume.Stop: instance GHC.Show.Show (Polysemy.Resume.Stop.StopExc Data.Text.Internal.Text)
- Polysemy.Resume.Stop: mapStop :: forall e e' r a. Member (Stop e') r => (e -> e') -> Sem (Stop e : r) a -> Sem r a
- Polysemy.Resume.Stop: newtype StopExc e
- Polysemy.Resume.Stop: runStop :: Sem (Stop e : r) a -> Sem r (Either e a)
- Polysemy.Resume.Stop: runStopAsExcFinal :: Exception (StopExc e) => Member (Final IO) r => Sem (Stop e : r) a -> Sem r a
- Polysemy.Resume.Stop: showStop :: forall e r a. Show e => Member (Stop Text) r => Sem (Stop e : r) a -> Sem r a
- Polysemy.Resume.Stop: stopEither :: Member (Stop err) r => Either err a -> Sem r a
- Polysemy.Resume.Stop: stopEitherAs :: Member (Stop err') r => err' -> Either err a -> Sem r a
- Polysemy.Resume.Stop: stopEitherWith :: Member (Stop err') r => (err -> err') -> Either err a -> Sem r a
- Polysemy.Resume.Stop: stopNote :: Member (Stop err) r => err -> Maybe a -> Sem r a
- Polysemy.Resume.Stop: stopOnError :: Member (Stop err) r => Sem (Error err : r) a -> Sem r a
- Polysemy.Resume.Stop: stopOnErrorWith :: Member (Stop err') r => (err -> err') -> Sem (Error err : r) a -> Sem r a
- Polysemy.Resume.Stop: stopToError :: Member (Error err) r => Sem (Stop err : r) a -> Sem r a
- Polysemy.Resume.Stop: stopToErrorIO :: Exception (StopExc err) => Members [Error err, Final IO] r => Sem (Stop err : r) a -> Sem r a
- Polysemy.Resume.Stop: stopToErrorWith :: Member (Error err') r => (err -> err') -> Sem (Stop err : r) a -> Sem r a
- Polysemy.Resume.Stop: stopToIOFinal :: Exception (StopExc e) => Member (Final IO) r => Sem (Stop e : r) a -> Sem r (Either e a)
- Polysemy.Resume.Stop: stopTryAny :: forall e r a. Members [Stop e, Embed IO] r => (Text -> e) -> IO a -> Sem r a
- Polysemy.Resume.Stop: stopTryIO :: forall exc e r a. Exception exc => Members [Stop e, Embed IO] r => (Text -> e) -> IO a -> Sem r a
- Polysemy.Resume.Stop: stopTryIOE :: forall exc e r a. Exception exc => Members [Stop e, Embed IO] r => (exc -> e) -> IO a -> Sem r a
- Polysemy.Resume.Stop: stopTryIOError :: forall e r a. Members [Stop e, Embed IO] r => (Text -> e) -> IO a -> Sem r a
+ Polysemy.Resume: interpretResumableScoped :: forall param resource effect err r. (forall x. param -> (resource -> Sem r x) -> Sem r x) -> (forall r0 x. resource -> effect (Sem r0) x -> Sem (Stop err : r) x) -> InterpreterFor (Scoped param (effect !! err)) r
+ Polysemy.Resume: interpretResumableScopedH :: forall param resource effect err r. (forall x. param -> (resource -> Sem r x) -> Sem r x) -> (forall r0 x. resource -> effect (Sem r0) x -> Tactical (effect !! err) (Sem r0) (Stop err : r) x) -> InterpreterFor (Scoped param (effect !! err)) r
+ Polysemy.Resume: interpretResumableScopedWith :: forall extra param resource effect err r r1. r1 ~ (extra ++ r) => KnownList extra => (forall x. param -> (resource -> Sem r1 x) -> Sem r x) -> (forall r0 x. resource -> effect (Sem r0) x -> Sem (Stop err : r1) x) -> InterpreterFor (Scoped param (effect !! err)) r
+ Polysemy.Resume: interpretResumableScopedWithH :: forall extra param resource effect err r r1. r1 ~ (extra ++ r) => KnownList extra => (forall x. param -> (resource -> Sem r1 x) -> Sem r x) -> (forall r0 x. resource -> effect (Sem r0) x -> Tactical (effect !! err) (Sem r0) (Stop err : r1) x) -> InterpreterFor (Scoped param (effect !! err)) r
+ Polysemy.Resume: interpretResumableScopedWith_ :: forall extra param effect err r r1. r1 ~ (extra ++ r) => KnownList extra => (forall x. param -> Sem r1 x -> Sem r x) -> (forall r0 x. effect (Sem r0) x -> Sem (Stop err : r1) x) -> InterpreterFor (Scoped param (effect !! err)) r
+ Polysemy.Resume: interpretResumableScoped_ :: forall param resource effect err r. (param -> Sem r resource) -> (forall r0 x. resource -> effect (Sem r0) x -> Sem (Stop err : r) x) -> InterpreterFor (Scoped param (effect !! err)) r
+ Polysemy.Resume: interpretScopedR :: forall param resource effect eo ei r. (forall x. param -> (resource -> Sem (Stop eo : r) x) -> Sem (Stop eo : r) x) -> (forall r0 x. resource -> effect (Sem r0) x -> Sem (Stop ei : (Stop eo : r)) x) -> InterpreterFor (Scoped param (effect !! ei) !! eo) r
+ Polysemy.Resume: interpretScopedRH :: forall param resource effect eo ei r. (forall x. param -> (resource -> Sem (Stop eo : r) x) -> Sem (Stop eo : r) x) -> (forall r0 x. resource -> effect (Sem r0) x -> Tactical (effect !! ei) (Sem r0) (Stop ei : (Stop eo : r)) x) -> InterpreterFor (Scoped param (effect !! ei) !! eo) r
+ Polysemy.Resume: interpretScopedRWith :: forall extra param resource effect eo ei r r1. r1 ~ (extra ++ (Stop eo : r)) => r1 ~ ((extra ++ '[Stop eo]) ++ r) => KnownList (extra ++ '[Stop eo]) => (forall x. param -> (resource -> Sem r1 x) -> Sem (Stop eo : r) x) -> (forall r0 x. resource -> effect (Sem r0) x -> Sem (Stop ei : r1) x) -> InterpreterFor (Scoped param (effect !! ei) !! eo) r
+ Polysemy.Resume: interpretScopedRWithH :: forall extra param resource effect eo ei r r1 extraerr. extraerr ~ (extra ++ '[Stop eo]) => r1 ~ (extra ++ (Stop eo : r)) => r1 ~ ((extra ++ '[Stop eo]) ++ r) => KnownList (extra ++ '[Stop eo]) => (forall x. param -> (resource -> Sem (extra ++ (Stop eo : r)) x) -> Sem (Stop eo : r) x) -> (forall r0 x. resource -> effect (Sem r0) x -> Tactical (effect !! ei) (Sem r0) (Stop ei : r1) x) -> InterpreterFor (Scoped param (effect !! ei) !! eo) r
+ Polysemy.Resume: interpretScopedRWith_ :: forall extra param effect eo ei r r1. r1 ~ (extra ++ (Stop eo : r)) => r1 ~ ((extra ++ '[Stop eo]) ++ r) => KnownList (extra ++ '[Stop eo]) => (forall x. param -> Sem r1 x -> Sem (Stop eo : r) x) -> (forall r0 x. effect (Sem r0) x -> Sem (Stop ei : r1) x) -> InterpreterFor (Scoped param (effect !! ei) !! eo) r
+ Polysemy.Resume: interpretScopedR_ :: forall param resource effect eo ei r. (param -> Sem (Stop eo : r) resource) -> (forall r0 x. resource -> effect (Sem r0) x -> Sem (Stop ei : (Stop eo : r)) x) -> InterpreterFor (Scoped param (effect !! ei) !! eo) r
+ Polysemy.Resume: interpretScopedResumable :: forall param resource effect err r. (forall x. param -> (resource -> Sem (Stop err : r) x) -> Sem (Stop err : r) x) -> (forall r0 x. resource -> effect (Sem r0) x -> Sem (Stop err : r) x) -> InterpreterFor (Scoped param effect !! err) r
+ Polysemy.Resume: interpretScopedResumableH :: forall param resource effect err r. (forall x. param -> (resource -> Sem (Stop err : r) x) -> Sem (Stop err : r) x) -> (forall r0 x. resource -> effect (Sem r0) x -> Tactical effect (Sem r0) (Stop err : r) x) -> InterpreterFor (Scoped param effect !! err) r
+ Polysemy.Resume: interpretScopedResumableWith :: forall extra param resource effect err r r1. r1 ~ ((extra ++ '[Stop err]) ++ r) => KnownList (extra ++ '[Stop err]) => (forall x. param -> (resource -> Sem r1 x) -> Sem (Stop err : r) x) -> (forall r0 x. resource -> effect (Sem r0) x -> Sem r1 x) -> InterpreterFor (Scoped param effect !! err) r
+ Polysemy.Resume: interpretScopedResumableWithH :: forall extra param resource effect err r r1 extraerr. extraerr ~ (extra ++ '[Stop err]) => r1 ~ (extraerr ++ r) => KnownList (extra ++ '[Stop err]) => (forall x. param -> (resource -> Sem r1 x) -> Sem (Stop err : r) x) -> (forall r0 x. resource -> effect (Sem r0) x -> Tactical effect (Sem r0) r1 x) -> InterpreterFor (Scoped param effect !! err) r
+ Polysemy.Resume: interpretScopedResumableWith_ :: forall extra param effect err r r1. r1 ~ ((extra ++ '[Stop err]) ++ r) => KnownList (extra ++ '[Stop err]) => (forall x. param -> Sem r1 x -> Sem (Stop err : r) x) -> (forall r0 x. effect (Sem r0) x -> Sem r1 x) -> InterpreterFor (Scoped param effect !! err) r
+ Polysemy.Resume: interpretScopedResumable_ :: forall param resource effect err r. (param -> Sem (Stop err : r) resource) -> (forall r0 x. resource -> effect (Sem r0) x -> Sem (Stop err : r) x) -> InterpreterFor (Scoped param effect !! err) r
+ Polysemy.Resume: replaceStop :: forall err e' r a. Member (Stop e') r => e' -> Sem (Stop err : r) a -> Sem r a
+ Polysemy.Resume: resumeFail :: forall err eff r. Show err => Members [Fail, Resumable err eff] r => InterpreterFor eff r
+ Polysemy.Resume: resumeFailWith :: forall err eff r. Members [Fail, Resumable err eff] r => (err -> Text) -> InterpreterFor eff r
+ Polysemy.Resume: stopToFail :: forall err r. Show err => Member Fail r => InterpreterFor (Stop err) r
+ Polysemy.Resume: stopToFailWith :: forall err r. Member Fail r => (err -> Text) -> InterpreterFor (Stop err) r
+ Polysemy.Resume.Effect.Stop: stop :: forall e_a4mw r_a5B6 a_a4my. Member (Stop e_a4mw) r_a5B6 => e_a4mw -> Sem r_a5B6 a_a4my
+ Polysemy.Resume.Interpreter.Resumable: catchResumable :: forall (err :: Type) (eff :: Effect) handled r. Members [eff, Error err] r => (err -> Maybe handled) -> InterpreterFor (Resumable handled eff) r
+ Polysemy.Resume.Interpreter.Resumable: 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
+ Polysemy.Resume.Interpreter.Resumable: 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
+ Polysemy.Resume.Interpreter.Resumable: 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
+ Polysemy.Resume.Interpreter.Resumable: 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
+ Polysemy.Resume.Interpreter.Resumable: 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
+ Polysemy.Resume.Interpreter.Resumable: 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
+ Polysemy.Resume.Interpreter.Resumable: raiseResumable :: forall (err :: Type) (eff :: Effect) (r :: EffectRow). InterpreterTrans (Resumable err eff) eff r
+ Polysemy.Resume.Interpreter.Resumable: resumable :: forall (err :: Type) (eff :: Effect) (r :: EffectRow). InterpreterFor eff (Stop err : r) -> InterpreterFor (Resumable err eff) r
+ Polysemy.Resume.Interpreter.Resumable: resumableError :: forall (err :: Type) (eff :: Effect) r. InterpreterFor eff (Error err : (Stop err : r)) -> InterpreterFor (Resumable err eff) r
+ Polysemy.Resume.Interpreter.Resumable: 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
+ Polysemy.Resume.Interpreter.Resumable: 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
+ Polysemy.Resume.Interpreter.Resumable: 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
+ Polysemy.Resume.Interpreter.Resumable: runAsResumable :: forall (err :: Type) (eff :: Effect) r. Members [Resumable err eff, Stop err] r => InterpreterFor eff r
+ Polysemy.Resume.Interpreter.Scoped: interpretResumableScoped :: forall param resource effect err r. (forall x. param -> (resource -> Sem r x) -> Sem r x) -> (forall r0 x. resource -> effect (Sem r0) x -> Sem (Stop err : r) x) -> InterpreterFor (Scoped param (effect !! err)) r
+ Polysemy.Resume.Interpreter.Scoped: interpretResumableScopedH :: forall param resource effect err r. (forall x. param -> (resource -> Sem r x) -> Sem r x) -> (forall r0 x. resource -> effect (Sem r0) x -> Tactical (effect !! err) (Sem r0) (Stop err : r) x) -> InterpreterFor (Scoped param (effect !! err)) r
+ Polysemy.Resume.Interpreter.Scoped: interpretResumableScopedWith :: forall extra param resource effect err r r1. r1 ~ (extra ++ r) => KnownList extra => (forall x. param -> (resource -> Sem r1 x) -> Sem r x) -> (forall r0 x. resource -> effect (Sem r0) x -> Sem (Stop err : r1) x) -> InterpreterFor (Scoped param (effect !! err)) r
+ Polysemy.Resume.Interpreter.Scoped: interpretResumableScopedWithH :: forall extra param resource effect err r r1. r1 ~ (extra ++ r) => KnownList extra => (forall x. param -> (resource -> Sem r1 x) -> Sem r x) -> (forall r0 x. resource -> effect (Sem r0) x -> Tactical (effect !! err) (Sem r0) (Stop err : r1) x) -> InterpreterFor (Scoped param (effect !! err)) r
+ Polysemy.Resume.Interpreter.Scoped: interpretResumableScopedWith_ :: forall extra param effect err r r1. r1 ~ (extra ++ r) => KnownList extra => (forall x. param -> Sem r1 x -> Sem r x) -> (forall r0 x. effect (Sem r0) x -> Sem (Stop err : r1) x) -> InterpreterFor (Scoped param (effect !! err)) r
+ Polysemy.Resume.Interpreter.Scoped: interpretResumableScoped_ :: forall param resource effect err r. (param -> Sem r resource) -> (forall r0 x. resource -> effect (Sem r0) x -> Sem (Stop err : r) x) -> InterpreterFor (Scoped param (effect !! err)) r
+ Polysemy.Resume.Interpreter.Scoped: interpretScopedR :: forall param resource effect eo ei r. (forall x. param -> (resource -> Sem (Stop eo : r) x) -> Sem (Stop eo : r) x) -> (forall r0 x. resource -> effect (Sem r0) x -> Sem (Stop ei : (Stop eo : r)) x) -> InterpreterFor (Scoped param (effect !! ei) !! eo) r
+ Polysemy.Resume.Interpreter.Scoped: interpretScopedRH :: forall param resource effect eo ei r. (forall x. param -> (resource -> Sem (Stop eo : r) x) -> Sem (Stop eo : r) x) -> (forall r0 x. resource -> effect (Sem r0) x -> Tactical (effect !! ei) (Sem r0) (Stop ei : (Stop eo : r)) x) -> InterpreterFor (Scoped param (effect !! ei) !! eo) r
+ Polysemy.Resume.Interpreter.Scoped: interpretScopedRWith :: forall extra param resource effect eo ei r r1. r1 ~ (extra ++ (Stop eo : r)) => r1 ~ ((extra ++ '[Stop eo]) ++ r) => KnownList (extra ++ '[Stop eo]) => (forall x. param -> (resource -> Sem r1 x) -> Sem (Stop eo : r) x) -> (forall r0 x. resource -> effect (Sem r0) x -> Sem (Stop ei : r1) x) -> InterpreterFor (Scoped param (effect !! ei) !! eo) r
+ Polysemy.Resume.Interpreter.Scoped: interpretScopedRWithH :: forall extra param resource effect eo ei r r1 extraerr. extraerr ~ (extra ++ '[Stop eo]) => r1 ~ (extra ++ (Stop eo : r)) => r1 ~ ((extra ++ '[Stop eo]) ++ r) => KnownList (extra ++ '[Stop eo]) => (forall x. param -> (resource -> Sem (extra ++ (Stop eo : r)) x) -> Sem (Stop eo : r) x) -> (forall r0 x. resource -> effect (Sem r0) x -> Tactical (effect !! ei) (Sem r0) (Stop ei : r1) x) -> InterpreterFor (Scoped param (effect !! ei) !! eo) r
+ Polysemy.Resume.Interpreter.Scoped: interpretScopedRWith_ :: forall extra param effect eo ei r r1. r1 ~ (extra ++ (Stop eo : r)) => r1 ~ ((extra ++ '[Stop eo]) ++ r) => KnownList (extra ++ '[Stop eo]) => (forall x. param -> Sem r1 x -> Sem (Stop eo : r) x) -> (forall r0 x. effect (Sem r0) x -> Sem (Stop ei : r1) x) -> InterpreterFor (Scoped param (effect !! ei) !! eo) r
+ Polysemy.Resume.Interpreter.Scoped: interpretScopedR_ :: forall param resource effect eo ei r. (param -> Sem (Stop eo : r) resource) -> (forall r0 x. resource -> effect (Sem r0) x -> Sem (Stop ei : (Stop eo : r)) x) -> InterpreterFor (Scoped param (effect !! ei) !! eo) r
+ Polysemy.Resume.Interpreter.Scoped: interpretScopedResumable :: forall param resource effect err r. (forall x. param -> (resource -> Sem (Stop err : r) x) -> Sem (Stop err : r) x) -> (forall r0 x. resource -> effect (Sem r0) x -> Sem (Stop err : r) x) -> InterpreterFor (Scoped param effect !! err) r
+ Polysemy.Resume.Interpreter.Scoped: interpretScopedResumableH :: forall param resource effect err r. (forall x. param -> (resource -> Sem (Stop err : r) x) -> Sem (Stop err : r) x) -> (forall r0 x. resource -> effect (Sem r0) x -> Tactical effect (Sem r0) (Stop err : r) x) -> InterpreterFor (Scoped param effect !! err) r
+ Polysemy.Resume.Interpreter.Scoped: interpretScopedResumableWith :: forall extra param resource effect err r r1. r1 ~ ((extra ++ '[Stop err]) ++ r) => KnownList (extra ++ '[Stop err]) => (forall x. param -> (resource -> Sem r1 x) -> Sem (Stop err : r) x) -> (forall r0 x. resource -> effect (Sem r0) x -> Sem r1 x) -> InterpreterFor (Scoped param effect !! err) r
+ Polysemy.Resume.Interpreter.Scoped: interpretScopedResumableWithH :: forall extra param resource effect err r r1 extraerr. extraerr ~ (extra ++ '[Stop err]) => r1 ~ (extraerr ++ r) => KnownList (extra ++ '[Stop err]) => (forall x. param -> (resource -> Sem r1 x) -> Sem (Stop err : r) x) -> (forall r0 x. resource -> effect (Sem r0) x -> Tactical effect (Sem r0) r1 x) -> InterpreterFor (Scoped param effect !! err) r
+ Polysemy.Resume.Interpreter.Scoped: interpretScopedResumableWith_ :: forall extra param effect err r r1. r1 ~ ((extra ++ '[Stop err]) ++ r) => KnownList (extra ++ '[Stop err]) => (forall x. param -> Sem r1 x -> Sem (Stop err : r) x) -> (forall r0 x. effect (Sem r0) x -> Sem r1 x) -> InterpreterFor (Scoped param effect !! err) r
+ Polysemy.Resume.Interpreter.Scoped: interpretScopedResumable_ :: forall param resource effect err r. (param -> Sem (Stop err : r) resource) -> (forall r0 x. resource -> effect (Sem r0) x -> Sem (Stop err : r) x) -> InterpreterFor (Scoped param effect !! err) r
+ Polysemy.Resume.Interpreter.Stop: StopExc :: err -> StopExc err
+ Polysemy.Resume.Interpreter.Stop: [$sel:unStopExc:StopExc] :: StopExc err -> err
+ Polysemy.Resume.Interpreter.Stop: instance Data.Typeable.Internal.Typeable err => GHC.Exception.Type.Exception (Polysemy.Resume.Interpreter.Stop.StopExc err)
+ Polysemy.Resume.Interpreter.Stop: instance Data.Typeable.Internal.Typeable err => GHC.Show.Show (Polysemy.Resume.Interpreter.Stop.StopExc err)
+ Polysemy.Resume.Interpreter.Stop: instance GHC.Exception.Type.Exception (Polysemy.Resume.Interpreter.Stop.StopExc Data.Text.Internal.Text)
+ Polysemy.Resume.Interpreter.Stop: instance GHC.Show.Show (Polysemy.Resume.Interpreter.Stop.StopExc Data.Text.Internal.Text)
+ Polysemy.Resume.Interpreter.Stop: mapStop :: forall err e' r a. Member (Stop e') r => (err -> e') -> Sem (Stop err : r) a -> Sem r a
+ Polysemy.Resume.Interpreter.Stop: newtype StopExc err
+ Polysemy.Resume.Interpreter.Stop: replaceStop :: forall err e' r a. Member (Stop e') r => e' -> Sem (Stop err : r) a -> Sem r a
+ Polysemy.Resume.Interpreter.Stop: runStop :: Sem (Stop err : r) a -> Sem r (Either err a)
+ Polysemy.Resume.Interpreter.Stop: runStopAsExcFinal :: forall err r a. Exception (StopExc err) => Member (Final IO) r => Sem (Stop err : r) a -> Sem r a
+ Polysemy.Resume.Interpreter.Stop: showStop :: forall err r a. Show err => Member (Stop Text) r => Sem (Stop err : r) a -> Sem r a
+ Polysemy.Resume.Interpreter.Stop: stopEither :: forall err r a. Member (Stop err) r => Either err a -> Sem r a
+ Polysemy.Resume.Interpreter.Stop: stopEitherAs :: forall err err' r a. Member (Stop err') r => err' -> Either err a -> Sem r a
+ Polysemy.Resume.Interpreter.Stop: stopEitherWith :: forall err err' r a. Member (Stop err') r => (err -> err') -> Either err a -> Sem r a
+ Polysemy.Resume.Interpreter.Stop: stopNote :: forall err r a. Member (Stop err) r => err -> Maybe a -> Sem r a
+ Polysemy.Resume.Interpreter.Stop: stopOnError :: forall err r a. Member (Stop err) r => Sem (Error err : r) a -> Sem r a
+ Polysemy.Resume.Interpreter.Stop: stopOnErrorWith :: forall err err' r a. Member (Stop err') r => (err -> err') -> Sem (Error err : r) a -> Sem r a
+ Polysemy.Resume.Interpreter.Stop: stopToError :: forall err r a. Member (Error err) r => Sem (Stop err : r) a -> Sem r a
+ Polysemy.Resume.Interpreter.Stop: stopToErrorIO :: forall err r a. Exception (StopExc err) => Members [Error err, Final IO] r => Sem (Stop err : r) a -> Sem r a
+ Polysemy.Resume.Interpreter.Stop: stopToErrorWith :: forall err err' r a. Member (Error err') r => (err -> err') -> Sem (Stop err : r) a -> Sem r a
+ Polysemy.Resume.Interpreter.Stop: stopToIOFinal :: forall err r a. Exception (StopExc err) => Member (Final IO) r => Sem (Stop err : r) a -> Sem r (Either err a)
+ Polysemy.Resume.Interpreter.Stop: stopTryAny :: forall err r a. Members [Stop err, Embed IO] r => (Text -> err) -> IO a -> Sem r a
+ Polysemy.Resume.Interpreter.Stop: stopTryIO :: forall exc err r a. Exception exc => Members [Stop err, Embed IO] r => (Text -> err) -> IO a -> Sem r a
+ Polysemy.Resume.Interpreter.Stop: stopTryIOE :: forall exc err r a. Exception exc => Members [Stop err, Embed IO] r => (exc -> err) -> IO a -> Sem r a
+ Polysemy.Resume.Interpreter.Stop: stopTryIOError :: forall err r a. Members [Stop err, Embed IO] r => (Text -> err) -> IO a -> Sem r a
+ Polysemy.Resume.Resume: resumeFail :: forall err eff r. Show err => Members [Fail, Resumable err eff] r => InterpreterFor eff r
+ Polysemy.Resume.Resume: resumeFailWith :: forall err eff r. Members [Fail, Resumable err eff] r => (err -> Text) -> InterpreterFor eff r
+ Polysemy.Resume.Resume: stopToFail :: forall err r. Show err => Member Fail r => InterpreterFor (Stop err) r
+ Polysemy.Resume.Resume: stopToFailWith :: forall err r. Member Fail r => (err -> Text) -> InterpreterFor (Stop err) r
- Polysemy.Resume: mapStop :: forall e e' r a. Member (Stop e') r => (e -> e') -> Sem (Stop e : r) a -> Sem r a
+ Polysemy.Resume: mapStop :: forall err e' r a. Member (Stop e') r => (err -> e') -> Sem (Stop err : r) a -> Sem r a
- Polysemy.Resume: runStop :: Sem (Stop e : r) a -> Sem r (Either e a)
+ Polysemy.Resume: runStop :: Sem (Stop err : r) a -> Sem r (Either err a)
- Polysemy.Resume: showStop :: forall e r a. Show e => Member (Stop Text) r => Sem (Stop e : r) a -> Sem r a
+ Polysemy.Resume: showStop :: forall err r a. Show err => Member (Stop Text) r => Sem (Stop err : r) a -> Sem r a
- Polysemy.Resume: stop :: forall e_a4Ag r_a5Os a_a4Ai. MemberWithError (Stop e_a4Ag) r_a5Os => e_a4Ag -> Sem r_a5Os a_a4Ai
+ Polysemy.Resume: stop :: forall e_a4mw r_a5B6 a_a4my. Member (Stop e_a4mw) r_a5B6 => e_a4mw -> Sem r_a5B6 a_a4my
- Polysemy.Resume: stopEither :: Member (Stop err) r => Either err a -> Sem r a
+ Polysemy.Resume: stopEither :: forall err r a. Member (Stop err) r => Either err a -> Sem r a
- Polysemy.Resume: stopEitherAs :: Member (Stop err') r => err' -> Either err a -> Sem r a
+ Polysemy.Resume: stopEitherAs :: forall err err' r a. Member (Stop err') r => err' -> Either err a -> Sem r a
- Polysemy.Resume: stopEitherWith :: Member (Stop err') r => (err -> err') -> Either err a -> Sem r a
+ Polysemy.Resume: stopEitherWith :: forall err err' r a. Member (Stop err') r => (err -> err') -> Either err a -> Sem r a
- Polysemy.Resume: stopNote :: Member (Stop err) r => err -> Maybe a -> Sem r a
+ Polysemy.Resume: stopNote :: forall err r a. Member (Stop err) r => err -> Maybe a -> Sem r a
- Polysemy.Resume: stopOnError :: Member (Stop err) r => Sem (Error err : r) a -> Sem r a
+ Polysemy.Resume: stopOnError :: forall err r a. Member (Stop err) r => Sem (Error err : r) a -> Sem r a
- Polysemy.Resume: stopOnErrorWith :: Member (Stop err') r => (err -> err') -> Sem (Error err : r) a -> Sem r a
+ Polysemy.Resume: stopOnErrorWith :: forall err err' r a. Member (Stop err') r => (err -> err') -> Sem (Error err : r) a -> Sem r a
- Polysemy.Resume: stopToError :: Member (Error err) r => Sem (Stop err : r) a -> Sem r a
+ Polysemy.Resume: stopToError :: forall err r a. Member (Error err) r => Sem (Stop err : r) a -> Sem r a
- Polysemy.Resume: stopToErrorWith :: Member (Error err') r => (err -> err') -> Sem (Stop err : r) a -> Sem r a
+ Polysemy.Resume: stopToErrorWith :: forall err err' r a. Member (Error err') r => (err -> err') -> Sem (Stop err : r) a -> Sem r a
- Polysemy.Resume: stopToIOFinal :: Exception (StopExc e) => Member (Final IO) r => Sem (Stop e : r) a -> Sem r (Either e a)
+ Polysemy.Resume: stopToIOFinal :: forall err r a. Exception (StopExc err) => Member (Final IO) r => Sem (Stop err : r) a -> Sem r (Either err a)
- Polysemy.Resume: stopTryAny :: forall e r a. Members [Stop e, Embed IO] r => (Text -> e) -> IO a -> Sem r a
+ Polysemy.Resume: stopTryAny :: forall err r a. Members [Stop err, Embed IO] r => (Text -> err) -> IO a -> Sem r a
- Polysemy.Resume: stopTryIO :: forall exc e r a. Exception exc => Members [Stop e, Embed IO] r => (Text -> e) -> IO a -> Sem r a
+ Polysemy.Resume: stopTryIO :: forall exc err r a. Exception exc => Members [Stop err, Embed IO] r => (Text -> err) -> IO a -> Sem r a
- Polysemy.Resume: stopTryIOE :: forall exc e r a. Exception exc => Members [Stop e, Embed IO] r => (exc -> e) -> IO a -> Sem r a
+ Polysemy.Resume: stopTryIOE :: forall exc err r a. Exception exc => Members [Stop err, Embed IO] r => (exc -> err) -> IO a -> Sem r a
- Polysemy.Resume: stopTryIOError :: forall e r a. Members [Stop e, Embed IO] r => (Text -> e) -> IO a -> Sem r a
+ Polysemy.Resume: stopTryIOError :: forall err r a. Members [Stop err, Embed IO] r => (Text -> err) -> IO a -> Sem r a

Files

+ changelog.md view
@@ -0,0 +1,30 @@+# Unreleased++# 0.6.0.0++* Add `replaceStop`, shorthand for `mapStop . const`.+* Add `∀` to `Stop` interpreters.+* Add resumers that transform to `Fail`.+* Move `Scoped` interpreters from `polysemy-conc`, since `Scoped` is now in `polysemy`.+* Support GHC 9.4.++# 0.5.0.0++* Add interceptors.+* Change modules for effects to `Polysemy.Resume.Effect`.+* Add `stopEitherAs`.+* Add exception catching `stop` combinators.++# 0.2.0.0++* Add combinators `resumeOr` and `resumingOr`, which take an additional branch for the success case.+* Improve `raiseResumable`:+  * Don't discard resources+  * Allow interpreter to change type of `a`+* Add operator versions of `resume` (`!!`) and `resumeAs` (`<!`), (`!>`).+* Add combinators `resumeWith` and `resumingWith` that ignore the error and execute an action, plus their operator+  variants `(!>>)` and `(<<!)`.++# 0.1.0.0++* initial release
lib/Polysemy/Resume.hs view
@@ -1,3 +1,4 @@+-- | Description: Polysemy effects for cross-interpreter error tracking. module Polysemy.Resume (   -- * Introduction   -- $intro@@ -15,6 +16,24 @@   resumable,   raiseResumable,   resumableIO,+  interpretScopedResumable,+  interpretScopedResumableH,+  interpretScopedResumable_,+  interpretScopedResumableWith,+  interpretScopedResumableWithH,+  interpretScopedResumableWith_,+  interpretResumableScoped,+  interpretResumableScopedH,+  interpretResumableScoped_,+  interpretResumableScopedWith,+  interpretResumableScopedWithH,+  interpretResumableScopedWith_,+  interpretScopedR,+  interpretScopedRH,+  interpretScopedR_,+  interpretScopedRWith,+  interpretScopedRWithH,+  interpretScopedRWith_,   -- * Partial Handlers   -- $partial   resumableOr,@@ -41,12 +60,36 @@   resumableFor,   runAsResumable,   catchResumable,-  module Polysemy.Resume.Stop,+  stopToFailWith,+  stopToFail,+  resumeFailWith,+  resumeFail,+  module Polysemy.Resume.Interpreter.Stop, ) where  import Polysemy.Resume.Effect.Resumable (Resumable, type (!!)) import Polysemy.Resume.Effect.Stop (Stop (..), stop)-import Polysemy.Resume.Resumable (+import Polysemy.Resume.Interpreter.Scoped (+  interpretResumableScoped,+  interpretResumableScopedH,+  interpretResumableScopedWith,+  interpretResumableScopedWithH,+  interpretResumableScopedWith_,+  interpretResumableScoped_,+  interpretScopedR,+  interpretScopedRH,+  interpretScopedRWith,+  interpretScopedRWithH,+  interpretScopedRWith_,+  interpretScopedR_,+  interpretScopedResumable,+  interpretScopedResumableH,+  interpretScopedResumableWith,+  interpretScopedResumableWithH,+  interpretScopedResumableWith_,+  interpretScopedResumable_,+  )+import Polysemy.Resume.Interpreter.Resumable (   catchResumable,   interceptResumable,   interceptResumableH,@@ -68,6 +111,8 @@   resumeAs,   resumeEither,   resumeError,+  resumeFail,+  resumeFailWith,   resumeHoist,   resumeHoistAs,   resumeHoistError,@@ -78,14 +123,17 @@   resuming,   resumingOr,   resumingWith,+  stopToFail,+  stopToFailWith,   (!!),   (!>),   (!>>),   (<!),   (<<!),   )-import Polysemy.Resume.Stop (+import Polysemy.Resume.Interpreter.Stop (   mapStop,+  replaceStop,   runStop,   showStop,   stopEither,@@ -97,10 +145,10 @@   stopToError,   stopToErrorWith,   stopToIOFinal,-  stopTryIOE,+  stopTryAny,   stopTryIO,+  stopTryIOE,   stopTryIOError,-  stopTryAny,   )  -- $intro@@ -133,7 +181,7 @@ -- -- 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 'Polysemy.Error.Error' to 'Stop' and wrapping 'Stopper' in+-- This library makes the connection explicit by changing 'Polysemy.Error.Error' to 'Stop' and wrapping @Stopper@ in -- 'Resumable' when using it in an effect stack:  -- $partial
lib/Polysemy/Resume/Effect/Resumable.hs view
@@ -1,3 +1,4 @@+-- |Description: The 'Resumable' effect. module Polysemy.Resume.Effect.Resumable where  import Polysemy.Internal.Union (Weaving)
lib/Polysemy/Resume/Effect/Stop.hs view
@@ -1,6 +1,6 @@ {-# options_haddock prune #-} --- |Description: Internal+-- |Description: The 'Stop' effect. module Polysemy.Resume.Effect.Stop where  -- |An effect similar to 'Polysemy.Error.Error' without the ability to be caught.
+ lib/Polysemy/Resume/Interpreter/Resumable.hs view
@@ -0,0 +1,329 @@+{-# options_haddock prune #-}+{-# options_ghc -Wno-redundant-constraints #-}++-- | Description: Interpreters for 'Resumable'.+module Polysemy.Resume.Interpreter.Resumable where++import Polysemy.Error (Error (Throw))+import Polysemy.Internal (Sem (Sem, runSem), liftSem, usingSem)+import Polysemy.Internal.CustomErrors (FirstOrder)+import Polysemy.Internal.Tactics (liftT, runTactics)+import Polysemy.Internal.Union (ElemOf, Weaving (Weaving), decomp, hoist, inj, injWeaving, membership, prjUsing, weave)++import Polysemy.Resume.Effect.Resumable (Resumable (..))+import Polysemy.Resume.Effect.Stop (Stop, stop)+import Polysemy.Resume.Interpreter.Stop (StopExc, runStop, stopOnError, stopToIOFinal)++type InterpreterTrans' eff eff' r r' =+  ∀ a b .+  (Sem (eff' : r') a -> Sem r b) ->+  Sem (eff : r) a ->+  Sem r b++type InterpreterTrans eff eff' r =+  InterpreterTrans' eff eff' r r++distribEither ::+  Functor f =>+  f () ->+  (f (Either err a) -> res) ->+  Either err (f a) ->+  res+distribEither initialState result =+  result . \case+    Right fa -> Right <$> fa+    Left err -> Left err <$ initialState+{-# inline distribEither #-}++-- | 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'.+--+-- >>> run $ resumable interpretStopper (interpretResumer mainProgram)+-- 237+resumable ::+  ∀ (err :: Type) (eff :: Effect) (r :: EffectRow) .+  InterpreterFor eff (Stop err : r) ->+  InterpreterFor (Resumable err eff) r+resumable interpreter (Sem m) =+  Sem \ k -> m \ u ->+    case decomp (hoist (resumable interpreter) u) of+      Right (Weaving (Resumable e) s wv ex ins) ->+        distribEither s ex <$> runSem resultFromEff k+        where+          resultFromEff =+            runStop $ interpreter $ liftSem $ weave s (raise . raise . wv) ins (injWeaving e)+      Left g ->+        k g+{-# inline resumable #-}++-- | Convenience combinator for turning an interpreter that doesn't use 'Stop' into a 'Resumable'.+raiseResumable ::+  ∀ (err :: Type) (eff :: Effect) (r :: EffectRow) .+  InterpreterTrans (Resumable err eff) eff r+raiseResumable interpreter =+  interpreter . normalize . raiseUnder+  where+    normalize :: InterpreterFor (Resumable err eff) (eff : r)+    normalize (Sem m) =+      Sem \ k -> m \ u ->+        case decomp (hoist normalize u) of+          Right (Weaving (Resumable e) s wv ex ins) ->+            ex . fmap Right <$> (usingSem k $ liftSem $ weave s wv ins (injWeaving e))+          Left g ->+            k g+    {-# inline normalize #-}+{-# inline raiseResumable #-}++-- | Like 'resumable', but use exceptions instead of 'Control.Monad.Trans.ExceptT'.+resumableIO ::+  ∀ (err :: Type) (eff :: Effect) (r :: EffectRow) .+  Exception (StopExc err) =>+  Member (Final IO) r =>+  InterpreterFor eff (Stop err : r) ->+  InterpreterFor (Resumable err eff) r+resumableIO interpreter (Sem m) =+  Sem \ k -> m \ u ->+    case decomp (hoist (resumable interpreter) u) of+      Right (Weaving (Resumable e) s wv ex ins) ->+        distribEither s ex <$> runSem resultFromEff k+        where+          resultFromEff =+            stopToIOFinal $ interpreter $ liftSem $ weave s (raise . raise . wv) ins (injWeaving e)+      Left g ->+        k g+{-# inline resumableIO #-}++-- | Like 'interpretResumable', but for higher-order effects.+interpretResumableH ::+  ∀ (err :: Type) (eff :: Effect) (r :: EffectRow) .+  -- | This handler function has @'Stop' err@ in its stack, allowing it to absorb errors.+  (∀ x r0 . eff (Sem r0) x -> Tactical (Resumable err eff) (Sem r0) (Stop err : r) x) ->+  InterpreterFor (Resumable err eff) r+interpretResumableH handler (Sem m) =+  Sem \ k -> m \ u ->+    case decomp u of+      Left there ->+        k (hoist (interpretResumableH handler) there)+      Right (Weaving (Resumable (Weaving e s dist ex ins)) sOuter distOuter exOuter insOuter) ->+        usingSem k (exFinal <$> runStop (tac (handler e)))+        where+          tac =+            runTactics+            (Compose (s <$ sOuter))+            (raiseUnder . fmap Compose . distOuter . fmap dist . getCompose)+            (ins <=< insOuter . getCompose)+            (raise . interpretResumableH handler . fmap Compose . distOuter . fmap dist . getCompose)+          exFinal = exOuter . \case+            Right (Compose a) -> Right . ex <$> a+            Left err -> Left err <$ sOuter+{-# inline interpretResumableH #-}++-- | Create an interpreter for @'Resumable' err eff@ by supplying a handler function for @eff@, analogous to+-- 'Polysemy.interpret'.+-- If the handler throws errors with 'Stop', they will be absorbed into 'Resumable', to be caught by+-- 'Polysemy.Resume.resume' in a downstream interpreter.+--+-- @+-- interpretStopperResumable ::+--   InterpreterFor Stopper r+-- interpretStopperResumable =+--   interpretResumable \\case+--     StopBang -> stop (Bang 13)+--     StopBoom -> stop (Boom "ouch")+-- @+--+-- >>> run $ interpretStopperResumable (interpretResumer mainProgram)+-- 237+interpretResumable ::+  ∀ (err :: Type) (eff :: Effect) r .+  FirstOrder eff "interpretResumable" =>+  (∀ x r0 . eff (Sem r0) x -> Sem (Stop err : r) x) ->+  InterpreterFor (Resumable err eff) r+interpretResumable handler =+  interpretResumableH \ e -> liftT (handler e)+{-# inline interpretResumable #-}++-- | Interceptor variant of 'interpretResumableH'.+interceptResumableUsingH ::+  ∀ (err :: Type) (eff :: Effect) (r :: EffectRow) (a :: Type) .+  ElemOf (Resumable err eff) r ->+  (∀ x r0 . eff (Sem r0) x -> Tactical (Resumable err eff) (Sem r0) (Stop err : r) x) ->+  Sem r a ->+  Sem r a+interceptResumableUsingH proof handler (Sem m) =+  Sem \ k -> m \ u ->+    case prjUsing proof u of+      Nothing ->+        k (hoist (interceptResumableUsingH proof handler) u)+      Just (Weaving (Resumable (Weaving e s dist ex ins)) sOuter distOuter exOuter insOuter) ->+        usingSem k (exFinal <$> runStop (tac (handler e)))+        where+          tac =+            runTactics+            (Compose (s <$ sOuter))+            (raise . raise . fmap Compose . distOuter . fmap dist . getCompose)+            (ins <=< insOuter . getCompose)+            (raise . interceptResumableUsingH proof handler . fmap Compose . distOuter . fmap dist . getCompose)+          exFinal = exOuter . \case+            Right (Compose a) -> Right . ex <$> a+            Left err -> Left err <$ sOuter+{-# inline interceptResumableUsingH #-}++-- | Interceptor variant of 'interpretResumable'.+interceptResumableUsing ::+  ∀ (err :: Type) (eff :: Effect) (r :: EffectRow) (a :: Type) .+  FirstOrder eff "interceptResumableUsing" =>+  ElemOf (Resumable err eff) r ->+  (∀ x r0 . eff (Sem r0) x -> Sem (Stop err : r) x) ->+  Sem r a ->+  Sem r a+interceptResumableUsing proof f =+  interceptResumableUsingH proof \ e ->+    liftT (f e)+{-# inline interceptResumableUsing #-}++-- | Interceptor variant of 'interpretResumableH'.+interceptResumableH ::+  ∀ (err :: Type) (eff :: Effect) (r :: EffectRow) (a :: Type) .+  Member (Resumable err eff) r =>+  (∀ x r0 . eff (Sem r0) x -> Tactical (Resumable err eff) (Sem r0) (Stop err : r) x) ->+  Sem r a ->+  Sem r a+interceptResumableH =+  interceptResumableUsingH membership+{-# inline interceptResumableH #-}++-- | Interceptor variant of 'interpretResumable'.+interceptResumable ::+  ∀ (err :: Type) (eff :: Effect) (r :: EffectRow) (a :: Type) .+  Member (Resumable err eff) r =>+  FirstOrder eff "interceptResumable" =>+  (∀ x r0 . eff (Sem r0) x -> Sem (Stop err : r) x) ->+  Sem r a ->+  Sem r a+interceptResumable f =+  interceptResumableH \ e ->+    liftT (f e)+{-# inline interceptResumable #-}++-- | Convert an interpreter for @eff@ that uses 'Error' into one using 'Stop' and wrap it using 'resumable'.+resumableError ::+  ∀ (err :: Type) (eff :: Effect) r .+  InterpreterFor eff (Error err : Stop err : r) ->+  InterpreterFor (Resumable err eff) r+resumableError interpreter =+  resumable (stopOnError . interpreter . raiseUnder)+{-# inline resumableError #-}++-- | 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 (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)+-- @+--+-- >>> runError (resumableFor bangOnly interpretStopper (interpretResumerPartial mainProgram))+-- Right 39+resumableOr ::+  ∀ (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+resumableOr canHandle interpreter (Sem m) =+  Sem \ k -> m \ u ->+    case decomp (hoist (resumableOr canHandle interpreter) u) of+      Right (Weaving (Resumable e) s wv ex ins) ->+        distribEither s ex <$> (tryHandle =<< runSem resultFromEff k)+        where+          tryHandle = \case+            Left err ->+              either (k . inj . Throw) (pure . Left) (canHandle err)+            Right a ->+              pure (Right a)+          resultFromEff =+            runStop $ interpreter $ liftSem $ weave s (raise . raise . wv) ins (injWeaving e)+      Left g ->+        k g+{-# inline resumableOr #-}++-- | Variant of 'resumableOr' that uses 'Maybe' and rethrows the original error.+resumableFor ::+  ∀ (err :: Type) (eff :: Effect) handled r .+  Member (Error err) r =>+  (err -> Maybe handled) ->+  InterpreterFor eff (Stop err : r) ->+  InterpreterFor (Resumable handled eff) r+resumableFor canHandle =+  resumableOr canHandle'+  where+    canHandle' err =+      maybeToRight err (canHandle err)+{-# inline resumableFor #-}++-- | Reinterpreting variant of 'resumableFor'.+catchResumable ::+  ∀ (err :: Type) (eff :: Effect) handled r .+  Members [eff, Error err] r =>+  (err -> Maybe handled) ->+  InterpreterFor (Resumable handled eff) r+catchResumable canHandle (Sem m) =+  Sem \ k -> m \ u ->+    case decomp (hoist (catchResumable canHandle) u) of+      Right (Weaving (Resumable e) s wv ex ins) ->+        distribEither s ex <$> runSem resultFromEff k+        where+          resultFromEff =+            catchJust canHandle (fmap Right $ liftSem $ weave s wv ins (injWeaving e)) (pure . Left)+      Left g ->+        k g+{-# inline catchResumable #-}++-- | Interpret an effect @eff@ by wrapping it in @Resumable@ and @Stop@ and leaving the rest up to the user.+runAsResumable ::+  ∀ (err :: Type) (eff :: Effect) r .+  Members [Resumable err eff, Stop err] r =>+  InterpreterFor eff r+runAsResumable (Sem m) =+  Sem \ k -> m \ u ->+    case decomp (hoist (runAsResumable @err @eff) u) of+      Right wav ->+        runSem (either (stop @err) pure =<< send (Resumable wav)) k+      Left g ->+        k g+{-# inline runAsResumable #-}
+ lib/Polysemy/Resume/Interpreter/Scoped.hs view
@@ -0,0 +1,374 @@+{-# options_haddock prune #-}++-- |Description: Interpreters for 'Scoped' in combination with 'Resumable'+--+-- @since 0.6.0.0+module Polysemy.Resume.Interpreter.Scoped where++import GHC.Err (errorWithoutStackTrace)+import Polysemy.Internal (liftSem, restack)+import Polysemy.Internal.Combinators (interpretWeaving)+import Polysemy.Internal.Scoped (Scoped (InScope, Run))+import Polysemy.Internal.Sing (KnownList (singList))+import Polysemy.Internal.Tactics (liftT)+import Polysemy.Internal.Union (Weaving (Weaving), extendMembershipLeft, injWeaving, injectMembership, weave)++import Polysemy.Resume.Effect.Resumable (Resumable (Resumable), type (!!))+import Polysemy.Resume.Effect.Stop (Stop)+import Polysemy.Resume.Interpreter.Resumable (interpretResumableH)+import Polysemy.Resume.Interpreter.Stop (runStop)++exResumable ::+  Functor f =>+  f () ->+  (f (Either err a) -> x) ->+  (f' a' -> a) ->+  Sem r (Either err (f (f' a'))) ->+  Sem r x+exResumable s ex ex' =+  fmap $ ex . \case+    Right a -> Right . ex' <$> a+    Left err -> Left err <$ s+{-# inline exResumable #-}++-- |Combined higher-order interpreter for 'Scoped' and 'Resumable'.+-- This allows 'Stop' to be sent from within the resource allocator so that the consumer receives it, terminating the+-- entire scope.+interpretScopedResumableH ::+  ∀ param resource effect err r .+  (∀ x . param -> (resource -> Sem (Stop err : r) x) -> Sem (Stop err : r) x) ->+  (∀ r0 x . resource -> effect (Sem r0) x -> Tactical effect (Sem r0) (Stop err : r) x) ->+  InterpreterFor (Scoped param effect !! err) r+interpretScopedResumableH withResource scopedHandler =+  interpretWeaving \case+    Weaving (Resumable (Weaving (InScope param main) s' wv' ex' _)) s wv ex _ -> do+      exResumable s ex ex' $ runStop $ withResource param \ resource ->+        interpretH (scopedHandler resource) (raiseUnder (go $ raiseUnder $ wv ((wv' (main <$ s')) <$ s)))+    _ ->+      errorWithoutStackTrace "top level run"+  where+    go :: InterpreterFor (Scoped param effect !! err) (effect : r)+    go =+      interpretWeaving \ (Weaving (Resumable (Weaving effect s' wv' ex' ins')) s wv ex ins) -> case effect of+        Run act ->+          ex . fmap Right <$> liftSem (weave s (go . wv) ins (injWeaving (Weaving act s' wv' ex' ins')))+        InScope param main -> do+          exResumable s ex ex' $ raise $ runStop $ withResource param \ resource ->+            interpretH (scopedHandler resource) (raiseUnder (go $ wv (wv' (main <$ s') <$ s)))++-- |Combined interpreter for 'Scoped' and 'Resumable'.+-- This allows 'Stop' to be sent from within the resource allocator so that the consumer receives it, terminating the+-- entire scope.+interpretScopedResumable ::+  ∀ param resource effect err r .+  (∀ x . param -> (resource -> Sem (Stop err : r) x) -> Sem (Stop err : r) x) ->+  (∀ r0 x . resource -> effect (Sem r0) x -> Sem (Stop err : r) x) ->+  InterpreterFor (Scoped param effect !! err) r+interpretScopedResumable withResource scopedHandler =+  interpretScopedResumableH withResource \ r e -> liftT (scopedHandler r e)++-- |Combined interpreter for 'Scoped' and 'Resumable'.+-- This allows 'Stop' to be sent from within the resource allocator so that the consumer receives it, terminating the+-- entire scope.+-- In this variant, the resource allocator is a plain action.+interpretScopedResumable_ ::+  ∀ param resource effect err r .+  (param -> Sem (Stop err : r) resource) ->+  (∀ r0 x . resource -> effect (Sem r0) x -> Sem (Stop err : r) x) ->+  InterpreterFor (Scoped param effect !! err) r+interpretScopedResumable_ resource =+  interpretScopedResumable \ p use -> use =<< resource p++-- |Combined higher-order 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.+interpretScopedResumableWithH ::+  ∀ extra param resource effect err r r1 extraerr .+  extraerr ~ (extra ++ '[Stop err]) =>+  r1 ~ (extraerr ++ r) =>+  KnownList (extra ++ '[Stop err]) =>+  (∀ x . param -> (resource -> Sem r1 x) -> Sem (Stop err : r) x) ->+  (∀ r0 x . resource -> effect (Sem r0) x -> Tactical effect (Sem r0) r1 x) ->+  InterpreterFor (Scoped param effect !! err) r+interpretScopedResumableWithH withResource scopedHandler =+  interpretWeaving \case+    Weaving (Resumable (Weaving (InScope param main) s' wv' ex' _)) s wv ex _ -> do+      exResumable s ex ex' $ runStop $ withResource param \ resource ->+        interpretH (scopedHandler resource) $ inScope $+          restack+            (injectMembership+             (singList @'[Scoped param effect !! err])+             (singList @(effect : extraerr))) $ wv (wv' (main <$ s') <$ s)+    _ ->+      errorWithoutStackTrace "top level Run"+  where+    inScope :: InterpreterFor (Scoped param effect !! err) (effect : r1)+    inScope =+      interpretWeaving \ (Weaving (Resumable (Weaving effect s' wv' ex' ins')) s wv ex ins) -> case effect of+        InScope param main ->+          restack+            (extendMembershipLeft (singList @(effect : extraerr))) $+            exResumable s ex ex' $ runStop $ withResource param \ resource ->+              interpretH (scopedHandler resource) (inScope $ wv (wv' (main <$ s') <$ s))+        Run act ->+          ex . fmap Right <$> liftSem (weave s (inScope . wv) ins (injWeaving (Weaving act s' wv' ex' ins')))++-- |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.+interpretScopedResumableWith ::+  ∀ extra param resource effect err r r1 .+  r1 ~ ((extra ++ '[Stop err]) ++ r) =>+  KnownList (extra ++ '[Stop err]) =>+  (∀ x . param -> (resource -> Sem r1 x) -> Sem (Stop err : r) x) ->+  (∀ r0 x . resource -> effect (Sem r0) x -> Sem r1 x) ->+  InterpreterFor (Scoped param effect !! err) r+interpretScopedResumableWith withResource scopedHandler =+  interpretScopedResumableWithH @extra withResource \ r e -> liftT (scopedHandler r e)++-- |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.+interpretScopedResumableWith_ ::+  ∀ extra param effect err r r1 .+  r1 ~ ((extra ++ '[Stop err]) ++ r) =>+  KnownList (extra ++ '[Stop err]) =>+  (∀ x . param -> Sem r1 x -> Sem (Stop err : r) x) ->+  (∀ r0 x . effect (Sem r0) x -> Sem r1 x) ->+  InterpreterFor (Scoped param effect !! err) r+interpretScopedResumableWith_ extra scopedHandler =+  interpretScopedResumableWith @extra (\ p f -> extra p (f ())) (const scopedHandler)++-- |Combined higher-order interpreter for 'Resumable' and 'Scoped'.+-- In this variant, only the handler may send 'Stop', but this allows resumption to happen on each action inside of the+-- scope.+interpretResumableScopedH ::+  ∀ param resource effect err r .+  (∀ x . param -> (resource -> Sem r x) -> Sem r x) ->+  (∀ r0 x . resource -> effect (Sem r0) x -> Tactical (effect !! err) (Sem r0) (Stop err : r) x) ->+  InterpreterFor (Scoped param (effect !! err)) r+interpretResumableScopedH withResource scopedHandler =+  interpretWeaving $ \(Weaving effect s wv ex _) -> case effect of+    Run _ -> errorWithoutStackTrace "top level run"+    InScope param main -> withResource param \ resource ->+      ex <$> interpretResumableH (scopedHandler resource) (inScope $ raiseUnder $ wv (main <$ s))+  where+    inScope :: InterpreterFor (Scoped param (effect !! err)) (effect !! err : r)+    inScope =+      interpretWeaving \ (Weaving effect s wv ex ins) -> case effect of+        Run act -> liftSem $ injWeaving $ Weaving act s (inScope . wv) ex ins+        InScope param main -> raise $ withResource param \ resource ->+          ex <$> interpretResumableH (scopedHandler resource) (inScope $ wv (main <$ s))++-- |Combined interpreter for 'Resumable' and 'Scoped'.+-- In this variant, only the handler may send 'Stop', but this allows resumption to happen on each action inside of the+-- scope.+interpretResumableScoped ::+  ∀ param resource effect err r .+  (∀ x . param -> (resource -> Sem r x) -> Sem r x) ->+  (∀ r0 x . resource -> effect (Sem r0) x -> Sem (Stop err : r) x) ->+  InterpreterFor (Scoped param (effect !! err)) r+interpretResumableScoped withResource scopedHandler =+  interpretResumableScopedH withResource \ r e -> liftT (scopedHandler r e)++-- |Combined interpreter for 'Resumable' and 'Scoped'.+-- In this variant:+-- - Only the handler may send 'Stop', but this allows resumption to happen on each action inside of the scope.+-- - The resource allocator is a plain action.+interpretResumableScoped_ ::+  ∀ param resource effect err r .+  (param -> Sem r resource) ->+  (∀ r0 x . resource -> effect (Sem r0) x -> Sem (Stop err : r) x) ->+  InterpreterFor (Scoped param (effect !! err)) r+interpretResumableScoped_ resource =+  interpretResumableScoped \ p use -> use =<< resource p++-- |Combined higher-order 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.+interpretResumableScopedWithH ::+  ∀ extra param resource effect err r r1 .+  r1 ~ (extra ++ r) =>+  KnownList extra =>+  (∀ x . param -> (resource -> Sem r1 x) -> Sem r x) ->+  (∀ r0 x . resource -> effect (Sem r0) x -> Tactical (effect !! err) (Sem r0) (Stop err : r1) x) ->+  InterpreterFor (Scoped param (effect !! err)) r+interpretResumableScopedWithH withResource scopedHandler =+  interpretWeaving \case+    Weaving (InScope param main) s wv ex _ ->+      ex <$> withResource param \ resource ->+        interpretResumableH (scopedHandler resource) $ inScope $+          restack+            (injectMembership+             (singList @'[Scoped param (effect !! err)])+             (singList @(effect !! err : extra))) $ wv (main <$ s)+    _ ->+      errorWithoutStackTrace "top level Run"+  where+    inScope :: InterpreterFor (Scoped param (effect !! err)) (effect !! err : r1)+    inScope =+      interpretWeaving \case+        Weaving (InScope param main) s wv ex _ ->+          restack+            (extendMembershipLeft (singList @(effect !! err : extra)))+            (ex <$> withResource param \resource ->+                interpretResumableH (scopedHandler resource) $ inScope $ wv (main <$ s))+        Weaving (Run act) s wv ex ins ->+          liftSem $ injWeaving $ Weaving act s (inScope . wv) ex ins++-- |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.+interpretResumableScopedWith ::+  ∀ extra param resource effect err r r1 .+  r1 ~ (extra ++ r) =>+  KnownList extra =>+  (∀ x . param -> (resource -> Sem r1 x) -> Sem r x) ->+  (∀ r0 x . resource -> effect (Sem r0) x -> Sem (Stop err : r1) x) ->+  InterpreterFor (Scoped param (effect !! err)) r+interpretResumableScopedWith withResource scopedHandler =+  interpretResumableScopedWithH @extra withResource \ r e -> liftT (scopedHandler r e)++-- |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.+interpretResumableScopedWith_ ::+  ∀ extra param effect err r r1 .+  r1 ~ (extra ++ r) =>+  KnownList extra =>+  (∀ x . param -> Sem r1 x -> Sem r x) ->+  (∀ r0 x . effect (Sem r0) x -> Sem (Stop err : r1) x) ->+  InterpreterFor (Scoped param (effect !! err)) r+interpretResumableScopedWith_ extra scopedHandler =+  interpretResumableScopedWith @extra @param @() @effect @err @r @r1 (\ p f -> extra p (f ())) (const scopedHandler)++-- |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.+interpretScopedRH ::+  ∀ param resource effect eo ei r .+  (∀ x . param -> (resource -> Sem (Stop eo : r) x) -> Sem (Stop eo : r) x) ->+  (∀ r0 x . resource -> effect (Sem r0) x -> Tactical (effect !! ei) (Sem r0) (Stop ei : Stop eo : r) x) ->+  InterpreterFor (Scoped param (effect !! ei) !! eo) r+interpretScopedRH withResource scopedHandler =+  interpretWeaving \case+    Weaving (Resumable (Weaving (InScope param main) s' wv' ex' _)) s wv ex _ -> do+      exResumable s ex ex' $ runStop $ withResource param \ resource ->+        interpretResumableH (scopedHandler resource) (raiseUnder (inScope $ raiseUnder $ wv (wv' (main <$ s') <$ s)))+    _ ->+      errorWithoutStackTrace "top level run"+  where+    inScope :: InterpreterFor (Scoped param (effect !! ei) !! eo) (effect !! ei : r)+    inScope =+      interpretWeaving \ (Weaving (Resumable (Weaving effect s' wv' ex' ins')) s wv ex ins) -> case effect of+        Run act ->+          ex . fmap Right <$> liftSem (weave s (inScope . wv) ins (injWeaving (Weaving act s' wv' ex' ins')))+        InScope param main -> do+          exResumable s ex ex' $ raise $ runStop $ withResource param \ resource ->+            interpretResumableH (scopedHandler resource) (raiseUnder (inScope $ wv (wv' (main <$ s') <$ s)))++-- |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.+interpretScopedR ::+  ∀ param resource effect eo ei r .+  (∀ x . param -> (resource -> Sem (Stop eo : r) x) -> Sem (Stop eo : r) x) ->+  (∀ r0 x . resource -> effect (Sem r0) x -> Sem (Stop ei : Stop eo : r) x) ->+  InterpreterFor (Scoped param (effect !! ei) !! eo) r+interpretScopedR withResource scopedHandler =+  interpretScopedRH withResource \ r e -> liftT (scopedHandler r e)++-- |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.+interpretScopedR_ ::+  ∀ param resource effect eo ei r .+  (param -> Sem (Stop eo : r) resource) ->+  (∀ r0 x . resource -> effect (Sem r0) x -> Sem (Stop ei : Stop eo : r) x) ->+  InterpreterFor (Scoped param (effect !! ei) !! eo) r+interpretScopedR_ resource =+  interpretScopedR \ p use -> use =<< resource p++-- |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.+interpretScopedRWithH ::+  ∀ extra param resource effect eo ei r r1 extraerr .+  extraerr ~ (extra ++ '[Stop eo]) =>+  r1 ~ (extra ++ Stop eo : r) =>+  r1 ~ ((extra ++ '[Stop eo]) ++ r) =>+  KnownList (extra ++ '[Stop eo]) =>+  (∀ x . param -> (resource -> Sem (extra ++ Stop eo : r) x) -> Sem (Stop eo : r) x) ->+  (∀ r0 x . resource -> effect (Sem r0) x -> Tactical (effect !! ei) (Sem r0) (Stop ei : r1) x) ->+  InterpreterFor (Scoped param (effect !! ei) !! eo) r+interpretScopedRWithH withResource scopedHandler =+  interpretWeaving \case+    Weaving (Resumable (Weaving (InScope param main) s' wv' ex' _)) s wv ex _ -> do+      exResumable s ex ex' $ runStop $ withResource param \ resource ->+        interpretResumableH (scopedHandler resource) $ inScope $+          restack+            (injectMembership+             (singList @'[Scoped param (effect !! ei) !! eo])+             (singList @(effect !! ei : extraerr))) $ wv (wv' (main <$ s') <$ s)+    _ ->+      errorWithoutStackTrace "top level Run"+  where+    inScope :: InterpreterFor (Scoped param (effect !! ei) !! eo) (effect !! ei : r1)+    inScope =+      interpretWeaving \ (Weaving (Resumable (Weaving effect s' wv' ex' ins')) s wv ex ins) -> case effect of+        InScope param main ->+          exResumable s ex ex' $+          restack (extendMembershipLeft (singList @(effect !! ei : extraerr))) $+          runStop $+          withResource param \ resource ->+            interpretResumableH (scopedHandler resource) (inScope $ wv (wv' (main <$ s') <$ s))+        Run act ->+          ex . fmap Right <$> liftSem (weave s (inScope . wv) ins (injWeaving (Weaving act s' wv' ex' ins')))++-- |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.+interpretScopedRWith ::+  ∀ extra param resource effect eo ei r r1 .+  r1 ~ (extra ++ Stop eo : r) =>+  r1 ~ ((extra ++ '[Stop eo]) ++ r) =>+  KnownList (extra ++ '[Stop eo]) =>+  (∀ x . param -> (resource -> Sem r1 x) -> Sem (Stop eo : r) x) ->+  (∀ r0 x . resource -> effect (Sem r0) x -> Sem (Stop ei : r1) x) ->+  InterpreterFor (Scoped param (effect !! ei) !! eo) r+interpretScopedRWith withResource scopedHandler =+  interpretScopedRWithH @extra withResource \ r e -> liftT (scopedHandler r e)++-- |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.+interpretScopedRWith_ ::+  ∀ extra param effect eo ei r r1 .+  r1 ~ (extra ++ Stop eo : r) =>+  r1 ~ ((extra ++ '[Stop eo]) ++ r) =>+  KnownList (extra ++ '[Stop eo]) =>+  (∀ x . param -> Sem r1 x -> Sem (Stop eo : r) x) ->+  (∀ r0 x . effect (Sem r0) x -> Sem (Stop ei : r1) x) ->+  InterpreterFor (Scoped param (effect !! ei) !! eo) r+interpretScopedRWith_ extra scopedHandler =+  interpretScopedRWith @extra (\ p f -> extra p (f ())) (const scopedHandler)
+ lib/Polysemy/Resume/Interpreter/Stop.hs view
@@ -0,0 +1,254 @@+{-# options_haddock prune #-}++-- |Description: Interpreters for 'Stop'.+module Polysemy.Resume.Interpreter.Stop where++import qualified Control.Exception as Base+import Control.Exception (throwIO)+import Control.Monad.Trans.Except (ExceptT (ExceptT), runExceptT, throwE)+import Data.Typeable (typeRep)+import Polysemy.Final (getInitialStateS, interpretFinal, runS, withStrategicToFinal)+import Polysemy.Internal (Sem (Sem), usingSem)+import Polysemy.Internal.Union (Weaving (Weaving), decomp, hoist, weave)+import qualified Text.Show++import Polysemy.Resume.Effect.Stop (Stop (Stop), stop)++-- |Equivalent of 'runError'.+runStop ::+  Sem (Stop err : r) a ->+  Sem r (Either err a)+runStop (Sem m) =+  Sem \ k ->+    runExceptT $ m \ u ->+      case decomp u of+        Left x ->+          ExceptT $ k $ weave (Right ()) (either (pure . Left) runStop) rightToMaybe x+        Right (Weaving (Stop err) _ _ _ _) ->+          throwE err+{-# inline runStop #-}++-- | Internal type used to tag exceptions thrown by 'Stop' interpreters.+newtype StopExc err =+  StopExc { unStopExc :: err }+  deriving stock (Typeable)++instance {-# overlappable #-} Typeable err => Show (StopExc err) where+  show =+    mappend "StopExc: " . show . typeRep++instance Show (StopExc Text) where+  show (StopExc err) =+    "StopExc " <> show err++instance {-# overlappable #-} Typeable err => Exception (StopExc err)++instance Exception (StopExc Text)++-- |Run 'Stop' by throwing exceptions.+runStopAsExcFinal ::+  ∀ err r a .+  Exception (StopExc err) =>+  Member (Final IO) r =>+  Sem (Stop err : r) a ->+  Sem r a+runStopAsExcFinal =+  interpretFinal \case+    Stop err ->+      pure (throwIO (StopExc err))+{-# inline runStopAsExcFinal #-}++-- |Run 'Stop' by throwing and catching exceptions.+stopToIOFinal ::+  ∀ err r a .+  Exception (StopExc err) =>+  Member (Final IO) r =>+  Sem (Stop err : r) a ->+  Sem r (Either err a)+stopToIOFinal sem =+  withStrategicToFinal @IO do+    m' <- runS (runStopAsExcFinal sem)+    s <- getInitialStateS+    pure $ either ((<$ s) . Left . unStopExc) (fmap Right) <$> Base.try m'+{-# inline stopToIOFinal #-}++-- |Stop if the argument is 'Left', transforming the error with @f@.+stopEitherWith ::+  ∀ err err' r a .+  Member (Stop err') r =>+  (err -> err') ->+  Either err a ->+  Sem r a+stopEitherWith f =+  either (stop . f) pure+{-# inline stopEitherWith #-}++-- |Stop if the argument is 'Left', using the supplied error.+stopEitherAs ::+  ∀ err err' r a .+  Member (Stop err') r =>+  err' ->+  Either err a ->+  Sem r a+stopEitherAs err =+  stopEitherWith (const err)+{-# inline stopEitherAs #-}++-- |Stop if the argument is 'Left'.+stopEither ::+  ∀ err r a .+  Member (Stop err) r =>+  Either err a ->+  Sem r a+stopEither =+  stopEitherWith id+{-# inline stopEither #-}++-- |Stop with the supplied error if the argument is 'Nothing'.+stopNote ::+  ∀ err r a .+  Member (Stop err) r =>+  err ->+  Maybe a ->+  Sem r a+stopNote err =+  maybe (stop err) pure+{-# inline stopNote #-}++-- |Convert a program using regular 'Error's to one using 'Stop'.+stopOnError ::+  ∀ err r a .+  Member (Stop err) r =>+  Sem (Error err : r) a ->+  Sem r a+stopOnError =+  stopEither <=< runError+{-# inline stopOnError #-}++-- |Convert a program using regular 'Error's to one using 'Stop'.+stopOnErrorWith ::+  ∀ err err' r a .+  Member (Stop err') r =>+  (err -> err') ->+  Sem (Error err : r) a ->+  Sem r a+stopOnErrorWith f =+  stopEitherWith f <=< runError+{-# inline stopOnErrorWith #-}++-- |Convert a program using 'Stop' to one using 'Error', transforming the error with the supplied function.+stopToErrorWith ::+  ∀ err err' r a .+  Member (Error err') r =>+  (err -> err') ->+  Sem (Stop err : r) a ->+  Sem r a+stopToErrorWith f =+  either (throw . f) pure <=< runStop+{-# inline stopToErrorWith #-}++-- |Convert a program using 'Stop' to one using 'Error'.+stopToError ::+  ∀ err r a .+  Member (Error err) r =>+  Sem (Stop err : r) a ->+  Sem r a+stopToError =+  stopToErrorWith id+{-# inline stopToError #-}++-- |Convert a program using 'Stop' to one using 'Error'.+stopToErrorIO ::+  ∀ err r a .+  Exception (StopExc err) =>+  Members [Error err, Final IO] r =>+  Sem (Stop err : r) a ->+  Sem r a+stopToErrorIO =+  either throw pure <=< stopToIOFinal+{-# inline stopToErrorIO #-}++-- |Map over the error type in a 'Stop'.+mapStop ::+  ∀ err e' r a .+  Member (Stop e') r =>+  (err -> e') ->+  Sem (Stop err : r) a ->+  Sem r a+mapStop f (Sem m) =+  Sem \ k -> m \ u ->+    case decomp u of+      Left x ->+        k (hoist (mapStop f) x)+      Right (Weaving (Stop err) _ _ _ _) ->+        usingSem k (send $ Stop (f err))+{-# inline mapStop #-}++-- |Replace the error in a 'Stop' with another type.+replaceStop ::+  ∀ err e' r a .+  Member (Stop e') r =>+  e' ->+  Sem (Stop err : r) a ->+  Sem r a+replaceStop e' =+  mapStop (const e')+{-# inline replaceStop #-}++-- |Convert the error type in a 'Stop' to 'Text'.+showStop ::+  ∀ err r a .+  Show err =>+  Member (Stop Text) r =>+  Sem (Stop err : r) a ->+  Sem r a+showStop =+  mapStop @err @Text show+{-# inline showStop #-}++-- |Convert an 'IO' exception to 'Stop' using the provided transformation.+stopTryIOE ::+  ∀ exc err r a .+  Exception exc =>+  Members [Stop err, Embed IO] r =>+  (exc -> err) ->+  IO a ->+  Sem r a+stopTryIOE f =+  stopEitherWith f <=< tryIOE @exc+{-# inline stopTryIOE #-}++-- |Convert an 'IO' exception of type @err@ to 'Stop' using the provided transformation from 'Text'.+stopTryIO ::+  ∀ exc err r a .+  Exception exc =>+  Members [Stop err, Embed IO] r =>+  (Text -> err) ->+  IO a ->+  Sem r a+stopTryIO f =+  stopEitherWith f <=< tryIO @exc+{-# inline stopTryIO #-}++-- |Convert an 'IO' exception of type 'Control.Exception.IOError' to 'Stop' using the provided transformation from+-- 'Text'.+stopTryIOError ::+  ∀ err r a .+  Members [Stop err, Embed IO] r =>+  (Text -> err) ->+  IO a ->+  Sem r a+stopTryIOError f =+  stopEitherWith f <=< tryIOError+{-# inline stopTryIOError #-}++-- |Convert an 'IO' exception to 'Stop' using the provided transformation from 'Text'.+stopTryAny ::+  ∀ err r a .+  Members [Stop err, Embed IO] r =>+  (Text -> err) ->+  IO a ->+  Sem r a+stopTryAny f =+  stopEitherWith f <=< tryAny+{-# inline stopTryAny #-}
− lib/Polysemy/Resume/Resumable.hs
@@ -1,327 +0,0 @@-{-# options_ghc -Wno-redundant-constraints #-}--module Polysemy.Resume.Resumable where--import Polysemy.Error (Error (Throw))-import Polysemy.Internal (Sem (Sem, runSem), liftSem, usingSem)-import Polysemy.Internal.CustomErrors (FirstOrder)-import Polysemy.Internal.Tactics (liftT, runTactics)-import Polysemy.Internal.Union (ElemOf, Weaving (Weaving), decomp, hoist, inj, injWeaving, membership, prjUsing, weave)--import Polysemy.Resume.Effect.Resumable (Resumable (..))-import Polysemy.Resume.Effect.Stop (Stop, stop)-import Polysemy.Resume.Stop (StopExc, runStop, stopOnError, stopToIOFinal)--type InterpreterTrans' eff eff' r r' =-  ∀ a b .-  (Sem (eff' : r') a -> Sem r b) ->-  Sem (eff : r) a ->-  Sem r b--type InterpreterTrans eff eff' r =-  InterpreterTrans' eff eff' r r--distribEither ::-  Functor f =>-  f () ->-  (f (Either err a) -> res) ->-  Either err (f a) ->-  res-distribEither initialState result =-  result . \case-    Right fa -> Right <$> fa-    Left err -> Left err <$ initialState-{-# inline distribEither #-}---- |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'.------ >>> run $ resumable interpretStopper (interpretResumer mainProgram)--- 237-resumable ::-  ∀ (err :: Type) (eff :: Effect) (r :: EffectRow) .-  InterpreterFor eff (Stop err : r) ->-  InterpreterFor (Resumable err eff) r-resumable interpreter (Sem m) =-  Sem \ k -> m \ u ->-    case decomp (hoist (resumable interpreter) u) of-      Right (Weaving (Resumable e) s wv ex ins) ->-        distribEither s ex <$> runSem resultFromEff k-        where-          resultFromEff =-            runStop $ interpreter $ liftSem $ weave s (raise . raise . wv) ins (injWeaving e)-      Left g ->-        k g-{-# inline resumable #-}---- |Convenience combinator for turning an interpreter that doesn't use 'Stop' into a 'Resumable'.-raiseResumable ::-  ∀ (err :: Type) (eff :: Effect) (r :: EffectRow) .-  InterpreterTrans (Resumable err eff) eff r-raiseResumable interpreter =-  interpreter . normalize . raiseUnder-  where-    normalize :: InterpreterFor (Resumable err eff) (eff : r)-    normalize (Sem m) =-      Sem \ k -> m \ u ->-        case decomp (hoist normalize u) of-          Right (Weaving (Resumable e) s wv ex ins) ->-            ex . fmap Right <$> (usingSem k $ liftSem $ weave s wv ins (injWeaving e))-          Left g ->-            k g-    {-# inline normalize #-}-{-# inline raiseResumable #-}---- |Like 'resumable', but use exceptions instead of 'ExceptT'.-resumableIO ::-  ∀ (err :: Type) (eff :: Effect) (r :: EffectRow) .-  Exception (StopExc err) =>-  Member (Final IO) r =>-  InterpreterFor eff (Stop err : r) ->-  InterpreterFor (Resumable err eff) r-resumableIO interpreter (Sem m) =-  Sem \ k -> m \ u ->-    case decomp (hoist (resumable interpreter) u) of-      Right (Weaving (Resumable e) s wv ex ins) ->-        distribEither s ex <$> runSem resultFromEff k-        where-          resultFromEff =-            stopToIOFinal $ interpreter $ liftSem $ weave s (raise . raise . wv) ins (injWeaving e)-      Left g ->-        k g-{-# inline resumableIO #-}---- |Like 'interpretResumable', but for higher-order effects.-interpretResumableH ::-  ∀ (err :: Type) (eff :: Effect) (r :: EffectRow) .-  -- |This handler function has @'Stop' err@ in its stack, allowing it to absorb errors.-  (∀ x r0 . eff (Sem r0) x -> Tactical (Resumable err eff) (Sem r0) (Stop err : r) x) ->-  InterpreterFor (Resumable err eff) r-interpretResumableH handler (Sem m) =-  Sem \ k -> m \ u ->-    case decomp u of-      Left there ->-        k (hoist (interpretResumableH handler) there)-      Right (Weaving (Resumable (Weaving e s dist ex ins)) sOuter distOuter exOuter insOuter) ->-        usingSem k (exFinal <$> runStop (tac (handler e)))-        where-          tac =-            runTactics-            (Compose (s <$ sOuter))-            (raiseUnder . fmap Compose . distOuter . fmap dist . getCompose)-            (ins <=< insOuter . getCompose)-            (raise . interpretResumableH handler . fmap Compose . distOuter . fmap dist . getCompose)-          exFinal = exOuter . \case-            Right (Compose a) -> Right . ex <$> a-            Left err -> Left err <$ sOuter-{-# inline interpretResumableH #-}---- |Create an interpreter for @'Resumable' err eff@ by supplying a handler function for @eff@, analogous to--- 'Polysemy.interpret'.--- If the handler throws errors with 'Stop', they will be absorbed into 'Resumable', to be caught by--- 'Polysemy.Resume.resume' in a downstream interpreter.------ @--- interpretStopperResumable ::---   InterpreterFor Stopper r--- interpretStopperResumable =---   interpretResumable \\case---     StopBang -> stop (Bang 13)---     StopBoom -> stop (Boom "ouch")--- @------ >>> run $ interpretStopperResumable (interpretResumer mainProgram)--- 237-interpretResumable ::-  ∀ (err :: Type) (eff :: Effect) r .-  FirstOrder eff "interpretResumable" =>-  (∀ x r0 . eff (Sem r0) x -> Sem (Stop err : r) x) ->-  InterpreterFor (Resumable err eff) r-interpretResumable handler =-  interpretResumableH \ e -> liftT (handler e)-{-# inline interpretResumable #-}---- |Interceptor variant of 'interpretResumableH'.-interceptResumableUsingH ::-  ∀ (err :: Type) (eff :: Effect) (r :: EffectRow) (a :: Type) .-  ElemOf (Resumable err eff) r ->-  (∀ x r0 . eff (Sem r0) x -> Tactical (Resumable err eff) (Sem r0) (Stop err : r) x) ->-  Sem r a ->-  Sem r a-interceptResumableUsingH proof handler (Sem m) =-  Sem \ k -> m \ u ->-    case prjUsing proof u of-      Nothing ->-        k (hoist (interceptResumableUsingH proof handler) u)-      Just (Weaving (Resumable (Weaving e s dist ex ins)) sOuter distOuter exOuter insOuter) ->-        usingSem k (exFinal <$> runStop (tac (handler e)))-        where-          tac =-            runTactics-            (Compose (s <$ sOuter))-            (raise . raise . fmap Compose . distOuter . fmap dist . getCompose)-            (ins <=< insOuter . getCompose)-            (raise . interceptResumableUsingH proof handler . fmap Compose . distOuter . fmap dist . getCompose)-          exFinal = exOuter . \case-            Right (Compose a) -> Right . ex <$> a-            Left err -> Left err <$ sOuter-{-# inline interceptResumableUsingH #-}---- |Interceptor variant of 'interpretResumable'.-interceptResumableUsing ::-  ∀ (err :: Type) (eff :: Effect) (r :: EffectRow) (a :: Type) .-  FirstOrder eff "interceptResumableUsing" =>-  ElemOf (Resumable err eff) r ->-  (∀ x r0 . eff (Sem r0) x -> Sem (Stop err : r) x) ->-  Sem r a ->-  Sem r a-interceptResumableUsing proof f =-  interceptResumableUsingH proof \ e ->-    liftT (f e)-{-# inline interceptResumableUsing #-}---- |Interceptor variant of 'interpretResumableH'.-interceptResumableH ::-  ∀ (err :: Type) (eff :: Effect) (r :: EffectRow) (a :: Type) .-  Member (Resumable err eff) r =>-  (∀ x r0 . eff (Sem r0) x -> Tactical (Resumable err eff) (Sem r0) (Stop err : r) x) ->-  Sem r a ->-  Sem r a-interceptResumableH =-  interceptResumableUsingH membership-{-# inline interceptResumableH #-}---- |Interceptor variant of 'interpretResumable'.-interceptResumable ::-  ∀ (err :: Type) (eff :: Effect) (r :: EffectRow) (a :: Type) .-  Member (Resumable err eff) r =>-  FirstOrder eff "interceptResumable" =>-  (∀ x r0 . eff (Sem r0) x -> Sem (Stop err : r) x) ->-  Sem r a ->-  Sem r a-interceptResumable f =-  interceptResumableH \ e ->-    liftT (f e)-{-# inline interceptResumable #-}---- |Convert an interpreter for @eff@ that uses 'Error' into one using 'Stop' and wrap it using 'resumable'.-resumableError ::-  ∀ (err :: Type) (eff :: Effect) r .-  InterpreterFor eff (Error err : Stop err : r) ->-  InterpreterFor (Resumable err eff) r-resumableError interpreter =-  resumable (stopOnError . interpreter . raiseUnder)-{-# inline resumableError #-}---- |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 (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)--- @------ >>> runError (resumableFor bangOnly interpretStopper (interpretResumerPartial mainProgram))--- Right 39-resumableOr ::-  ∀ (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-resumableOr canHandle interpreter (Sem m) =-  Sem \ k -> m \ u ->-    case decomp (hoist (resumableOr canHandle interpreter) u) of-      Right (Weaving (Resumable e) s wv ex ins) ->-        distribEither s ex <$> (tryHandle =<< runSem resultFromEff k)-        where-          tryHandle = \case-            Left err ->-              either (k . inj . Throw) (pure . Left) (canHandle err)-            Right a ->-              pure (Right a)-          resultFromEff =-            runStop $ interpreter $ liftSem $ weave s (raise . raise . wv) ins (injWeaving e)-      Left g ->-        k g-{-# inline resumableOr #-}---- |Variant of 'resumableOr' that uses 'Maybe' and rethrows the original error.-resumableFor ::-  ∀ (err :: Type) (eff :: Effect) handled r .-  Member (Error err) r =>-  (err -> Maybe handled) ->-  InterpreterFor eff (Stop err : r) ->-  InterpreterFor (Resumable handled eff) r-resumableFor canHandle =-  resumableOr canHandle'-  where-    canHandle' err =-      maybeToRight err (canHandle err)-{-# inline resumableFor #-}---- |Reinterpreting variant of 'resumableFor'.-catchResumable ::-  ∀ (err :: Type) (eff :: Effect) handled r .-  Members [eff, Error err] r =>-  (err -> Maybe handled) ->-  InterpreterFor (Resumable handled eff) r-catchResumable canHandle (Sem m) =-  Sem \ k -> m \ u ->-    case decomp (hoist (catchResumable canHandle) u) of-      Right (Weaving (Resumable e) s wv ex ins) ->-        distribEither s ex <$> runSem resultFromEff k-        where-          resultFromEff =-            catchJust canHandle (fmap Right $ liftSem $ weave s wv ins (injWeaving e)) (pure . Left)-      Left g ->-        k g-{-# inline catchResumable #-}---- |Interpret an effect @eff@ by wrapping it in @Resumable@ and @Stop@ and leaving the rest up to the user.-runAsResumable ::-  ∀ (err :: Type) (eff :: Effect) r .-  Members [Resumable err eff, Stop err] r =>-  InterpreterFor eff r-runAsResumable (Sem m) =-  Sem \ k -> m \ u ->-    case decomp (hoist (runAsResumable @err @eff) u) of-      Right wav ->-        runSem (either (stop @err) pure =<< send (Resumable wav)) k-      Left g ->-        k g-{-# inline runAsResumable #-}
lib/Polysemy/Resume/Resume.hs view
@@ -1,17 +1,17 @@--- |Resumption combinators, transforming an effect into 'Resumable' and 'Stop'.+-- | Resumption combinators, transforming an effect into 'Resumable' and 'Stop'. module Polysemy.Resume.Resume where  import Polysemy.Resume.Effect.Resumable (Resumable) import Polysemy.Resume.Effect.Stop (Stop, stop)-import Polysemy.Resume.Resumable (runAsResumable)-import Polysemy.Resume.Stop (runStop)+import Polysemy.Resume.Interpreter.Resumable (runAsResumable)+import Polysemy.Resume.Interpreter.Stop (runStop) --- |Execute the action of a regular effect @eff@ so that any error of type @err@ that maybe be thrown by the (unknown)+-- | 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 'Polysemy.Error.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 'Polysemy.Resume.Resumable.resumable'.+-- with 'Polysemy.Resume.Interpreter.Resumable.resumable'. -- -- @ -- data Resumer :: Effect where@@ -37,7 +37,7 @@   either handler pure =<< runStop (runAsResumable @err (raiseUnder sem)) {-# inline resume #-} --- |Operator version of 'resume'.+-- | Operator version of 'resume'. -- -- @since 0.2.0.0 (!!) ::@@ -50,7 +50,7 @@   resume {-# inline (!!) #-} --- Reinterpreting version of 'resume'.+-- | Reinterpreting version of 'resume'. resumeRe ::   ∀ err eff r a .   Sem (eff : r) a ->@@ -60,7 +60,7 @@   either handler pure =<< runStop (runAsResumable @err (raiseUnder2 sem)) {-# inline resumeRe #-} --- |Flipped variant of 'resume'.+-- | Flipped variant of 'resume'. resuming ::   ∀ err eff r a .   Member (Resumable err eff) r =>@@ -71,7 +71,7 @@   flip resume {-# inline resuming #-} --- |Flipped variant of 'resumeRe'.+-- | Flipped variant of 'resumeRe'. resumingRe ::   ∀ err eff r a .   (err -> Sem (Resumable err eff : r) a) ->@@ -81,7 +81,7 @@   flip resumeRe {-# inline resumingRe #-} --- |Variant of 'resume' that unconditionally recovers with a constant value.+-- | Variant of 'resume' that unconditionally recovers with a constant value. resumeAs ::   ∀ err eff r a .   Member (Resumable err eff) r =>@@ -92,7 +92,7 @@   resuming @err \ _ -> pure a {-# inline resumeAs #-} --- |Operator version of 'resumeAs'.+-- | Operator version of 'resumeAs'. -- -- @since 0.2.0.0 (<!) ::@@ -104,7 +104,7 @@ (<!) =   resumeAs @err --- |Operator version of 'resumeAs', flipped version of '(<!)'.+-- | Operator version of 'resumeAs', flipped version of '(<!)'. -- -- @since 0.2.0.0 (!>) ::@@ -116,7 +116,7 @@ (!>) =   flip (resumeAs @err) --- |Convenience specialization of 'resume' that silently discards errors for void programs.+-- | Convenience specialization of 'resume' that silently discards errors for void programs. resume_ ::   ∀ err eff r .   Member (Resumable err eff) r =>@@ -125,7 +125,7 @@ resume_ =   resumeAs @err () --- |Variant of 'resume' that unconditionally recovers with an action.+-- | Variant of 'resume' that unconditionally recovers with an action. -- -- @since 0.2.0.0 resumeWith ::@@ -138,7 +138,7 @@   resume @err ma (const ma') {-# inline resumeWith #-} --- |Operator variant of 'resumeWith'.+-- | Operator variant of 'resumeWith'. -- -- @since 0.2.0.0 (!>>) ::@@ -151,7 +151,7 @@   resumeWith @err {-# inline (!>>) #-} --- |Variant of 'resuming' that unconditionally recovers with an action.+-- | Variant of 'resuming' that unconditionally recovers with an action. -- -- @since 0.2.0.0 resumingWith ::@@ -164,7 +164,7 @@   resume @err ma (const ma') {-# inline resumingWith #-} --- |Operator variant of 'resumingWith'.+-- | Operator variant of 'resumingWith'. -- -- @since 0.2.0.0 (<<!) ::@@ -177,7 +177,7 @@   resumingWith @err {-# inline (<<!) #-} --- |Variant of 'resume' that propagates the error to another 'Stop' effect after applying a function.+-- | Variant of 'resume' that propagates the error to another 'Stop' effect after applying a function. resumeHoist ::   ∀ err eff err' r a .   Members [Resumable err eff, Stop err'] r =>@@ -188,7 +188,7 @@   resuming (stop . f) {-# inline resumeHoist #-} --- |Variant of 'resumeHoist' that uses a constant value.+-- | Variant of 'resumeHoist' that uses a constant value. resumeHoistAs ::   ∀ err eff err' r .   Members [Resumable err eff, Stop err'] r =>@@ -198,7 +198,7 @@   resumeHoist @err (const err) {-# inline resumeHoistAs #-} --- |Variant of 'resumeHoist' that uses the unchanged error.+-- | Variant of 'resumeHoist' that uses the unchanged error. restop ::   ∀ err eff r .   Members [Resumable err eff, Stop err] r =>@@ -207,7 +207,7 @@   resumeHoist @err id {-# inline restop #-} --- |Variant of 'resume' that immediately produces an 'Either'.+-- | Variant of 'resume' that immediately produces an 'Either'. resumeEither ::   ∀ err eff r a .   Member (Resumable err eff) r =>@@ -216,7 +216,7 @@ resumeEither ma =   resuming (pure . Left) (Right <$> ma) --- |Variant of 'resume' that takes a branch for error and success.+-- | 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@@ -232,7 +232,7 @@     Right a -> fb a     Left e -> err e --- |Variant of 'resuming' that takes a branch for error and success.+-- | 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@@ -246,7 +246,7 @@ resumingOr err ma fb =   resumeOr ma fb err --- |Variant of 'resume' that propagates the error to an 'Error' effect after applying a function.+-- | Variant of 'resume' that propagates the error to an 'Error' effect after applying a function. resumeHoistError ::   ∀ err eff err' r a .   Members [Resumable err eff, Error err'] r =>@@ -257,7 +257,7 @@   resuming (throw . f) {-# inline resumeHoistError #-} --- |Variant of 'resumeHoistError' that uses the unchanged error.+-- | Variant of 'resumeHoistError' that uses the unchanged error. resumeHoistErrorAs ::   ∀ err eff err' r a .   Members [Resumable err eff, Error err'] r =>@@ -268,7 +268,7 @@   resumeHoistError @err (const err) {-# inline resumeHoistErrorAs #-} --- |Variant of 'resumeHoistError' that uses the unchanged error.+-- | Variant of 'resumeHoistError' that uses the unchanged error. resumeError ::   ∀ err eff r a .   Members [Resumable err eff, Error err] r =>@@ -277,3 +277,43 @@ resumeError =   resumeHoistError @err id {-# inline resumeError #-}++-- | Transform 'Stop' to 'Fail' using the supplied error message rendering function.+stopToFailWith ::+  ∀ err r .+  Member Fail r =>+  (err -> Text) ->+  InterpreterFor (Stop err) r+stopToFailWith f =+  either (fail . toString . f) pure <=< runStop+{-# inline stopToFailWith #-}++-- | Resume a computation, converting 'Stop' to 'Fail'.+resumeFailWith ::+  ∀ err eff r .+  Members [Fail, Resumable err eff] r =>+  (err -> Text) ->+  InterpreterFor eff r+resumeFailWith f =+  resuming (fail . toString . f)+{-# inline resumeFailWith #-}++-- | Transform 'Stop' to 'Fail' using 'show'.+stopToFail ::+  ∀ err r .+  Show err =>+  Member Fail r =>+  InterpreterFor (Stop err) r+stopToFail =+  stopToFailWith show+{-# inline stopToFail #-}++-- | Resume a computation, converting 'Stop' to 'Fail' using 'show'.+resumeFail ::+  ∀ err eff r .+  Show err =>+  Members [Fail, Resumable err eff] r =>+  InterpreterFor eff r+resumeFail =+  resumeFailWith @err show+{-# inline resumeFail #-}
− lib/Polysemy/Resume/Stop.hs
@@ -1,230 +0,0 @@-module Polysemy.Resume.Stop where--import qualified Control.Exception as Base-import Control.Exception (throwIO)-import Control.Monad.Trans.Except (ExceptT (ExceptT), runExceptT, throwE)-import Data.Typeable (typeRep)-import Polysemy.Final (getInitialStateS, interpretFinal, runS, withStrategicToFinal)-import Polysemy.Internal (Sem (Sem), usingSem)-import Polysemy.Internal.Union (Weaving (Weaving), decomp, hoist, weave)-import qualified Text.Show--import Polysemy.Resume.Effect.Stop (Stop (Stop), stop)--hush :: Either e a -> Maybe a-hush (Right a) = Just a-hush (Left _) = Nothing---- |Equivalent of 'runError'.-runStop ::-  Sem (Stop e : r) a ->-  Sem r (Either e a)-runStop (Sem m) =-  Sem \ k ->-    runExceptT $ m \ u ->-      case decomp u of-        Left x ->-          ExceptT $ k $ weave (Right ()) (either (pure . Left) runStop) hush x-        Right (Weaving (Stop e) _ _ _ _) ->-          throwE e-{-# inline runStop #-}--newtype StopExc e =-  StopExc { unStopExc :: e }-  deriving (Typeable)--instance {-# overlappable #-} Typeable e => Show (StopExc e) where-  show =-    mappend "StopExc: " . show . typeRep--instance Show (StopExc Text) where-  show (StopExc e) =-    "StopExc " <> show e--instance {-# overlappable #-} Typeable e => Exception (StopExc e)--instance Exception (StopExc Text)--runStopAsExcFinal ::-  Exception (StopExc e) =>-  Member (Final IO) r =>-  Sem (Stop e : r) a ->-  Sem r a-runStopAsExcFinal =-  interpretFinal \case-    Stop e ->-      pure (throwIO (StopExc e))-{-# inline runStopAsExcFinal #-}---- |Run 'Stop' by throwing exceptions.-stopToIOFinal ::-  Exception (StopExc e) =>-  Member (Final IO) r =>-  Sem (Stop e : r) a ->-  Sem r (Either e a)-stopToIOFinal sem =-  withStrategicToFinal @IO do-    m' <- runS (runStopAsExcFinal sem)-    s <- getInitialStateS-    pure $ either ((<$ s) . Left . unStopExc) (fmap Right) <$> Base.try m'-{-# inline stopToIOFinal #-}---- |Stop if the argument is 'Left', transforming the error with @f@.-stopEitherWith ::-  Member (Stop err') r =>-  (err -> err') ->-  Either err a ->-  Sem r a-stopEitherWith f =-  either (stop . f) pure-{-# inline stopEitherWith #-}---- |Stop if the argument is 'Left', using the supplied error.-stopEitherAs ::-  Member (Stop err') r =>-  err' ->-  Either err a ->-  Sem r a-stopEitherAs e =-  stopEitherWith (const e)-{-# inline stopEitherAs #-}---- |Stop if the argument is 'Left'.-stopEither ::-  Member (Stop err) r =>-  Either err a ->-  Sem r a-stopEither =-  stopEitherWith id-{-# inline stopEither #-}---- |Stop with the supplied error if the argument is 'Nothing'.-stopNote ::-  Member (Stop err) r =>-  err ->-  Maybe a ->-  Sem r a-stopNote err =-  maybe (stop err) pure-{-# inline stopNote #-}---- |Convert a program using regular 'Error's to one using 'Stop'.-stopOnError ::-  Member (Stop err) r =>-  Sem (Error err : r) a ->-  Sem r a-stopOnError =-  stopEither <=< runError-{-# inline stopOnError #-}---- |Convert a program using regular 'Error's to one using 'Stop'.-stopOnErrorWith ::-  Member (Stop err') r =>-  (err -> err') ->-  Sem (Error err : r) a ->-  Sem r a-stopOnErrorWith f =-  stopEitherWith f <=< runError-{-# inline stopOnErrorWith #-}---- |Convert a program using 'Stop' to one using 'Error', transforming the error with the supplied function.-stopToErrorWith ::-  Member (Error err') r =>-  (err -> err') ->-  Sem (Stop err : r) a ->-  Sem r a-stopToErrorWith f =-  either (throw . f) pure <=< runStop-{-# inline stopToErrorWith #-}---- |Convert a program using 'Stop' to one using 'Error'.-stopToError ::-  Member (Error err) r =>-  Sem (Stop err : r) a ->-  Sem r a-stopToError =-  stopToErrorWith id-{-# inline stopToError #-}---- |Convert a program using 'Stop' to one using 'Error'.-stopToErrorIO ::-  Exception (StopExc err) =>-  Members [Error err, Final IO] r =>-  Sem (Stop err : r) a ->-  Sem r a-stopToErrorIO =-  either throw pure <=< stopToIOFinal-{-# inline stopToErrorIO #-}---- |Map over the error type in a 'Stop'.-mapStop ::-  ∀ e e' r a .-  Member (Stop e') r =>-  (e -> e') ->-  Sem (Stop e : r) a ->-  Sem r a-mapStop f (Sem m) =-  Sem \ k -> m \ u ->-    case decomp u of-      Left x ->-        k (hoist (mapStop f) x)-      Right (Weaving (Stop e) _ _ _ _) ->-        usingSem k (send $ Stop (f e))-{-# inline mapStop #-}---- |Convert the error type in a 'Stop' to 'Text'.-showStop ::-  ∀ e r a .-  Show e =>-  Member (Stop Text) r =>-  Sem (Stop e : r) a ->-  Sem r a-showStop =-  mapStop @e @Text show-{-# inline showStop #-}---- |Convert an 'IO' exception to 'Stop' using the provided transformation.-stopTryIOE ::-  ∀ exc e r a .-  Exception exc =>-  Members [Stop e, Embed IO] r =>-  (exc -> e) ->-  IO a ->-  Sem r a-stopTryIOE f =-  stopEitherWith f <=< tryIOE @exc-{-# inline stopTryIOE #-}---- |Convert an 'IO' exception of type @e@ to 'Stop' using the provided transformation from 'Text'.-stopTryIO ::-  ∀ exc e r a .-  Exception exc =>-  Members [Stop e, Embed IO] r =>-  (Text -> e) ->-  IO a ->-  Sem r a-stopTryIO f =-  stopEitherWith f <=< tryIO @exc-{-# inline stopTryIO #-}---- |Convert an 'IO' exception of type 'IOError' to 'Stop' using the provided transformation from 'Text'.-stopTryIOError ::-  ∀ e r a .-  Members [Stop e, Embed IO] r =>-  (Text -> e) ->-  IO a ->-  Sem r a-stopTryIOError f =-  stopEitherWith f <=< tryIOError-{-# inline stopTryIOError #-}---- |Convert an 'IO' exception to 'Stop' using the provided transformation from 'Text'.-stopTryAny ::-  ∀ e r a .-  Members [Stop e, Embed IO] r =>-  (Text -> e) ->-  IO a ->-  Sem r a-stopTryAny f =-  stopEitherWith f <=< tryAny-{-# inline stopTryAny #-}
polysemy-resume.cabal view
@@ -1,11 +1,11 @@ cabal-version: 2.2 --- This file has been generated from package.yaml by hpack version 0.34.6.+-- This file has been generated from package.yaml by hpack version 0.35.0. -- -- see: https://github.com/sol/hpack  name:           polysemy-resume-version:        0.5.0.0+version:        0.6.0.0 synopsis:       Polysemy error tracking description:    See https://hackage.haskell.org/package/polysemy-resume/docs/Polysemy-Resume.html category:       Error@@ -17,6 +17,9 @@ license:        BSD-2-Clause-Patent license-file:   LICENSE build-type:     Simple+extra-source-files:+    changelog.md+    readme.md  source-repository head   type: git@@ -27,9 +30,10 @@       Polysemy.Resume       Polysemy.Resume.Effect.Resumable       Polysemy.Resume.Effect.Stop-      Polysemy.Resume.Resumable+      Polysemy.Resume.Interpreter.Resumable+      Polysemy.Resume.Interpreter.Scoped+      Polysemy.Resume.Interpreter.Stop       Polysemy.Resume.Resume-      Polysemy.Resume.Stop   hs-source-dirs:       lib   default-extensions:@@ -53,6 +57,7 @@       DisambiguateRecordFields       DoAndIfThenElse       DuplicateRecordFields+      EmptyCase       EmptyDataDecls       ExistentialQuantification       FlexibleContexts@@ -67,8 +72,9 @@       MultiParamTypeClasses       MultiWayIf       NamedFieldPuns-      OverloadedStrings+      OverloadedLabels       OverloadedLists+      OverloadedStrings       PackageImports       PartialTypeSignatures       PatternGuards@@ -95,8 +101,8 @@   ghc-options: -Wall -Wredundant-constraints -Wincomplete-uni-patterns -Wmissing-deriving-strategies -Widentities -Wunused-packages   build-depends:       base >=4.12 && <5-    , incipit-core >=0.3-    , polysemy >=1.6+    , incipit-core >=0.4+    , polysemy ==1.8.*     , transformers   mixins:       base hiding (Prelude)@@ -134,6 +140,7 @@       DisambiguateRecordFields       DoAndIfThenElse       DuplicateRecordFields+      EmptyCase       EmptyDataDecls       ExistentialQuantification       FlexibleContexts@@ -148,8 +155,9 @@       MultiParamTypeClasses       MultiWayIf       NamedFieldPuns-      OverloadedStrings+      OverloadedLabels       OverloadedLists+      OverloadedStrings       PackageImports       PartialTypeSignatures       PatternGuards@@ -176,16 +184,13 @@   ghc-options: -Wall -Wredundant-constraints -Wincomplete-uni-patterns -Wmissing-deriving-strategies -Widentities -Wunused-packages -threaded -rtsopts -with-rtsopts=-N   build-depends:       base >=4.12 && <5-    , hedgehog-    , incipit-core >=0.3-    , polysemy-    , polysemy-plugin+    , incipit-core >=0.4+    , polysemy ==1.8.*+    , polysemy-plugin >=0.4.3 && <0.5     , polysemy-resume     , polysemy-test >=0.6     , stm     , tasty-    , tasty-hedgehog-    , text   mixins:       base hiding (Prelude)     , incipit-core (IncipitCore as Prelude)
+ readme.md view
@@ -0,0 +1,205 @@+# About++This library provides the Polysemy effects 'Resumable' and 'Stop' for the+purpose of safely connecting throwing and catching errors across different+interpreters.++# Example++Given these two effects and an error:++```haskell+import Polysemy.Resume (Resumable, Stop, resumable, resumableFor, resume, runStop, stop)++data Stopper :: Effect where+  StopBang :: Stopper m ()+  StopBoom :: Stopper m ()++makeSem ''Stopper++data Resumer :: Effect where+  MainProgram :: Resumer m Int++makeSem ''Resumer++data Boom =+  Boom { unBoom :: Text }+  |+  Bang { unBang :: Int }+  deriving (Eq, Show)+```++we implement an interpreter for `Stopper` that may throw the error `Boom`, but+we do not want to hardcode that fact into the effect constructors, as in:++```haskell+data Stopper :: Effect where+  StopBang :: Stopper m (Either Boom ())+```++because we might want to provide alternative interpreters that do not have this+requirement, and `Boom` might contain information about the interpreter+implementation that we don't want to leak into the effect signature.++On the other hand, having no guarantee that the consumer program knows about or+catches the error requires us to manually ensure we handle them at the+appropriate location.+This is especially critical due to the fact that using `catch` requires an+`Error` membership, which in turn requires the `Error` to be handled outside of+the consumer again, hiding any new uses of the throwing interpreter in another+part of the program.++A first attempt at making this situation safer is to introduce a wrapping+effect:++```haskell+data Resumable err eff m a where+  Resumable ::+    ∀ err eff r a .+    Weaving eff (Sem r) a ->+    Resumable err eff (Sem r) (Either err a)+```++which we now use instead of the raw `eff` in consumers:++```haskell+interpretResumer ::+  Member (Resumable Boom Stopper) r =>+  InterpreterFor Resumer r+interpretResumer =+  interpret \ MainProgram ->+    resume (192 <$ stopBang) \ _ ->+      pure 237+```++For a nicer syntax, there is a type alias for `Resumable`:++```haskell+Member (Stopper !! Boom) r =>+```++We have now marked the interpreter for `Resumer`, which consumes `Stopper`, as+being capable of handling the `Boom` error when it occurs in `Stopper`.+The function `resume` takes an error handler as its second argument with which+we can catch `Boom`.++The interpreter for `Stopper` could look like this:++```haskell+interpretStopper ::+  Member (Stop Boom) r =>+  InterpreterFor Stopper r+interpretStopper =+  interpret \case+    StopBang -> stop (Bang 13)+    StopBoom -> stop (Boom "ouch")+```++Instead of `Error`, we are using `Stop` here, which is identical except for not+providing `Catch`.+This only serves to be more explicit about the intention of the error, but+a regular `Error` can be converted with `stopOnError`.++In order to convert this interpreter to a `Resumable`, we use `resumable`:++```haskell+>>> run $ resumable interpretStopper (interpretResumer mainProgram)+237+```++`resumable` weaves `interpretStopper` and its `Stop` together into+a `Resumable`, which is then consumed entirely by `resume` inside+`interpretResumer`, so no additional effects have to be handled.++## Higher-Order Effects++Converting an interpreter with `resumable` only works in rather simple+conditions.+If there are higher-order effects involved, you may get incorrect semantics,+for example when inserting a `finally` around the entire resumable program:++```haskell+resumable (interpretStopper (sem `finally` releaseResources))+```++In this case, `releaseResources` is executed after each use of `StopBang` or+`StopBoom`.+This requires the use of `interpretResumable` and `interpretResumableH`, which+take handler functions like `interpret`:++```haskell+interpretStopper ::+  InterpreterFor (Stopper !! Boom) r+interpretStopper =+  interpretResumable \case+    StopBang -> stop (Bang 13)+    StopBoom -> stop (Boom "ouch")+```++## Partial Error Handling++Of course, one requirement in the problem description still remains+unsatisfied: We might want to hide implementation details of `interpretStopper`+from consumers.+We can do that by transforming the `Boom` error into a more abstract version at+the interpretation site:++```haskell+newtype Blip =+  Blip { unBlip :: Int }+  deriving (Eq, Show)++bangOnly :: Boom -> Maybe Blip+bangOnly = \case+  Bang n -> Just (Blip n)+  Boom _ -> Nothing+```++Now `Boom` might have contained information about e.g. an http client backend,+and we're transforming that into an error that just says "http error".+If a consumer also deals with that backend, we might keep that information.++This modified error can now be used for `Resumable`.+First, we change the `Resumer` interpreter to use `Blip`:++```haskell+interpretResumerPartial ::+  Member (Resumable Blip Stopper) r =>+  InterpreterFor Resumer r+interpretResumerPartial =+  interpret \ MainProgram ->+    resume (192 <$ stopBang) \ (Blip num) ->+      pure (num * 3)+```++Then we use a different adapter function for `interpretStopper`:++```haskell+>>> runError (resumableFor bangOnly interpretStopper (interpretResumerPartial mainProgram))+Right 39+```++`resumableFor` transforms the error and passes it to the consumer if it is+a `Just`, and rethrows it if not.+Since the error was only partially handled and unhandled errors get thrown as+`Error`, we have to call `runError` on the result, to obtain an `Either`.++If the consumer uses a constructor that throws an unhandled variant of the+error, it propagates to the call site:++```haskell+interpretResumerPartialUnhandled ::+  Member (Resumable Blip Stopper) r =>+  InterpreterFor Resumer r+interpretResumerPartialUnhandled =+  interpret \ MainProgram ->+    resume (192 <$ stopBoom) \ (Blip num) ->+      pure (num * 3)++>>> runError ((resumableFor bangOnly interpretStopper) (interpretResumerPartialUnhandled mainProgram))+Left (Boom "ouch")+```++# Thanks++to @KingOfTheHomeless for providing the initial implementation and lots of consultation!
test/Polysemy/Resume/HigherOrderTest.hs view
@@ -7,7 +7,7 @@  import Polysemy.Resume (type (!!)) import Polysemy.Resume.Effect.Stop (stop)-import Polysemy.Resume.Resumable (interpretResumableH)+import Polysemy.Resume.Interpreter.Resumable (interpretResumableH) import Polysemy.Resume.Resume (resume)  data Eff :: Effect where
test/Polysemy/Resume/Test/InterceptTest.hs view
@@ -7,7 +7,7 @@  import Polysemy.Resume.Effect.Resumable (type (!!)) import Polysemy.Resume.Effect.Stop (stop)-import Polysemy.Resume.Resumable (interceptResumable, interpretResumable)+import Polysemy.Resume.Interpreter.Resumable (interceptResumable, interpretResumable) import Polysemy.Resume.Resume (restop, (!!), (<!))  data A :: Effect where