Portability | non-portable (GHC extensions) |
---|---|
Stability | experimental |
Maintainer | nicolas.frisby@gmail.com |
A monad transformer for resumable exceptions. The ResumableT
transformer is
isomorphic to ReactT
, the dominant reactivity monad in the literature. The
differences serve to match the mtl
style.
- class Monad m => MonadResumable req res m | m -> req res where
- signal :: MonadResumable req res m => req -> m res
- respond :: MonadResumable req res m => (req -> m res) -> m a -> m a
- type Resumable scope req res = ResumableT scope req res Identity
- newtype ResumableT scope req res m a = ResumableT {
- unResumableT :: m (Either (req, res -> ResumableT scope req res m a) a)
- runResumableT :: Monad m => ResumableT scope req res m a -> m (req -> (res -> ResumableT scope req res m a) -> ResumableT scope req res m a) -> m a
- runResumableT_responder :: Monad m => ResumableT scope req res m a -> m (req -> ResumableT scope req res m res) -> m a
- runResumableT' :: Monad m => ResumableT scope req res m a -> (req -> (res -> ResumableT scope req res m a) -> ResumableT scope req res m a) -> m a
- runResumableT_responder' :: Monad m => ResumableT scope req res m a -> (req -> ResumableT scope req res m res) -> m a
- data Static
- data Dynamic
- asStatic :: ResumableT Static req res m a -> ResumableT Static req res m a
- asDynamic :: ResumableT Dynamic req res m a -> ResumableT Dynamic req res m a
- statically :: Scoped Static m => (ScopedAs Static m a -> ScopedAs Static m b) -> m a -> m b
- dynamically :: Scoped Dynamic m => (ScopedAs Dynamic m a -> ScopedAs Dynamic m b) -> m a -> m b
- mapResumableT_static :: (m (Either (req, res -> ResumableT scope req res m a) a) -> n (Either (req', res' -> ResumableT scope' req' res' n b) b)) -> ResumableT scope req res m a -> ResumableT scope' req' res' n b
- mapResumableT_dynamic :: (Monad m, Monad n) => (m (Either (req, res -> ResumableT scope req res m a) a) -> n (Either (req, res -> ResumableT scope req res m a) b)) -> ResumableT scope req res m a -> ResumableT scope req res n b
Monadic interface
class Monad m => MonadResumable req res m | m -> req res whereSource
A monadic interface for resumable exceptions.
yield :: req -> (res -> m a) -> m aSource
Raise the exception: a request and a resumption to use if the request can be handled.
handle :: m a -> (req -> (res -> m a) -> m a) -> m aSource
Installs a handler to quiesce an exception before it percolates to the higher-level handlers.
MonadResumable req res m => MonadResumable req res (ContT r m) | |
(Error e, MonadResumable req res m) => MonadResumable req res (ErrorT e m) | |
MonadResumable req res m => MonadResumable req res (StateT s m) | |
(Monoid w, MonadResumable req res m) => MonadResumable req res (WriterT w m) | |
MonadResumable req res m => MonadResumable req res (ReaderT r m) | |
(Monoid w, MonadResumable req res m) => MonadResumable req res (RWST r w s m) | |
Monad m => MonadResumable req res (ResumableT Dynamic req res m) | |
Monad m => MonadResumable req res (ResumableT Static req res m) |
signal :: MonadResumable req res m => req -> m resSource
Variation on yield
that immediately returns the result.
respond :: MonadResumable req res m => (req -> m res) -> m a -> m aSource
Variation on handle
that always applies the resumption.
Monad transformer
type Resumable scope req res = ResumableT scope req res IdentitySource
newtype ResumableT scope req res m a Source
ResumableT | |
|
Run functions
runResumableT :: Monad m => ResumableT scope req res m a -> m (req -> (res -> ResumableT scope req res m a) -> ResumableT scope req res m a) -> m aSource
The preferred top-level interface nevers allows exceptions to go unhandled.
runResumableT_responder :: Monad m => ResumableT scope req res m a -> m (req -> ResumableT scope req res m res) -> m aSource
This variation recognizes that the handling of requests primarily involves generating responses.
runResumableT' :: Monad m => ResumableT scope req res m a -> (req -> (res -> ResumableT scope req res m a) -> ResumableT scope req res m a) -> m aSource
The handler does not depend on the inner monad.
runResumableT_responder' :: Monad m => ResumableT scope req res m a -> (req -> ResumableT scope req res m res) -> m aSource
The responder does not depend on the inner monad.
Scope manipulation
(Monoid w, MonadReader r m, MonadState s m, MonadWriter w m) => MonadRWS r w s (ResumableT Static req res m) | |
Monad m => MonadResumable req res (ResumableT Static req res m) | |
MonadReader r m => MonadReader r (ResumableT Static req res m) | |
MonadError e m => MonadError e (ResumableT Static req res m) |
(Monoid w, MonadReader r m, MonadState s m, MonadWriter w m) => MonadRWS r w s (ResumableT Dynamic req res m) | |
Monad m => MonadResumable req res (ResumableT Dynamic req res m) | |
MonadReader r m => MonadReader r (ResumableT Dynamic req res m) | |
MonadError e m => MonadError e (ResumableT Dynamic req res m) |
asStatic :: ResumableT Static req res m a -> ResumableT Static req res m aSource
Establishes static scoping as default.
asDynamic :: ResumableT Dynamic req res m a -> ResumableT Dynamic req res m aSource
Establishes dynamic scoping as default.
dynamically :: Scoped Dynamic m => (ScopedAs Dynamic m a -> ScopedAs Dynamic m b) -> m a -> m bSource
Manipulating the inner monad
mapResumableT_static :: (m (Either (req, res -> ResumableT scope req res m a) a) -> n (Either (req', res' -> ResumableT scope' req' res' n b) b)) -> ResumableT scope req res m a -> ResumableT scope' req' res' n bSource
This manipulation of the inner monad acheives static scoping -- the manipulation is not preserved in the resumption.
mapResumableT_dynamic :: (Monad m, Monad n) => (m (Either (req, res -> ResumableT scope req res m a) a) -> n (Either (req, res -> ResumableT scope req res m a) b)) -> ResumableT scope req res m a -> ResumableT scope req res n bSource
This manipulation of the inner monad acheives dynamic scoping -- the manipulation is preserved in the resumption.