rhine-1.4: Functional Reactive Programming with type-level clocks
Safe HaskellSafe-Inferred
LanguageHaskell2010

FRP.Rhine.ClSF.Except

Description

This module provides exception handling, and thus control flow, to synchronous signal functions.

The API presented here closely follows automaton's Data.Automaton.Trans.Except, and reexports everything needed from there.

Synopsis

Documentation

type ClSFExcept cl a b m e = AutomatonExcept a b (ReaderT (TimeInfo cl) m) e Source #

A synchronous exception-throwing signal function.

It is based on a newtype from automaton, AutomatonExcept, to exhibit a monad interface in the exception type. return then corresponds to throwing an exception, and (>>=) is exception handling. (For more information, see the documentation of AutomatonExcept.)

  • cl: The clock on which the signal function ticks
  • a: The input type
  • b: The output type
  • m: The monad that the signal function may take side effects in
  • e: The type of exceptions that can be thrown

type BehaviourFExcept time a b m e = forall cl. time ~ Time cl => ClSFExcept cl a b m e Source #

A clock polymorphic ClSFExcept, or equivalently an exception-throwing behaviour. Any clock with time domain time may occur.

type BehaviorFExcept time a b m e = BehaviourFExcept time a b m e Source #

Compatibility to U.S. american spelling.

pass :: Monad m => Automaton (ExceptT e m) a a Source #

Do not throw an exception.

step :: Monad m => (a -> m (b, e)) -> ClSFExcept cl a b m e Source #

Advances a single tick with the given Kleisli arrow, and then throws an exception.

throwOnCond :: Monad m => (a -> Bool) -> e -> ClSF (ExceptT e m) cl a a Source #

Throw the exception e whenever the function evaluates to True.

throwOnCondM :: Monad m => (a -> m Bool) -> e -> ClSF (ExceptT e m) cl a a Source #

Variant of throwOnCond for Kleisli arrows. Throws the exception when the input is True.

throwOn :: Monad m => e -> ClSF (ExceptT e m) cl Bool () Source #

Throw the given exception when the Bool turns true.

throwOn' :: Monad m => ClSF (ExceptT e m) cl (Bool, e) () Source #

Variant of throwOn, where the exception can vary every tick.

throwMaybe :: Monad m => ClSF (ExceptT e m) cl (Maybe e) (Maybe a) Source #

When the input is Just e, throw the exception e.

throwS :: Monad m => ClSF (ExceptT e m) cl e a Source #

Immediately throw the incoming exception.

throw :: Monad m => e -> Automaton (ExceptT e m) a b Source #

Immediately throw the given exception.

try :: Monad m => ClSF (ExceptT e m) cl a b -> ClSFExcept cl a b m e Source #

Enter the monad context in the exception for ClSFs in the ExceptT monad. The ClSF will be run until it encounters an exception.

once :: Monad m => (a -> m e) -> ClSFExcept cl a b m e Source #

Within the same tick, perform a monadic action, and immediately throw the value as an exception.

once_ :: Monad m => m e -> ClSFExcept cl a b m e Source #

A variant of once without input.

runClSFExcept :: Monad m => ClSFExcept cl a b m e -> ClSF (ExceptT e m) cl a b Source #

Leave the monad context, to use the ClSFExcept as an Arrow.

safe :: forall (m :: Type -> Type) a b e. Monad m => Automaton m a b -> AutomatonExcept a b m e #

An Automaton without an ExceptT layer never throws an exception, and can thus have an arbitrary exception type.

In particular, the exception type can be Void, so it can be used as the last statement in an AutomatonExcept do-block. See safely for an example.

safely :: forall (m :: Type -> Type) a b. Monad m => AutomatonExcept a b m Void -> Automaton m a b #

If no exception can occur, the Automaton can be executed without the ExceptT layer.

Used to exit the AutomatonExcept context, often in combination with safe:

automaton = safely $ do
  e <- try someAutomaton
  once $ input -> putStrLn $ "Whoops, something happened when receiving input " ++ show input ++ ": " ++ show e ++ ", but I'll continue now."
  safe fallbackAutomaton

exceptS :: forall (m :: Type -> Type) e a b. (Functor m, Monad m) => Automaton (ExceptT e m) a b -> Automaton m a (Either e b) #

Escape an ExceptT layer by outputting the exception whenever it occurs.

If an exception occurs, the current state is is tested again on the next input.

runAutomatonExcept :: forall (m :: Type -> Type) a b e. Monad m => AutomatonExcept a b m e -> Automaton (ExceptT e m) a b #

currentInput :: forall (m :: Type -> Type) e b. Monad m => AutomatonExcept e b m e #

Immediately throw the current input as an exception.

Useful inside AutomatonExcept if you don't want to advance a further step in execution, but first see what the current input is before continuing.