-- Hoogle documentation, generated by Haddock -- See Hoogle, http://www.haskell.org/hoogle/ -- | composing programs with multithreading, events and distributed computing -- -- See http://github.com/agocorona/transient In this release -- distributed primitives have been moved to the transient-universe -- package, and web primitives have been moved to the ghcjs-hplay -- package. @package transient @version 0.5.4 -- | See http://github.com/agocorona/transient everithing in this -- module is exported in order to allow extensibility. module Transient.Internals data TransIO x Transient :: StateT EventF IO (Maybe x) -> TransIO x [runTrans] :: TransIO x -> StateT EventF IO (Maybe x) type SData = () type EventId = Int type TransientIO = TransIO data LifeCycle Alive :: LifeCycle Parent :: LifeCycle Listener :: LifeCycle Dead :: LifeCycle data EventF EventF :: () -> Maybe SData -> TransIO a -> [b -> TransIO b] -> Map TypeRep SData -> Int -> ThreadId -> Bool -> Maybe EventF -> MVar [EventF] -> Maybe (IORef Int) -> IORef (LifeCycle, ByteString) -> EventF [meffects] :: EventF -> () [event] :: EventF -> Maybe SData [xcomp] :: EventF -> TransIO a [fcomp] :: EventF -> [b -> TransIO b] [mfData] :: EventF -> Map TypeRep SData [mfSequence] :: EventF -> Int [threadId] :: EventF -> ThreadId [freeTh] :: EventF -> Bool [parent] :: EventF -> Maybe EventF [children] :: EventF -> MVar [EventF] [maxThread] :: EventF -> Maybe (IORef Int) [labelth] :: EventF -> IORef (LifeCycle, ByteString) type Effects = forall a b c. TransIO a -> TransIO a -> (a -> TransIO b) -> StateIO (StateIO (Maybe c) -> StateIO (Maybe c), Maybe a) type StateIO = StateT EventF IO -- | Run a "non transient" computation within the underlying state monad, -- so it is guaranteed that the computation neither can stop neither can -- trigger additional events/threads noTrans :: StateT EventF IO x -> TransIO x -- | Run the transient computation with a blank state runTransient :: TransIO x -> IO (Maybe x, EventF) -- | Run the transient computation with an state runTransState :: EventF -> TransIO x -> IO (Maybe x, EventF) -- | Get the continuation context: closure, continuation, state, child -- threads etc getCont :: TransIO EventF -- | Run the closure and the continuation using the state data of the -- calling thread runCont :: EventF -> StateIO (Maybe a) -- | Run the closure and the continuation using his own state data runCont' :: EventF -> IO (Maybe a, EventF) -- | Warning: radiactive untyped stuff. handle with care getContinuations :: StateIO [a -> TransIO b] -- | Compose a list of continuations compose :: (Monad f, Alternative f) => [a1 -> f a1] -> a1 -> f a -- | Run the closure (the x in 'x >>= f') of the current -- bind operation. runClosure :: EventF -> StateIO (Maybe a) -- | Run the continuation (the f in 'x >>= f') of the -- current bind operation with the current state runContinuation :: EventF -> a -> StateIO (Maybe b) setContinuation :: TransIO a -> (a -> TransIO b) -> [c -> TransIO c] -> StateIO () withContinuation :: t -> TransIO b -> TransIO b -- | run a chain of continuations. It is up to the programmer to assure by -- construction that each continuation type-check with the next, that the -- parameter type match the input of the first continuation. Normally -- this makes sense if it stop the current flow with stop after -- the invocation runContinuations :: [a -> TransIO b] -> c -> TransIO d restoreStack :: MonadState EventF m => [b -> TransIO b] -> m () readWithErr :: (Read a, Typeable * a) => String -> IO [(a, String)] readsPrec' :: (Typeable * a, Read a) => t -> String -> [(a, String)] class (Show a, Read a, Typeable a) => Loggable a -- | Dynamic serializable data for logging data IDynamic IDyns :: String -> IDynamic IDynamic :: a -> IDynamic type Recover = Bool type CurrentPointer = [LogElem] type LogEntries = [LogElem] data LogElem Wait :: LogElem Exec :: LogElem Var :: IDynamic -> LogElem data Log Log :: Recover -> CurrentPointer -> LogEntries -> Log data RemoteStatus WasRemote :: RemoteStatus WasParallel :: RemoteStatus NoRemote :: RemoteStatus -- | A sinonym of empty that can be used in a monadic expression. it stop -- the computation and execute the next alternative computation (composed -- with <|>) stop :: Alternative m => m stopped class AdditionalOperators m where atEnd' = (<**) atEnd = (<***) -- | Executes the second operand even if the frist return empty. A normal -- imperative (monadic) sequence uses the operator (>>) which in -- the Transient monad does not execute the next operand if the previous -- one return empty. (**>) :: AdditionalOperators m => m a -> m b -> m b -- | Forces the execution of the second operand even if the first stop. It -- does not execute the second operand as result of internal events -- occuring in the first operand. Return the first result (<**) :: AdditionalOperators m => m a -> m b -> m a atEnd' :: AdditionalOperators m => m a -> m b -> m a -- | Forces the execution of the second operand even if the first stop. -- Return the first result. The second operand is executed also when -- internal events happens in the first operand and it returns something (<***) :: AdditionalOperators m => m a -> m b -> m a atEnd :: AdditionalOperators m => m a -> m b -> m a -- | When the first operand is an asynchronous operation, the second -- operand is executed once (one single time) when the first completes -- his first asyncronous operation. -- -- This is useful for spawning asynchronous or distributed tasks that are -- singletons and that should start when the first one is set up. -- -- for example a streaming where the event receivers are acivated before -- the senders. (<|) :: TransIO a -> TransIO b -> TransIO a -- | Set the current closure and continuation for the current statement setEventCont :: TransIO a -> (a -> TransIO b) -> StateIO EventF -- | 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 (TransIO b -> -- TransIO b) resetEventCont :: MonadState EventF m => Maybe t1 -> t -> m (a -> a) tailsafe :: [t] -> [t] waitQSemB :: (Num a, Ord a) => IORef a -> IO Bool signalQSemB :: Num a => IORef a -> IO () -- | Set the maximun number of threads for a procedure. It is useful to -- limit the parallelization of transient code that uses parallel -- spawn and waitEvents threads :: Int -> TransIO a -> TransIO a -- | Delete all the previous child threads generated by the expression -- taken as parameter and continue execution of the current thread. oneThread :: TransIO a -> TransIO a -- | Add a label to the current passing threads so it can be printed by -- debugging calls like showThreads labelState :: (MonadIO m, MonadState EventF m) => String -> m () printBlock :: MVar () showThreads :: MonadIO m => EventF -> m () -- | Return the state of the thread that initiated the transient -- computation topState :: TransIO EventF -- | Return the state variable of the type desired with which a thread, -- identified by his number in the treee was initiated showState :: (Typeable a, MonadIO m, Alternative m) => String -> EventF -> m (Maybe a) -- | Add n threads to the limit of threads. If there is no limit, it set it addThreads' :: Int -> TransIO () -- | Assure that at least there are n threads available addThreads :: Int -> TransIO () -- | The threads generated in the process passed as parameter will not be -- killed by `kill*` primitives. -- -- Since there is no thread control, the application run slightly faster. freeThreads :: TransIO a -> TransIO a -- | The threads will be killed when the parent thread dies. That is the -- default. This can be invoked to revert the effect of -- freeThreads hookedThreads :: TransIO a -> TransIO a -- | kill all the child threads of the current thread killChilds :: TransIO () -- | Kill the current thread and the childs killBranch :: TransIO () -- | Kill the childs and the thread of an state killBranch' :: MonadIO m => EventF -> m () -- | Get the state data for the desired type if there is any. getData :: (MonadState EventF m, Typeable a) => m (Maybe a) -- | getData specialized for the Transient monad. if Nothing, the monadic -- computation does not continue. -- -- If there is no such data, getSData silently stop the -- computation. That may or may not be the desired behaviour. To make -- sure that this does not get unnoticed, use this construction: -- --
--   getSData <|> error "no data"
--   
-- -- To have the same semantics and guarantees than get, use a -- default value: -- --
--   getInt= getSData <|> return (0 :: Int)
--   
-- -- The default value (0 in this case) has the same role than the initial -- value in a state monad. The difference is that you can define as many -- get as you need for all your data types. -- -- To distingish two data with the same types, use newtype definitions. getSData :: Typeable a => TransIO a -- | Synonym for getSData getState :: Typeable a => TransIO a -- | Set session data for this type. retrieved with getData or getSData -- Note that this is data in a state monad, that means that the update -- only affect downstream in the monad execution. it is not a global -- state neither a per user or per thread state it is a monadic state -- like the one of a state monad. setData :: (MonadState EventF m, Typeable a) => a -> m () -- | Modify state data. It accept a function that get the current state (if -- exist) as parameter. The state will be deleted or changed depending on -- function result modifyData :: (MonadState EventF m, Typeable a) => (Maybe a -> Maybe a) -> m () -- | Synonym for modifyData modifyState :: (MonadState EventF m, Typeable a) => (Maybe a -> Maybe a) -> m () -- | Synonym for setData setState :: (MonadState EventF m, Typeable a) => a -> m () delData :: (MonadState EventF m, Typeable a) => a -> m () delState :: (MonadState EventF m, Typeable a) => a -> m () -- | Executes the computation and reset the state if it fails. try :: TransIO a -> TransIO a -- | Executes the computation and reset the state either if it fails or not sandbox :: TransIO a -> TransIO a -- | Generator of identifiers that are unique withing the current monadic -- sequence They are not unique in the whole program. genId :: MonadState EventF m => m Int getPrevId :: MonadState EventF m => m Int -- | Async calls data StreamData a SMore :: a -> StreamData a SLast :: a -> StreamData a SDone :: StreamData a SError :: SomeException -> StreamData a -- | Variant of parallel that repeatedly executes the IO computation -- without end waitEvents :: IO b -> TransIO b -- | Variant of parallel that execute the IO computation once async :: IO b -> TransIO b -- | in an alternative computation it executes an async operations -- synchronously. This means that the alternatives do not execute until -- the async operation finishes. Do not use in Applicatives. sync :: TransIO a -> TransIO a -- | `spawn= freeThreads . waitEvents` spawn :: IO a -> TransIO a -- | Executes an IO action each certain interval of time and return his -- value if it changes sample :: Eq a => IO a -> Int -> TransIO a -- | Return empty to the current thread and execute the IO action in a new -- thread. When the IO action returns, the transient computation -- continues with this value as the result The IO action may be -- re-executed or not depending on the result. So parallel can spawn any -- number of threads/results. -- -- If the maximum number of threads, set with threads has been -- reached parallel perform the work sequentially, in the current -- thread. So parallel means that 'it can be parallelized if there -- are thread available' -- -- if there is a limitation of threads, when a thread finish, the counter -- of threads available is increased so another parallel can make -- use of it. -- -- The behaviour of parallel depend on StreamData; If -- SMore, parallel will excute again the IO action. With -- SLast, SDone and SError, parallel will not -- repeat the IO action anymore. parallel :: IO (StreamData b) -> TransIO (StreamData b) loop :: EventF -> IO (StreamData t) -> IO () free :: ThreadId -> EventF -> IO () hangThread :: EventF -> EventF -> IO () -- | kill all the child threads associated with the continuation context killChildren :: MVar [EventF] -> IO () -- | De-invert an event handler. -- -- The first parameter is the setter of the event handler to be -- deinverted. Usually it is the primitive provided by a framework to set -- an event handler -- -- the second parameter is the value to return to the event handler. -- Usually it is `return()` -- -- it configures the event handler by calling the setter of the event -- handler with the current continuation react :: Typeable eventdata => ((eventdata -> IO response) -> IO ()) -> IO response -> TransIO eventdata -- | continue the computation in another thread and return empty to -- the computation in the curren thread. -- -- Useful for executing alternative computations abduce :: TransIO () getLineRef :: TVar (Maybe a) roption :: MVar [t] -- | Install a event receiver that wait for a string and trigger the -- continuation when this string arrives. option :: (Typeable b, Show b, Read b, Eq b) => b -> String -> TransIO b -- | Validates an input entered in the keyboard in non blocking mode. non -- blocking means that the user can enter also anything else to activate -- other option unlike option, wich watch continuously, input only -- wait for one valid response input :: (Typeable a, Read a, Show a) => (a -> Bool) -> String -> TransIO a -- | Non blocking getLine with a validator getLine' :: (Read a, Typeable * a) => (a -> Bool) -> IO a reads1 :: (Typeable * a, Read a) => String -> [(a, String)] inputLoop :: IO b processLine :: MonadIO m => String -> m () -- | Wait for the execution of exit and return the result or the -- exhaustion of thread activity stay :: MVar (Maybe a) -> IO (Maybe a) newtype Exit a Exit :: a -> Exit a -- | Keep the main thread running, initiate the non blocking keyboard input -- and execute the transient computation. -- -- It also read a slash-separated list of string that are read by -- option and input as if they were entered by the keyboard -- --
--   foo  -p  options/to/be/read/by/option/and/input
--   
keep :: Typeable a => TransIO a -> IO (Maybe a) -- | Same than keep but do not initiate the asynchronous keyboard -- input. 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 is no -- more threads running keep' :: Typeable a => TransIO a -> IO (Maybe a) execCommandLine :: IO () -- | Force the finalization of the main thread and thus, all the Transient -- block (and the application if there is no more code) exit :: Typeable a => a -> TransIO a -- | Alternative operator for maybe values. Used in infix mode onNothing :: Monad m => m (Maybe b) -> m b -> m b data Backtrack b Backtrack :: Maybe b -> [EventF] -> Backtrack b [backtracking] :: Backtrack b -> Maybe b [backStack] :: Backtrack b -> [EventF] -- | Assures that backtracking will not go further back backCut :: (Typeable reason, Show reason) => reason -> TransientIO () undoCut :: TransientIO () -- | The second parameter will be executed when backtracking onBack :: (Typeable b, Show b) => TransientIO a -> (b -> TransientIO a) -> TransientIO a onUndo :: TransientIO a -> TransientIO a -> TransientIO a -- | Register an action that will be executed when backtracking registerBack :: (Typeable b, Show b) => b -> TransientIO a -> TransientIO a registerUndo :: TransientIO a -> TransientIO a -- | backtracking is stopped. the exection continues forward from this -- point on. forward :: (Typeable b, Show b) => b -> TransIO () retry :: TransIO () noFinish :: TransIO () -- | Execute backtracking. It execute the registered actions in reverse -- order. -- -- If the backtracking flag is changed the flow proceed forward from that -- point on. -- -- If the backtrack stack is finished or undoCut executed, the -- backtracking will stop. back :: (Typeable b, Show b) => b -> TransientIO a backStateOf :: (Monad m, Show a, Typeable a) => a -> m (Backtrack a) undo :: TransIO a newtype FinishReason FinishReason :: (Maybe SomeException) -> FinishReason -- | Initialize the event variable for finalization. all the following -- computations in different threads will share it it also isolate this -- event from other branches that may have his own finish variable initFinish :: TransientIO () -- | Set a computation to be called when the finish event happens onFinish :: ((Maybe SomeException) -> TransIO ()) -> TransIO () -- | Set a computation to be called when the finish event happens this only -- apply for onFinish' :: TransIO a -> ((Maybe SomeException) -> TransIO a) -> TransIO a -- | Trigger the event, so this closes all the resources finish :: Maybe SomeException -> TransIO a -- | trigger finish when the stream of data ends checkFinalize :: StreamData a -> TransIO a -- | When a exception is produced anywhere after this statement, the -- handler is executed. | handlers are executed Last in first out. onException :: Exception e => (e -> TransIO ()) -> TransIO () onException' :: Exception e => TransIO a -> (e -> TransIO a) -> TransIO a -- | stop the backtracking mechanism from executing further handlers cutExceptions :: TransientIO () -- | Resume to normal execution at this point continue :: TransIO () catcht :: Exception e => TransIO b -> (e -> TransIO b) -> TransIO b instance GHC.Show.Show Transient.Internals.FinishReason instance GHC.Read.Read a => GHC.Read.Read (Transient.Internals.StreamData a) instance GHC.Show.Show a => GHC.Show.Show (Transient.Internals.StreamData a) instance GHC.Show.Show Transient.Internals.RemoteStatus instance GHC.Classes.Eq Transient.Internals.RemoteStatus instance GHC.Show.Show Transient.Internals.Log instance GHC.Show.Show Transient.Internals.LogElem instance GHC.Read.Read Transient.Internals.LogElem instance GHC.Show.Show Transient.Internals.LifeCycle instance GHC.Classes.Eq Transient.Internals.LifeCycle instance Control.Monad.State.Class.MonadState Transient.Internals.EventF Transient.Internals.TransIO instance GHC.Base.Functor Transient.Internals.TransIO instance GHC.Base.Applicative Transient.Internals.TransIO instance (GHC.Show.Show a, GHC.Read.Read a, Data.Typeable.Internal.Typeable a) => Transient.Internals.Loggable a instance GHC.Show.Show Transient.Internals.IDynamic instance GHC.Read.Read Transient.Internals.IDynamic instance GHC.Base.Alternative Transient.Internals.TransIO instance GHC.Base.MonadPlus Transient.Internals.TransIO instance (GHC.Num.Num a, GHC.Classes.Eq a) => GHC.Num.Num (Transient.Internals.TransIO a) instance Transient.Internals.AdditionalOperators Transient.Internals.TransIO instance GHC.Base.Monoid a => GHC.Base.Monoid (Transient.Internals.TransIO a) instance GHC.Base.Monad Transient.Internals.TransIO instance Control.Monad.IO.Class.MonadIO Transient.Internals.TransIO instance GHC.Read.Read GHC.Exception.SomeException -- | see -- https://www.fpcomplete.com/user/agocorona/beautiful-parallel-non-determinism-transient-effects-iii module Transient.Indeterminism -- | slurp a list of values and process them in parallel . To limit the -- number of processing threads, use threads choose :: Show a => [a] -> TransIO a -- | alternative definition with more parallelism, as the composition of n -- async sentences choose' :: [a] -> TransIO a collect :: Int -> TransIO a -> TransIO [a] -- | search with a timeout After the timeout, it stop unconditionally and -- return the current results. It also stops as soon as there are enough -- results specified in the first parameter. The results are returned by -- the original thread -- --
--   timeout t proc=do
--     r <- collect' 1 t proc
--     case r of
--        []  ->  empty
--        r:_ -> return r
--   
-- --
--   timeout 10000 empty <|> liftIO (print "timeout")
--   
-- -- That executes the alternative and will print "timeout". This would not -- be produced if collect would not return the results to the original -- thread -- -- search is executed in different threads and his state is -- lost, so don't rely in state to pass information collect' :: Int -> Int -> TransIO a -> TransIO [a] -- | group the output of a possible multithreaded process in groups of n -- elements. group :: Int -> TransIO a -> TransIO [a] -- | group result for a time interval, measured with diffUTCTime groupByTime :: Integer -> TransIO a -> TransIO [a] -- | See http://github.com/agocorona/transient module Transient.Base data TransIO x Transient :: StateT EventF IO (Maybe x) -> TransIO x [runTrans] :: TransIO x -> StateT EventF IO (Maybe x) type TransientIO = TransIO -- | Keep the main thread running, initiate the non blocking keyboard input -- and execute the transient computation. -- -- It also read a slash-separated list of string that are read by -- option and input as if they were entered by the keyboard -- --
--   foo  -p  options/to/be/read/by/option/and/input
--   
keep :: Typeable a => TransIO a -> IO (Maybe a) -- | Same than keep but do not initiate the asynchronous keyboard -- input. 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 is no -- more threads running keep' :: Typeable a => TransIO a -> IO (Maybe a) -- | A sinonym of empty that can be used in a monadic expression. it stop -- the computation and execute the next alternative computation (composed -- with <|>) stop :: Alternative m => m stopped -- | Install a event receiver that wait for a string and trigger the -- continuation when this string arrives. option :: (Typeable b, Show b, Read b, Eq b) => b -> String -> TransIO b -- | Validates an input entered in the keyboard in non blocking mode. non -- blocking means that the user can enter also anything else to activate -- other option unlike option, wich watch continuously, input only -- wait for one valid response input :: (Typeable a, Read a, Show a) => (a -> Bool) -> String -> TransIO a -- | Force the finalization of the main thread and thus, all the Transient -- block (and the application if there is no more code) exit :: Typeable a => a -> TransIO a -- | Variant of parallel that execute the IO computation once async :: IO b -> TransIO b -- | Variant of parallel that repeatedly executes the IO computation -- without end waitEvents :: IO b -> TransIO b -- | `spawn= freeThreads . waitEvents` spawn :: IO a -> TransIO a -- | Return empty to the current thread and execute the IO action in a new -- thread. When the IO action returns, the transient computation -- continues with this value as the result The IO action may be -- re-executed or not depending on the result. So parallel can spawn any -- number of threads/results. -- -- If the maximum number of threads, set with threads has been -- reached parallel perform the work sequentially, in the current -- thread. So parallel means that 'it can be parallelized if there -- are thread available' -- -- if there is a limitation of threads, when a thread finish, the counter -- of threads available is increased so another parallel can make -- use of it. -- -- The behaviour of parallel depend on StreamData; If -- SMore, parallel will excute again the IO action. With -- SLast, SDone and SError, parallel will not -- repeat the IO action anymore. parallel :: IO (StreamData b) -> TransIO (StreamData b) -- | Executes an IO action each certain interval of time and return his -- value if it changes sample :: Eq a => IO a -> Int -> TransIO a -- | De-invert an event handler. -- -- The first parameter is the setter of the event handler to be -- deinverted. Usually it is the primitive provided by a framework to set -- an event handler -- -- the second parameter is the value to return to the event handler. -- Usually it is `return()` -- -- it configures the event handler by calling the setter of the event -- handler with the current continuation react :: Typeable eventdata => ((eventdata -> IO response) -> IO ()) -> IO response -> TransIO eventdata -- | Synonym for setData setState :: (MonadState EventF m, Typeable a) => a -> m () -- | Set session data for this type. retrieved with getData or getSData -- Note that this is data in a state monad, that means that the update -- only affect downstream in the monad execution. it is not a global -- state neither a per user or per thread state it is a monadic state -- like the one of a state monad. setData :: (MonadState EventF m, Typeable a) => a -> m () -- | Synonym for getSData getState :: Typeable a => TransIO a -- | getData specialized for the Transient monad. if Nothing, the monadic -- computation does not continue. -- -- If there is no such data, getSData silently stop the -- computation. That may or may not be the desired behaviour. To make -- sure that this does not get unnoticed, use this construction: -- --
--   getSData <|> error "no data"
--   
-- -- To have the same semantics and guarantees than get, use a -- default value: -- --
--   getInt= getSData <|> return (0 :: Int)
--   
-- -- The default value (0 in this case) has the same role than the initial -- value in a state monad. The difference is that you can define as many -- get as you need for all your data types. -- -- To distingish two data with the same types, use newtype definitions. getSData :: Typeable a => TransIO a -- | Get the state data for the desired type if there is any. getData :: (MonadState EventF m, Typeable a) => m (Maybe a) delState :: (MonadState EventF m, Typeable a) => a -> m () delData :: (MonadState EventF m, Typeable a) => a -> m () -- | Modify state data. It accept a function that get the current state (if -- exist) as parameter. The state will be deleted or changed depending on -- function result modifyData :: (MonadState EventF m, Typeable a) => (Maybe a -> Maybe a) -> m () -- | Synonym for modifyData modifyState :: (MonadState EventF m, Typeable a) => (Maybe a -> Maybe a) -> m () -- | Executes the computation and reset the state if it fails. try :: TransIO a -> TransIO a -- | Set the maximun number of threads for a procedure. It is useful to -- limit the parallelization of transient code that uses parallel -- spawn and waitEvents threads :: Int -> TransIO a -> TransIO a -- | Assure that at least there are n threads available addThreads :: Int -> TransIO () -- | The threads generated in the process passed as parameter will not be -- killed by `kill*` primitives. -- -- Since there is no thread control, the application run slightly faster. freeThreads :: TransIO a -> TransIO a -- | The threads will be killed when the parent thread dies. That is the -- default. This can be invoked to revert the effect of -- freeThreads hookedThreads :: TransIO a -> TransIO a -- | Delete all the previous child threads generated by the expression -- taken as parameter and continue execution of the current thread. oneThread :: TransIO a -> TransIO a -- | kill all the child threads of the current thread killChilds :: TransIO () -- | Executes the second operand even if the frist return empty. A normal -- imperative (monadic) sequence uses the operator (>>) which in -- the Transient monad does not execute the next operand if the previous -- one return empty. (**>) :: AdditionalOperators m => m a -> m b -> m b -- | Forces the execution of the second operand even if the first stop. It -- does not execute the second operand as result of internal events -- occuring in the first operand. Return the first result (<**) :: AdditionalOperators m => m a -> m b -> m a -- | Forces the execution of the second operand even if the first stop. -- Return the first result. The second operand is executed also when -- internal events happens in the first operand and it returns something (<***) :: AdditionalOperators m => m a -> m b -> m a -- | When the first operand is an asynchronous operation, the second -- operand is executed once (one single time) when the first completes -- his first asyncronous operation. -- -- This is useful for spawning asynchronous or distributed tasks that are -- singletons and that should start when the first one is set up. -- -- for example a streaming where the event receivers are acivated before -- the senders. (<|) :: TransIO a -> TransIO b -> TransIO a -- | When a exception is produced anywhere after this statement, the -- handler is executed. | handlers are executed Last in first out. onException :: Exception e => (e -> TransIO ()) -> TransIO () -- | stop the backtracking mechanism from executing further handlers cutExceptions :: TransientIO () -- | Resume to normal execution at this point continue :: TransIO () -- | Async calls data StreamData a SMore :: a -> StreamData a SLast :: a -> StreamData a SDone :: StreamData a SError :: SomeException -> StreamData a -- | Generator of identifiers that are unique withing the current monadic -- sequence They are not unique in the whole program. genId :: MonadState EventF m => m Int module Transient.EVars data EVar a EVar :: (TChan (StreamData a)) -> EVar a -- | creates an EVar. -- -- Evars are event vars. writeEVar trigger the execution of all -- the continuations associated to the readEVar of this variable -- (the code that is after them). -- -- It is like the publish-subscribe pattern but without inversion of -- control, since a readEVar can be inserted at any place in the -- Transient flow. -- -- EVars are created upstream and can be used to communicate two -- sub-threads of the monad. Following the Transient philosophy they do -- not block his own thread if used with alternative operators, unlike -- the IORefs and TVars. And unlike STM vars, that are composable, they -- wait for their respective events, while TVars execute the whole -- expression when any variable is modified. -- -- The execution continues after the writeEVar when all subscribers have -- been executed. -- -- Now the continuations are executed in parallel. -- -- see -- https://www.fpcomplete.com/user/agocorona/publish-subscribe-variables-transient-effects-v newEVar :: TransIO (EVar a) -- | delete al the subscriptions for an evar. cleanEVar :: EVar a -> TransIO () -- | read the EVar. It only succeed when the EVar is being updated The -- continuation gets registered to be executed whenever the variable is -- updated. -- -- if readEVar is re-executed in any kind of loop, since each -- continuation is different, this will register again. The effect is -- that the continuation will be executed multiple times To avoid -- multiple registrations, use cleanEVar readEVar :: EVar a -> TransIO a -- | update the EVar and execute all readEVar blocks with "last in-first -- out" priority writeEVar :: MonadIO m => EVar t -> t -> m () -- | write the EVar and drop all the readEVar handlers. -- -- It is like a combination of writeEVar and cleanEVar lastWriteEVar :: MonadIO m => EVar t -> t -> m () module Transient.Logged restore :: TransIO a -> TransIO a -- | Save the state of every thread at this point. If the process is -- re-executed with restore it will reexecute the thread from this -- point on.. checkpoint :: TransIO () -- | save the state of the thread that execute it and exit the transient -- block initiated with keep or similar . keep will return -- the value passed by suspend. If the process is executed again -- with restore it will reexecute the thread from this point on. -- -- it is useful to insert it in finish blocks to gather error -- information, suspend :: Typeable a => a -> TransIO a -- | write the result of the computation in the log and return it. but if -- there is data in the internal log, it read the data from the log and -- do not execute the computation. -- -- It accept nested step's. The effect is that if the outer step is -- executed completely the log of the inner steps are erased. If it is -- not the case, the inner steps are logged this reduce the log of large -- computations to the minimum. That is a feature not present in the -- package Workflow. -- --
--   r <- logged $ do
--           logged this :: TransIO ()
--           logged that :: TransIO ()
--           logged thatOther
--   liftIO $ print r
--   
-- -- when print is executed, the log is just the value of r. -- -- but at the thatOther execution the log is: [Exec,(), ()] logged :: Loggable a => TransientIO a -> TransientIO a received :: Loggable a => a -> TransIO () param :: Loggable a => TransIO a class (Show a, Read a, Typeable a) => Loggable a -- | -- https://www.fpcomplete.com/user/agocorona/the-hardworking-programmer-ii-practical-backtracking-to-undo-actions module Transient.Backtrack onUndo :: TransientIO a -> TransientIO a -> TransientIO a undo :: TransIO a retry :: TransIO () undoCut :: TransientIO () registerUndo :: TransientIO a -> TransientIO a -- | The second parameter will be executed when backtracking onBack :: (Typeable b, Show b) => TransientIO a -> (b -> TransientIO a) -> TransientIO a -- | Execute backtracking. It execute the registered actions in reverse -- order. -- -- If the backtracking flag is changed the flow proceed forward from that -- point on. -- -- If the backtrack stack is finished or undoCut executed, the -- backtracking will stop. back :: (Typeable b, Show b) => b -> TransientIO a -- | backtracking is stopped. the exection continues forward from this -- point on. forward :: (Typeable b, Show b) => b -> TransIO () -- | Assures that backtracking will not go further back backCut :: (Typeable reason, Show reason) => reason -> TransientIO () -- | Register an action that will be executed when backtracking registerBack :: (Typeable b, Show b) => b -> TransientIO a -> TransientIO a -- | Trigger the event, so this closes all the resources finish :: Maybe SomeException -> TransIO a -- | Set a computation to be called when the finish event happens onFinish :: ((Maybe SomeException) -> TransIO ()) -> TransIO () -- | Set a computation to be called when the finish event happens this only -- apply for onFinish' :: TransIO a -> ((Maybe SomeException) -> TransIO a) -> TransIO a -- | Initialize the event variable for finalization. all the following -- computations in different threads will share it it also isolate this -- event from other branches that may have his own finish variable initFinish :: TransientIO () noFinish :: TransIO () -- | trigger finish when the stream of data ends checkFinalize :: StreamData a -> TransIO a data FinishReason