Safe Haskell | None |
---|---|
Language | Haskell2010 |
See http://github.com/transient-haskell/transient Everything in this module is exported in order to allow extensibility.
Synopsis
- tshow :: a -> x -> x
- (!>) :: a -> b -> a
- tr :: Monad m => b -> m ()
- type StateIO = StateT EventF IO
- newtype TransIO a = Transient {}
- type SData = ()
- type EventId = Int
- type TransientIO = TransIO
- data LifeCycle
- data EventF = EventF {
- event :: Maybe SData
- xcomp :: TransIO a
- fcomp :: [b -> TransIO b]
- mfData :: Map TypeRep SData
- mfSequence :: Int
- threadId :: ThreadId
- freeTh :: Bool
- parent :: Maybe EventF
- children :: MVar [EventF]
- maxThread :: Maybe (IORef Int)
- labelth :: IORef (LifeCycle, ByteString)
- parseContext :: ParseContext
- execMode :: ExecMode
- data ParseContext = ParseContext {
- more :: TransIO (StreamData ByteString)
- buffer :: ByteString
- done :: IORef Bool
- class MonadState EventF m => TransMonad m
- noTrans :: StateIO x -> TransIO x
- liftTrans :: StateIO (Maybe b) -> TransIO b
- emptyEventF :: ThreadId -> IORef (LifeCycle, ByteString) -> MVar [EventF] -> EventF
- runTransient :: TransIO a -> IO (Maybe a, EventF)
- runTransState :: EventF -> TransIO x -> IO (Maybe x, EventF)
- emptyIfNothing :: Maybe a -> TransIO a
- getCont :: TransIO EventF
- runCont :: EventF -> StateIO (Maybe a)
- runCont' :: EventF -> IO (Maybe a, EventF)
- getContinuations :: StateIO [a -> TransIO b]
- compose :: [a -> TransIO a] -> a -> TransIO b
- runClosure :: EventF -> StateIO (Maybe a)
- runContinuation :: EventF -> a -> StateIO (Maybe b)
- setContinuation :: TransIO a -> (a -> TransIO b) -> [c -> TransIO c] -> StateIO ()
- withContinuation :: b -> TransIO a -> TransIO a
- restoreStack :: TransMonad m => [a -> TransIO a] -> m ()
- runContinuations :: [a -> TransIO b] -> c -> TransIO d
- data ExecMode
- fullStop :: TransIO stop
- mappendt :: (Applicative f, Monoid b) => f b -> f b -> f b
- readWithErr :: (Typeable a, Read a) => Int -> String -> IO [(a, String)]
- newtype ParseError = ParseError String
- read' :: (Typeable p, Read p) => String -> p
- readsPrec' :: (Typeable a, Read a) => Int -> String -> [(a, String)]
- stop :: Alternative m => m stopped
- class AdditionalOperators m where
- (<|) :: TransIO a -> TransIO b -> TransIO a
- setEventCont :: TransIO a -> (a -> TransIO b) -> StateIO ()
- resetEventCont :: MonadState EventF m => Maybe t -> m ()
- tailsafe :: [a] -> [a]
- waitQSemB :: (Ord a, Num a) => Bool -> IORef a -> IO Bool
- signalQSemB :: Num a => IORef a -> IO ()
- threads :: Int -> TransIO a -> TransIO a
- cloneInChild :: (MonadState EventF m, MonadIO m) => [Char] -> m EventF
- removeChild :: (MonadIO m, TransMonad m) => m ()
- oneThread :: TransIO a -> TransIO a
- labelState :: (MonadIO m, TransMonad m) => ByteString -> m ()
- threadState :: ByteString -> TransIO ThreadId
- killState :: (MonadIO m, Alternative m, MonadState EventF m) => ByteString -> m ()
- printBlock :: MVar ()
- showThreads :: MonadIO m => EventF -> m ()
- topState :: TransMonad m => m EventF
- findState :: (MonadIO m, Alternative m) => (EventF -> m Bool) -> EventF -> m EventF
- getStateFromThread :: (Typeable a, MonadIO m, Alternative m) => String -> EventF -> m (Maybe a)
- processStates :: Typeable a => (a -> TransIO ()) -> EventF -> TransIO ()
- addThreads' :: Int -> TransIO ()
- addThreads :: Int -> TransIO ()
- freeThreads :: TransIO a -> TransIO a
- hookedThreads :: TransIO a -> TransIO a
- killChilds :: TransIO ()
- killBranch :: TransIO ()
- killBranch' :: EventF -> IO ()
- getData :: (TransMonad m, Typeable a) => m (Maybe a)
- getSData :: Typeable a => TransIO a
- getState :: Typeable a => TransIO a
- setData :: (TransMonad m, Typeable a) => a -> m ()
- modifyData :: (TransMonad m, Typeable a) => (Maybe a -> Maybe a) -> m ()
- modifyData' :: (TransMonad m, Typeable a) => (a -> a) -> a -> m a
- modifyState :: (TransMonad m, Typeable a) => (Maybe a -> Maybe a) -> m ()
- setState :: (TransMonad m, Typeable a) => a -> m ()
- delData :: (TransMonad m, Typeable a) => a -> m ()
- delState :: (TransMonad m, Typeable a) => a -> m ()
- newtype Ref a = Ref (IORef a)
- newRState :: (MonadIO m, TransMonad m, Typeable a) => a -> m (IORef a)
- setRState :: (MonadIO m, TransMonad m, Typeable a) => a -> m ()
- getRData :: (MonadIO m, TransMonad m, Typeable a) => m (Maybe a)
- getRState :: Typeable a => TransIO a
- delRState :: (MonadState EventF m, Typeable a) => a -> m ()
- try :: TransIO a -> TransIO a
- sandbox :: TransIO a -> TransIO a
- genGlobalId :: MonadIO m => m Int
- rglobalId :: IORef Int
- genId :: TransMonad m => m Int
- getPrevId :: TransMonad m => m Int
- data StreamData a
- = SMore a
- | SLast a
- | SDone
- | SError SomeException
- waitEvents :: IO a -> TransIO a
- async :: IO a -> TransIO a
- sync :: TransIO a -> TransIO a
- spawn :: IO a -> TransIO a
- sample :: Eq a => IO a -> Int -> TransIO a
- abduce :: TransIO ()
- fork :: TransIO () -> TransIO ()
- parallel :: IO (StreamData b) -> TransIO (StreamData b)
- loop :: EventF -> IO (StreamData t) -> IO ()
- free :: ThreadId -> EventF -> IO ()
- hangThread :: EventF -> EventF -> IO ()
- killChildren :: MVar [EventF] -> IO ()
- react :: ((eventdata -> IO response) -> IO ()) -> IO response -> TransIO eventdata
- option :: (Typeable b, Show b, Read b, Eq b) => b -> String -> TransIO b
- option1 :: (Typeable b, Show b, Read b, Eq b) => b -> String -> TransIO b
- optionf :: (Typeable b, Show b, Read b, Eq b) => Bool -> b -> String -> TransIO b
- inputf :: (Show a, Read a, Typeable a) => Bool -> String -> String -> Maybe a -> (a -> Bool) -> TransIO a
- input :: (Typeable a, Read a, Show a) => (a -> Bool) -> String -> TransIO a
- input' :: (Typeable a, Read a, Show a) => Maybe a -> (a -> Bool) -> String -> TransIO a
- rcb :: IORef [(String, String, String -> IO ())]
- addConsoleAction :: String -> String -> (String -> IO ()) -> IO ()
- delConsoleAction :: String -> IO ()
- reads1 :: (Typeable a, Read a) => [Char] -> [(a, String)]
- read1 :: (Typeable a, Read a) => [Char] -> a
- rprompt :: IORef [Char]
- inputLoop :: IO a
- rconsumed :: IORef Bool
- lineprocessmode :: IORef Bool
- processLine :: [Char] -> IO ()
- breakSlash :: [String] -> String -> [String]
- tail1 :: [a] -> [a]
- stay :: MVar (Maybe a) -> IO (Maybe a)
- newtype Exit a = Exit a
- keep :: Typeable a => TransIO a -> IO (Maybe a)
- keep' :: Typeable a => TransIO a -> IO (Maybe a)
- execCommandLine :: IO ()
- exit :: Typeable a => a -> TransIO a
- onNothing :: Monad m => m (Maybe b) -> m b -> m b
- data Backtrack b = Show b => Backtrack {
- backtracking :: Maybe b
- backStack :: [EventF]
- backCut :: (Typeable b, Show b) => b -> TransientIO ()
- undoCut :: TransientIO ()
- onBack :: (Typeable b, Show b) => TransientIO a -> (b -> TransientIO a) -> TransientIO a
- onUndo :: TransientIO a -> TransientIO a -> TransientIO a
- registerBack :: (Typeable b, Show b) => b -> TransientIO a -> TransientIO a
- registerUndo :: TransientIO a -> TransientIO a
- forward :: (Typeable b, Show b) => b -> TransIO ()
- backtrack :: TransIO a
- retry :: TransIO ()
- noFinish :: TransIO ()
- back :: (Typeable b, Show b) => b -> TransIO a
- backStateOf :: (Show a, Typeable a) => a -> Backtrack a
- data BackPoint a = BackPoint (IORef [a -> TransIO ()])
- backPoint :: (Typeable reason, Show reason) => TransIO (BackPoint reason)
- onBackPoint :: MonadIO m => BackPoint t -> (t -> TransIO ()) -> m ()
- undo :: TransIO a
- newtype Finish = Finish String
- onFinish :: (Finish -> TransIO ()) -> TransIO ()
- onFinish' :: TransIO a -> (Finish -> TransIO a) -> TransIO a
- initFinish :: TransIO ()
- finish :: String -> TransIO ()
- checkFinalize :: StreamData a -> TransIO a
- onException :: Exception e => (e -> TransIO ()) -> TransIO ()
- exceptionPoint :: Exception e => TransIO (BackPoint e)
- onExceptionPoint :: Exception e => BackPoint e -> (e -> TransIO ()) -> TransIO ()
- onException' :: Exception e => TransIO a -> (e -> TransIO a) -> TransIO a
- exceptBack :: EventF -> SomeException -> IO (Maybe a, EventF)
- whileException :: Exception e => TransIO b -> (e -> TransIO ()) -> TransIO b
- cutExceptions :: TransIO ()
- continue :: TransIO ()
- catcht :: Exception e => TransIO b -> (e -> TransIO b) -> TransIO b
- catcht' :: Exception e => TransIO b -> (e -> TransIO b) -> TransIO b
- throwt :: Exception e => e -> TransIO a
Documentation
Instances
Monad TransIO Source # | |
Functor TransIO Source # | |
MonadFail TransIO Source # | |
Defined in Transient.Internals | |
Applicative TransIO Source # | |
MonadIO TransIO Source # | |
Defined in Transient.Internals | |
Alternative TransIO Source # | |
MonadPlus TransIO Source # | |
AdditionalOperators TransIO Source # | |
MonadState EventF TransIO Source # | |
(Num a, Eq a, Fractional a) => Fractional (TransIO a) Source # | |
(Num a, Eq a) => Num (TransIO a) Source # | |
Monoid a => Semigroup (TransIO a) Source # | |
Monoid a => Monoid (TransIO a) Source # | |
type TransientIO = TransIO Source #
EventF describes the context of a TransientIO computation:
EventF | |
|
data ParseContext Source #
ParseContext | |
|
class MonadState EventF m => TransMonad m Source #
To define primitives for all the transient monads: TransIO, Cloud and Widget
Instances
MonadState EventF m => TransMonad m Source # | |
Defined in Transient.Internals |
noTrans :: StateIO x -> TransIO x Source #
Run a computation in the underlying state monad. it is a little lighter and performant and it should not contain advanced effects beyond state.
liftTrans :: StateIO (Maybe b) -> TransIO b Source #
filters away the Nothing responses of the State monad.
in principle the state monad should return a single response, but, for performance reasons,
it can run inside elements of transient monad (using runTrans
) which may produce
many results
emptyEventF :: ThreadId -> IORef (LifeCycle, ByteString) -> MVar [EventF] -> EventF Source #
runTransient :: TransIO a -> IO (Maybe a, EventF) Source #
Run a transient computation with a default initial state
runTransState :: EventF -> TransIO x -> IO (Maybe x, EventF) Source #
Run a transient computation with a given initial state
emptyIfNothing :: Maybe a -> TransIO a Source #
getCont :: TransIO EventF Source #
Get the continuation context: closure, continuation, state, child threads etc
runCont :: EventF -> StateIO (Maybe a) Source #
Run the closure and the continuation using the state data of the calling thread
runCont' :: EventF -> IO (Maybe a, EventF) Source #
Run the closure and the continuation using its own state data.
getContinuations :: StateIO [a -> TransIO b] Source #
Warning: Radically untyped stuff. handle with care
runClosure :: EventF -> StateIO (Maybe a) Source #
Run the closure (the x
in 'x >>= f') of the current bind operation.
runContinuation :: EventF -> a -> StateIO (Maybe b) Source #
Run the continuation (the f
in 'x >>= f') of the current bind operation with the current state.
setContinuation :: TransIO a -> (a -> TransIO b) -> [c -> TransIO c] -> StateIO () Source #
Save a closure and a continuation (x
and f
in 'x >>= f').
withContinuation :: b -> TransIO a -> TransIO a Source #
Save a closure and continuation, run the closure, restore the old continuation. | NOTE: The old closure is discarded.
restoreStack :: TransMonad m => [a -> TransIO a] -> m () Source #
Restore the continuations to the provided ones. | NOTE: Events are also cleared out.
runContinuations :: [a -> TransIO b] -> c -> TransIO d Source #
Run a chain of continuations.
WARNING: It is up to the programmer to assure that each continuation typechecks
with the next, and that the parameter type match the input of the first
continuation.
NOTE: Normally this makes sense to stop the current flow with stop
after the
invocation.
fullStop :: TransIO stop Source #
stop the current computation and does not execute any alternative computation
mappendt :: (Applicative f, Monoid b) => f b -> f b -> f b Source #
newtype ParseError Source #
Instances
Show ParseError Source # | |
Defined in Transient.Internals showsPrec :: Int -> ParseError -> ShowS # show :: ParseError -> String # showList :: [ParseError] -> ShowS # | |
Exception ParseError Source # | |
Defined in Transient.Internals toException :: ParseError -> SomeException # fromException :: SomeException -> Maybe ParseError # displayException :: ParseError -> String # |
stop :: Alternative m => m stopped Source #
A synonym of empty
that can be used in a monadic expression. It stops
the computation, which allows the next computation in an Alternative
(<|>
) composition to run.
class AdditionalOperators m where Source #
(**>) :: m a -> m b -> m b infixl 4 Source #
Run m a
discarding its result before running m b
.
(<**) :: m a -> m b -> m a infixl 4 Source #
Run m b
discarding its result, after the whole task set m a
is
done.
atEnd' :: m a -> m b -> m a Source #
(<***) :: m a -> m b -> m a infixl 4 Source #
Run m b
discarding its result, once after each task in m a
, and
once again after the whole task set is done.
Instances
AdditionalOperators TransIO Source # | |
(<|) :: TransIO a -> TransIO b -> TransIO a Source #
Run b
once, discarding its result when the first task in task set a
has finished. Useful to start a singleton task after the first task has been
setup.
setEventCont :: TransIO a -> (a -> TransIO b) -> StateIO () Source #
Set the current closure and continuation for the current statement
resetEventCont :: MonadState EventF m => Maybe t -> m () Source #
Reset the closure and continuation. Remove inner binds than the previous computations may have stacked in the list of continuations. resetEventCont :: Maybe a -> EventF -> StateIO ()
tailsafe :: [a] -> [a] Source #
Total variant of tail
that returns an empty list when given an empty list.
Threads
threads :: Int -> TransIO a -> TransIO a Source #
Sets the maximum number of threads that can be created for the given task
set. When set to 0, new tasks start synchronously in the current thread.
New threads are created by parallel
, and APIs that use parallel.
cloneInChild :: (MonadState EventF m, MonadIO m) => [Char] -> m EventF Source #
removeChild :: (MonadIO m, TransMonad m) => m () Source #
oneThread :: TransIO a -> TransIO a Source #
Terminate all the child threads in the given task set and continue execution in the current thread. Useful to reap the children when a task is done, restart a task when a new event happens etc.
labelState :: (MonadIO m, TransMonad m) => ByteString -> m () Source #
Add a label to the current passing threads so it can be printed by debugging calls like showThreads
threadState :: ByteString -> TransIO ThreadId Source #
return the threadId associated with an state (you can see all of them with the console option ps
)
killState :: (MonadIO m, Alternative m, MonadState EventF m) => ByteString -> m () Source #
kill the thread subtree labeled as such (you can see all of them with the console option ps
)
printBlock :: MVar () Source #
showThreads :: MonadIO m => EventF -> m () Source #
Show the tree of threads hanging from the state.
topState :: TransMonad m => m EventF Source #
Return the state of the thread that initiated the transient computation topState :: TransIO EventF
findState :: (MonadIO m, Alternative m) => (EventF -> m Bool) -> EventF -> m EventF Source #
find the first computation state which match a filter in the subthree of states
getStateFromThread :: (Typeable a, MonadIO m, Alternative m) => String -> EventF -> m (Maybe a) Source #
Return the state variable of the type desired for a thread number
processStates :: Typeable a => (a -> TransIO ()) -> EventF -> TransIO () Source #
execute all the states of the type desired that are created by direct child threads
addThreads' :: Int -> TransIO () Source #
Add n threads to the limit of threads. If there is no limit, the limit is set.
addThreads :: Int -> TransIO () Source #
Ensure that at least n threads are available for the current task set.
freeThreads :: TransIO a -> TransIO a Source #
Disable tracking and therefore the ability to terminate the child threads. By default, child threads are terminated automatically when the parent thread dies, or they can be terminated using the kill primitives. Disabling it may improve performance a bit, however, all threads must be well-behaved to exit on their own to avoid a leak.
hookedThreads :: TransIO a -> TransIO a Source #
Enable tracking and therefore the ability to terminate the child threads.
This is the default but can be used to re-enable tracking if it was
previously disabled with freeThreads
.
killChilds :: TransIO () Source #
Kill all the child threads of the current thread.
killBranch :: TransIO () Source #
Kill the current thread and the childs.
killBranch' :: EventF -> IO () Source #
Kill the childs and the thread of an state
Extensible State: Session Data Management
getSData :: Typeable a => TransIO a Source #
Retrieve a previously stored data item of the given data type from the
monad state. The data type to retrieve is implicitly determined by the data type.
If the data item is not found, empty is executed, so the alternative computation will be executed, if any.
Otherwise, the computation will stop.
If you want to print an error message or return a default value, you can use an Alternative
composition. For example:
getSData <|> error "no data of the type desired" getInt = getSData <|> return (0 :: Int)
The later return either the value set or 0.
It is highly recommended not to use it directly, since his relatively complex behaviour may be confusing sometimes. Use instead a monomorphic alias like "getInt" defined above.
setData :: (TransMonad m, Typeable a) => a -> m () Source #
setData
stores a data item in the monad state which can be retrieved
later using getData
or getSData
. Stored data items are keyed by their
data type, and therefore only one item of a given type can be stored. A
newtype wrapper can be used to distinguish two data items of the same type.
import Control.Monad.IO.Class (liftIO) import Transient.Base import Data.Typeable data Person = Person { name :: String , age :: Int } deriving Typeable main = keep $ do setData $ Person Alberto 55 Person name age <- getSData liftIO $ print (name, age)
modifyData :: (TransMonad m, Typeable a) => (Maybe a -> Maybe a) -> m () Source #
Accepts a function which takes the current value of the stored data type
and returns the modified value. If the function returns Nothing
the value
is deleted otherwise updated.
modifyData' :: (TransMonad m, Typeable a) => (a -> a) -> a -> m a Source #
Either modify according with the first parameter or insert according with the second, depending on if the data exist or not. It returns the old value or the new value accordingly.
runTransient $ do modifyData' (\h -> h ++ " world") "hello new" ; r <- getSData ; liftIO $ putStrLn r -- > "hello new" runTransient $ do setData "hello" ; modifyData' (\h -> h ++ " world") "hello new" ; r <- getSData ; liftIO $ putStrLn r -- > "hello world"
modifyState :: (TransMonad m, Typeable a) => (Maybe a -> Maybe a) -> m () Source #
Same as modifyData
delData :: (TransMonad m, Typeable a) => a -> m () Source #
Delete the data item of the given type from the monad state.
newRState :: (MonadIO m, TransMonad m, Typeable a) => a -> m (IORef a) Source #
Initializes a new mutable reference (similar to STRef in the state monad) It is polimorphic. Each type has his own reference It return the associated IORef, so it can be updated in the IO monad
setRState :: (MonadIO m, TransMonad m, Typeable a) => a -> m () Source #
mutable state reference that can be updated (similar to STRef in the state monad) They are identified by his type. Initialized the first time it is set.
try :: TransIO a -> TransIO a Source #
Run an action, if it does not succeed, undo any state changes that may have been caused by the action and allow aternative actions to run with the original state
sandbox :: TransIO a -> TransIO a Source #
Executes the computation and reset the state either if it fails or not.
genGlobalId :: MonadIO m => m Int Source #
generates an identifier that is unique within the current program execution
genId :: TransMonad m => m Int Source #
Generator of identifiers that are unique within the current monadic sequence They are not unique in the whole program.
getPrevId :: TransMonad m => m Int Source #
data StreamData a Source #
StreamData
represents an result in an stream being generated.
SMore a | More to come |
SLast a | This is the last one |
SDone | No more, we are done |
SError SomeException | An error occurred |
Instances
Functor StreamData Source # | |
Defined in Transient.Internals fmap :: (a -> b) -> StreamData a -> StreamData b # (<$) :: a -> StreamData b -> StreamData a # | |
Read a => Read (StreamData a) Source # | |
Defined in Transient.Internals readsPrec :: Int -> ReadS (StreamData a) # readList :: ReadS [StreamData a] # readPrec :: ReadPrec (StreamData a) # readListPrec :: ReadPrec [StreamData a] # | |
Show a => Show (StreamData a) Source # | |
Defined in Transient.Internals showsPrec :: Int -> StreamData a -> ShowS # show :: StreamData a -> String # showList :: [StreamData a] -> ShowS # |
waitEvents :: IO a -> TransIO a Source #
A task stream generator that produces an infinite stream of results by
running an IO computation in a loop, each result may be processed in different threads (tasks)
depending on the thread limits stablished with threads
.
async :: IO a -> TransIO a Source #
Run an IO computation asynchronously carrying the result of the computation in a new thread when it completes. If there are no threads available, the async computation and his continuation is executed in the same thread before any alternative computation.
sync :: TransIO a -> TransIO a Source #
Avoid the execution of alternative computations when the computation is asynchronous
sync (async whatever) <|> liftIO (print "hello") -- never print "hello"
spawn :: IO a -> TransIO a Source #
create task threads faster, but with no thread control: spawn = freeThreads . waitEvents
sample :: Eq a => IO a -> Int -> TransIO a Source #
An stream generator that run an IO computation periodically at the specified time interval. The task carries the result of the computation. A new result is generated only if the output of the computation is different from the previous one.
Runs the rest of the computation in a new thread. Returns empty
to the current thread
fork :: TransIO () -> TransIO () Source #
fork an independent process. It is equivalent to forkIO. The thread created is managed with the thread control primitives of transient
parallel :: IO (StreamData b) -> TransIO (StreamData b) Source #
Run an IO action one or more times to generate a stream of tasks. The IO
action returns a StreamData
. When it returns an SMore
or SLast
a new
result is returned with the result value. If there are threads available, the res of the
computation is executed in a new thread. If the return value is SMore
, the
action is run again to generate the next result, otherwise task creation
stop.
Unless the maximum number of threads (set with threads
) has been reached,
the task is generated in a new thread and the current thread returns a void
task.
killChildren :: MVar [EventF] -> IO () Source #
kill all the child threads associated with the continuation context
react :: ((eventdata -> IO response) -> IO ()) -> IO response -> TransIO eventdata Source #
capture a callback handler so that the execution of the current computation continues whenever an event occurs. The effect is called "de-inversion of control"
The first parameter is a callback setter. The second parameter is a value to be
returned to the callback; if the callback expects no return value it
can just be return ()
. The callback setter expects a function taking the
eventdata
as an argument and returning a value; this
function is the continuation, which is supplied by react
.
Callbacks from foreign code can be wrapped into such a handler and hooked
into the transient monad using react
. Every time the callback is called it
continues the execution on the current transient computation.
do event <- react onEvent $ return () ....
Non-blocking keyboard input
option :: (Typeable b, Show b, Read b, Eq b) => b -> String -> TransIO b Source #
listen stdin and triggers a new task every time the input data matches the first parameter. The value contained by the task is the matched value i.e. the first argument itself. The second parameter is a message for the user. The label is displayed in the console when the option match.
inputf :: (Show a, Read a, Typeable a) => Bool -> String -> String -> Maybe a -> (a -> Bool) -> TransIO a Source #
General asynchronous console input.
inputf input listener after sucessful or not identifier prompt default value proc
input :: (Typeable a, Read a, Show a) => (a -> Bool) -> String -> TransIO a Source #
Waits on stdin and return a value when a console input matches the predicate specified in the first argument. The second parameter is a string to be displayed on the console before waiting.
input' :: (Typeable a, Read a, Show a) => Maybe a -> (a -> Bool) -> String -> TransIO a Source #
input
with a default value
delConsoleAction :: String -> IO () Source #
processLine :: [Char] -> IO () Source #
stay :: MVar (Maybe a) -> IO (Maybe a) Source #
Wait for the execution of exit
and return the result or the exhaustion of thread activity
keep :: Typeable a => TransIO a -> IO (Maybe a) Source #
Runs the transient computation in a child thread and keeps the main thread
running until all the user threads exit or some thread exit
.
The main thread provides facilities for accepting keyboard input in a
non-blocking but line-oriented manner. The program reads the standard input
and feeds it to all the async input consumers (e.g. option
and input
).
All async input consumers contend for each line entered on the standard
input and try to read it atomically. When a consumer consumes the input
others do not get to see it, otherwise it is left in the buffer for others
to consume. If nobody consumes the input, it is discarded.
A /
in the input line is treated as a newline.
When using asynchronous input, regular synchronous IO APIs like getLine cannot be used as they will contend for the standard input along with the asynchronous input thread. Instead you can use the asynchronous input APIs provided by transient.
A built-in interactive command handler also reads the stdin asynchronously. All available options waiting for input are displayed when the program is run. The following commands are available:
ps
: show threadslog
: inspect the log of a threadend
,exit
: terminate the program
An input not handled by the command handler can be handled by the program.
The program's command line is scanned for -p
or --path
command line
options. The arguments to these options are injected into the async input
channel as keyboard input to the program. Each line of input is separated by
a /
. For example:
foo -p ps/end
keep' :: Typeable a => TransIO a -> IO (Maybe a) Source #
Same as keep
but does not read from the standard input, and therefore
the async input APIs (option
and input
) cannot respond interactively.
However, input can still be passed via command line arguments as
described in keep
. Useful for debugging or for creating background tasks,
as well as to embed the Transient monad inside another computation. It
returns either the value returned by exit
or Nothing, when there are no
more threads running
execCommandLine :: IO () Source #
exit :: Typeable a => a -> TransIO a Source #
Exit the main thread with a result, and thus all the Transient threads (and the application if there is no more code)
onNothing :: Monad m => m (Maybe b) -> m b -> m b Source #
If the first parameter is Nothing
return the second parameter otherwise
return the first parameter..
backCut :: (Typeable b, Show b) => b -> TransientIO () Source #
Delete all the undo actions registered till now for the given track id.
undoCut :: TransientIO () Source #
backCut
for the default track; equivalent to backCut ()
.
onBack :: (Typeable b, Show b) => TransientIO a -> (b -> TransientIO a) -> TransientIO a Source #
Run the action in the first parameter and register the second parameter as
the undo action. On undo (back
) the second parameter is called with the
undo track id as argument.
onUndo :: TransientIO a -> TransientIO a -> TransientIO a Source #
onBack
for the default track; equivalent to onBack ()
.
registerBack :: (Typeable b, Show b) => b -> TransientIO a -> TransientIO a Source #
Register an undo action to be executed when backtracking. The first parameter is a "witness" whose data type is used to uniquely identify this backtracking action. The value of the witness parameter is not used.
registerUndo :: TransientIO a -> TransientIO a Source #
forward :: (Typeable b, Show b) => b -> TransIO () Source #
For a given undo track type, stop executing more backtracking actions and resume normal execution in the forward direction. Used inside an undo action.
backtrack :: TransIO a Source #
put at the end of an backtrack handler intended to backtrack to other previous handlers.
This is the default behaviour in transient. backtrack
is in order to keep the type compiler happy
noFinish :: TransIO () Source #
Abort finish. Stop executing more finish actions and resume normal
execution. Used inside onFinish
actions.
back :: (Typeable b, Show b) => b -> TransIO a Source #
Start the undo process for a given undo track identifier type. Performs all the undo
actions registered for that type in reverse order. An undo action can use
forward
to stop the undo process and resume forward execution. If there
are no more undo actions registered, execution stop
backPoint :: (Typeable reason, Show reason) => TransIO (BackPoint reason) Source #
a backpoint is a location in the code where callbacks can be installed and will be called when the backtracing pass trough that point. Normally used for exceptions.
onBackPoint :: MonadIO m => BackPoint t -> (t -> TransIO ()) -> m () Source #
install a callback in a backPoint
Instances
Show Finish Source # | |
Exception Finish Source # | |
Defined in Transient.Internals toException :: Finish -> SomeException # fromException :: SomeException -> Maybe Finish # displayException :: Finish -> String # |
onFinish' :: TransIO a -> (Finish -> TransIO a) -> TransIO a Source #
Run the action specified in the first parameter and register the second
parameter as a finish action to be run when finish
is called. Used in
infix style.
initFinish :: TransIO () Source #
Execute all the finalization actions registered up to the last
initFinish
, in reverse order and continue the execution. Either an exception or Nothing
can be
checkFinalize :: StreamData a -> TransIO a Source #
trigger finish when the stream of data ends
onException :: Exception e => (e -> TransIO ()) -> TransIO () Source #
Install an exception handler. Handlers are executed in reverse (i.e. last in, first out) order when such exception happens in the continuation. Note that multiple handlers can be installed for the same exception type.
The semantic is, thus, very different than the one of onException
exceptionPoint :: Exception e => TransIO (BackPoint e) Source #
set an exception point. Thi is a point in the backtracking in which exception handlers can be inserted with onExceptionPoint
it is an specialization of backPoint
for exceptions.
When an exception backtracking reach the backPoint it executes all the handlers registered for it.
Use case: suppose that when a connection fails, you need to stop a process. This process may not be started before the connection. Perhaps it was initiated after the socket read so an exception will not backtrack trough the process, since it is downstream, not upstream. The process may be even unrelated to the connection, in other branch of the computation.
in this case you only need to create a exceptionPoint
before stablishin the connection, and use onExceptionPoint
to set a handler that will be called when the connection fail.
onExceptionPoint :: Exception e => BackPoint e -> (e -> TransIO ()) -> TransIO () Source #
in conjunction with backPoint
it set a handler that will be called when backtracking pass
trough the point
exceptBack :: EventF -> SomeException -> IO (Maybe a, EventF) Source #
cutExceptions :: TransIO () Source #
Delete all the exception handlers registered till now.
continue :: TransIO () Source #
Use it inside an exception handler. it stop executing any further exception handlers and resume normal execution from this point on.
catcht :: Exception e => TransIO b -> (e -> TransIO b) -> TransIO b Source #
catch an exception in a Transient block
The semantic is the same than catch
but the computation and the exception handler can be multirhreaded
catcht' :: Exception e => TransIO b -> (e -> TransIO b) -> TransIO b Source #
catch an exception in a Transient block
The semantic is the same than catch
but the computation and the exception handler can be multirhreaded
throwt :: Exception e => e -> TransIO a Source #
throw an exception in the Transient monad
there is a difference between throw
and throwt
since the latter preserves the state, while the former does not.
Any exception not thrown with throwt
does not preserve the state.
main= keep $ do onException $ \(e:: SomeException) -> do v <- getState <|> return "hello" liftIO $ print v setState "world" throw $ ErrorCall "asdasd"
the latter print "hello". If you use throwt
instead, it prints "world"