
Control.Concurrent.Coroutine 




Description 
This module defines the Coroutine monad transformer.
A Coroutine monadic computation can suspend its execution at any time, returning to its invoker. The returned
coroutine suspension contains the continuation of the coroutine embedded in a functor. Here is an example of a
coroutine that suspends computation in the IO monad using the functor Yield:
producer = do yield 1
lift (putStrLn "Produced one, next is four.")
yield 4
return "Finished"
A suspended Coroutine computation can be resumed. The easiest way to run a coroutine 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 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 weave together steps of different
coroutines into a single coroutine using the function couple, which can then be executed by pogoStick.
Coroutines can be run from within another coroutine. In this case, the nested coroutines would normally suspend to
their invoker. Another option is to allow a nested coroutine to suspend both itself and its invoker at once. In this
case, the two suspension functors should be grouped into an EitherFunctor. To run nested coroutines of this kind,
use functions pogoStickNested, seesawNested, and coupleNested.
For other uses of trampolinestyle coroutines, see
Trampolined Style  Ganz, S. E. Friedman, D. P. Wand, M, ACM SIGPLAN NOTICES, 1999, VOL 34; NUMBER 9, pages 1827
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 

data Coroutine s m r   suspend :: (Monad m, Functor s) => s (Coroutine s m x) > Coroutine s m x   class Monad m => ParallelizableMonad m where  bindM2 :: (a > b > m c) > m a > m b > m c 
  class (Functor a, Functor d) => AncestorFunctor a d   runCoroutine :: Monad m => Coroutine Naught m x > m x   pogoStick :: (Functor s, Monad m) => (s (Coroutine s m x) > Coroutine s m x) > Coroutine s m x > m x   pogoStickNested :: (Functor s1, Functor s2, Monad m) => (s2 (Coroutine (EitherFunctor s1 s2) m x) > Coroutine (EitherFunctor s1 s2) m x) > Coroutine (EitherFunctor s1 s2) m x > Coroutine s1 m 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)   seesawNested :: (Monad m, Functor s0, Functor s1, Functor s2) => (forall x y r. (x > y > m r) > m x > m y > m r) > SeesawResolver s1 s2 > Coroutine (EitherFunctor s0 s1) m x > Coroutine (EitherFunctor s0 s2) m y > Coroutine s0 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  }   data Yield x y = Yield x y   data Await x y = Await !(x > y)   data Naught x   yield :: forall m x. Monad m => x > Coroutine (Yield x) m ()   await :: forall m x. Monad m => Coroutine (Await x) m x   nest :: (Functor a, Functor b) => a x > b y > NestedFunctor a b (x, y)   couple :: (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)   coupleNested :: (Monad m, Functor s0, Functor s1, Functor s2) => (forall x y r. (x > y > m r) > m x > m y > m r) > Coroutine (EitherFunctor s0 s1) m x > Coroutine (EitherFunctor s0 s2) m y > Coroutine (EitherFunctor s0 (SomeFunctor s1 s2)) m (x, y)   local :: forall m l r x. (Functor r, Monad m) => Coroutine r m x > Coroutine (EitherFunctor l r) m x   out :: forall m l r x. (Functor l, Monad m) => Coroutine l m x > Coroutine (EitherFunctor l r) m x   liftOut :: forall m a d x. (Monad m, Functor a, AncestorFunctor a d) => Coroutine a m x > Coroutine d m x     newtype NestedFunctor l r x = NestedFunctor (l (r x))   



Coroutine definition



Suspending, resumable monadic computations.
 Instances  



Suspend the current Coroutine.


Useful classes



Class of monads that can perform two computations in parallel.
  Methods  bindM2 :: (a > b > m c) > m a > m b > m c  Source 
 Perform two monadic computations in parallel and pass the results.

  Instances  



Class of functors that can be lifted.
  Instances  


Running Coroutine computations



Convert a nonsuspending Coroutine to the base monad.



Run a Coroutine, using a function that converts suspension to the resumption it wraps.



Run a nested Coroutine that can suspend both itself and the current Coroutine.



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.



Like seesaw, but for nested coroutines that are allowed to suspend the current coroutine as well as themselves.


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
 invoked when both coroutines are suspended, resolves both suspensions or either one
 resumeAny :: forall t1 t2 r. (t1 > r) > (t2 > r) > (t1 > t2 > r) > s1 t1 > s2 t2 > r  




Suspension functors



The Yield functor instance is equivalent to (,) but more descriptive.
 Constructors   Instances  



The Await functor instance is equivalent to (>) but more descriptive.
 Constructors   Instances  



The Naught functor instance doesn't contain anything and cannot be constructed. Used for building nonsuspendable
coroutines.
 Instances  



Suspend yielding a value.



Suspend until a value is provided.


Nested and coupled Coroutine computations



Combines two values under two functors into a pair of values under a single NestedFunctor.



Weaves two coroutines into one.



Weaves two nested coroutines into one.



Converts a coroutine into a nested one.



Converts a coroutine into one that can contain nested coroutines.



Like out, working over multiple functors.


data EitherFunctor l r x  Source 

Combines two alternative functors into one, applying one or the other. Used for nested coroutines.
 Constructors   Instances  


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  


Produced by Haddock version 2.6.0 