Safe Haskell | None |
---|---|
Language | Haskell2010 |
This effect allows you to "throw" a signal. For the most part signals are the same as checked
exceptions. The difference here is that the handler has the option to provide the value that
will be the result of calling the signal
function. This effectively allows you to have
recoverable exceptions at the throw site, instead of just at the handling site.
- data ResumeOrBreak b c
- data Signal a b
- throwSignal :: MonadEffect (Throw a) m => a -> m b
- handleSignal :: forall a b c m. Monad m => (a -> m (ResumeOrBreak b c)) -> RuntimeImplemented (Signal a b) (ExceptT c m) c -> m c
- type Throw e = Signal e Void
- handleException :: forall a c m. Monad m => (a -> m c) -> ExceptT a m c -> m c
- handleToEither :: forall e a m. ExceptT e m a -> m (Either e a)
- module Control.Effects
- module Control.Monad.Trans.Except
- newtype MaybeT (m :: * -> *) a :: (* -> *) -> * -> * = MaybeT {}
- discardAllExceptions :: MaybeT m a -> m (Maybe a)
- showAllExceptions :: Functor m => ExceptT SomeSignal m a -> m (Either Text a)
- data HandleException e
- handleWithoutDiscarding :: forall e m a. MonadEffect (HandleException e) m => (e -> m a) -> m a -> m a
- handleToEitherRecursive :: MonadEffect (HandleException e) m => m a -> m (Either e a)
- data SomeSignal
- signal :: forall a b m. MonadEffect (Signal a b) m => a -> m b
Documentation
data ResumeOrBreak b c Source #
The handle function will return a value of this type.
Generic (EffMethods (Signal a b) m) Source # | |
Effect (Signal a b) Source # | |
TypeError Constraint (UnhandledError a b) => MonadEffect (Signal a b) IO Source # | |
Monad m => MonadEffect (Signal a b) (MaybeT m) Source # | |
(Monad m, (~) * b c) => MonadEffect (Signal a c) (RuntimeImplemented (Signal a b) m) Source # | |
(Show e, Monad m) => MonadEffect (Signal e b) (ExceptT SomeSignal m) Source # | |
Monad m => MonadEffect (Signal e b) (ExceptT e m) Source # | |
type Rep (EffMethods (Signal a b) m) Source # | |
data EffMethods (Signal a b) Source # | |
type CanLift (Signal a b) t Source # | |
throwSignal :: MonadEffect (Throw a) m => a -> m b Source #
handleSignal :: forall a b c m. Monad m => (a -> m (ResumeOrBreak b c)) -> RuntimeImplemented (Signal a b) (ExceptT c m) c -> m c Source #
Handle signals of a computation. The handler function has the option to provide a value
to the caller of signal
and continue execution there, or do what regular exception handlers
do and continue execution after the handler.
handleException :: forall a c m. Monad m => (a -> m c) -> ExceptT a m c -> m c Source #
This handler can only behave like a regular exception handler. If used along with throwSignal
this module behaves like regular checked exceptions.
handleToEither :: forall e a m. ExceptT e m a -> m (Either e a) Source #
See documentation for handleException
. This handler gives you an Either
.
module Control.Effects
module Control.Monad.Trans.Except
newtype MaybeT (m :: * -> *) a :: (* -> *) -> * -> * #
The parameterizable maybe monad, obtained by composing an arbitrary
monad with the Maybe
monad.
Computations are actions that may produce a value or exit.
The return
function yields a computation that produces that
value, while >>=
sequences two subcomputations, exiting if either
computation does.
discardAllExceptions :: MaybeT m a -> m (Maybe a) Source #
showAllExceptions :: Functor m => ExceptT SomeSignal m a -> m (Either Text a) Source #
data HandleException e Source #
Effect (HandleException e) Source # | |
Monad m => MonadEffect (HandleException e) (ExceptT e m) Source # | |
data EffMethods (HandleException e) Source # | |
type CanLift (HandleException e) t Source # | |
handleWithoutDiscarding :: forall e m a. MonadEffect (HandleException e) m => (e -> m a) -> m a -> m a Source #
Use this function to handle exceptions without discarding the Throw
effect.
You'll want to use this if you're writing a recursive function. Using the regular handlers
in that case will result with infinite types.
Since this function doesn't discard constraints, you still need to handle the exception on the whole computation.
Here's a slightly contrived example.
data NotFound = NotFound data Tree a = Leaf a | Node (Tree a) (Tree a) data Step = GoLeft | GoRight findIndex :: (Handles NotFound m, Eq a) => a -> Tree a -> m [Step] findIndex x (Leaf a) | x == a = return [] | otherwise = throwSignal NotFound findIndex x (Node l r) = ((GoLeft :) $ findIndex x l) & handleWithoutDiscarding (NotFound -> (GoRight :) $ findIndex x r)
Note: When you finally handle the exception effect, the order in which you handle it and
other effects determines whether handleWithoutDiscarding
rolls back other effects if an exception
occured or it preserves all of them up to the point of the exception.
Handling exceptions last and handling them first will produce the former and latter
behaviour respectively.
handleToEitherRecursive :: MonadEffect (HandleException e) m => m a -> m (Either e a) Source #
handleToEither
that doesn't discard Throws
constraints. See documentation for
handleWithoutDiscarding
.
data SomeSignal Source #
Eq SomeSignal Source # | |
Ord SomeSignal Source # | |
Read SomeSignal Source # | |
Show SomeSignal Source # | |
(Show e, Monad m) => MonadEffect (Signal e b) (ExceptT SomeSignal m) Source # | |
signal :: forall a b m. MonadEffect (Signal a b) m => a -> m b Source #