| monad-coroutine-0.5: Coroutine monad transformer for suspending and resuming monadic computations | Source code | Contents | Index |
|
|
|
|
|
Description |
This module defines the Coroutine monad transformer.
A Coroutine monadic computation can suspend its execution at any time, returning control to its invoker. The
returned coroutine suspension is a Functor containing the resumption of the coroutine. Here is an example of a
coroutine in the IO monad that suspends computation using the functor Yield from the
Control.Monad.Coroutine.SuspensionFunctors module:
producer :: Coroutine (Yield Int) IO String
producer = do yield 1
lift (putStrLn "Produced one, next is four.")
yield 4
return "Finished"
To continue the execution of a suspended Coroutine, apply its resume method. The easiest way to run a coroutine
to completion is by using the pogoStick function, which keeps resuming the coroutine in trampolined style until it
completes. Here is an example of pogoStick applied to the producer example above:
printProduce :: Show x => Coroutine (Yield x) IO r -> IO r
printProduce producer = pogoStick (\(Yield x cont) -> lift (print x) >> cont) producer
Multiple concurrent coroutines can be run as well, and this module provides two different ways. The function seesaw
can be used to run two interleaved computations. Another possible way is to use the functions couple or merge to
weave together steps of different coroutines into a single coroutine, which can then be executed by pogoStick.
For other uses of trampoline-style coroutines, see
Trampolined Style - Ganz, S. E. Friedman, D. P. Wand, M, ACM SIGPLAN NOTICES, 1999, VOL 34; NUMBER 9, pages 18-27
and
The Essence of Multitasking - William L. Harrison, Proceedings of the 11th International Conference on Algebraic
Methodology and Software Technology, volume 4019 of Lecture Notes in Computer Science, 2006
|
|
Synopsis |
|
newtype Coroutine s m r = Coroutine {} | | suspend :: (Monad m, Functor s) => s (Coroutine s m x) -> Coroutine s m x | | mapMonad :: forall s m m' x. (Functor s, Monad m, Monad m') => (forall x. m x -> m' x) -> Coroutine s m x -> Coroutine s m' x | | mapSuspension :: forall s s' m x. (Functor s, Monad m) => (forall x. s x -> s' x) -> Coroutine s m x -> Coroutine s' m x | | data Naught x | | runCoroutine :: Monad m => Coroutine Naught m x -> m x | | pogoStick :: Monad m => (s (Coroutine s m x) -> Coroutine s m x) -> Coroutine s m x -> m x | | foldRun :: Monad m => (a -> s (Coroutine s m x) -> (a, Coroutine s m x)) -> a -> Coroutine s m x -> m (a, x) | | seesaw :: (Monad m, Functor s1, Functor s2) => (forall x y r. (x -> y -> m r) -> m x -> m y -> m r) -> SeesawResolver s1 s2 -> Coroutine s1 m x -> Coroutine s2 m y -> m (x, y) | | data SeesawResolver s1 s2 = SeesawResolver {resumeLeft :: forall t. s1 t -> t | resumeRight :: forall t. s2 t -> t | resumeAny :: forall t1 t2 r. (t1 -> r) -> (t2 -> r) -> (t1 -> t2 -> r) -> s1 t1 -> s2 t2 -> r | } | | newtype NestedFunctor l r x = NestedFunctor (l (r x)) | | | | nest :: (Functor a, Functor b) => a x -> b y -> NestedFunctor a b (x, y) | | couple :: forall s1 s2 m x y r. (Monad m, Functor s1, Functor s2) => (forall x y r. (x -> y -> m r) -> m x -> m y -> m r) -> Coroutine s1 m x -> Coroutine s2 m y -> Coroutine (SomeFunctor s1 s2) m (x, y) | | merge :: forall s m x. (Monad m, Functor s) => (forall x. [m x] -> m [x]) -> (forall x. [s x] -> s [x]) -> [Coroutine s m x] -> Coroutine s m [x] |
|
|
|
Coroutine definition
|
|
newtype Coroutine s m r | Source |
|
Suspending, resumable monadic computations.
| Constructors | Coroutine | | resume :: m (Either (s (Coroutine s m r)) r) | Run the next step of a Coroutine computation. The result of the step execution will be either a suspension or
the final coroutine result.
|
|
| Instances | |
|
|
|
Suspend the current Coroutine.
|
|
Coroutine operations
|
|
|
Change the base monad of a Coroutine.
|
|
|
Change the suspension functor of a Coroutine.
|
|
Running Coroutine computations
|
|
|
The Naught functor instance doesn't contain anything and cannot be constructed. Used for building non-suspendable
coroutines.
| Instances | |
|
|
|
Convert a non-suspending Coroutine to the base monad.
|
|
|
Run a suspendable Coroutine, using a function that extracts the coroutine resumption from each suspension.
|
|
|
Runs a suspendable coroutine much like pogoStick, but allows the resumption function to thread an arbitrary
state as well.
|
|
|
Runs two coroutines concurrently. The first argument is used to run the next step of each coroutine, the next to
convert the left, right, or both suspensions into the corresponding resumptions.
|
|
data SeesawResolver s1 s2 | Source |
|
A simple record containing the resolver functions for all possible coroutine pair suspensions.
| Constructors | SeesawResolver | | resumeLeft :: forall t. s1 t -> t | resolves the left suspension functor into the resumption it contains
| resumeRight :: forall t. s2 t -> t | resolves the right suspension into its resumption
| resumeAny :: forall t1 t2 r. (t1 -> r) -> (t2 -> r) -> (t1 -> t2 -> r) -> s1 t1 -> s2 t2 -> r | invoked when both coroutines are suspended, resolves both suspensions or either one
|
|
|
|
|
Nested and coupled Coroutine computations
|
|
newtype NestedFunctor l r x | Source |
|
Combines two functors into one, applying both.
| Constructors | | Instances | |
|
|
|
Combines two functors into one, applying either or both of them. Used for coupled coroutines.
| Constructors | | Instances | |
|
|
|
Combines two values under two functors into a pair of values under a single NestedFunctor.
|
|
|
Weaves two coroutines into one. The two coroutines suspend and resume in lockstep.
|
|
|
Weaves a list of coroutines with the same suspension functor type into a single coroutine. The coroutines suspend
and resume in lockstep.
|
|
Produced by Haddock version 2.7.2 |