This module defines some common suspension functors for use with the Control.Monad.Coroutine module.

- data Yield x y = Yield x y
- newtype Await x y = Await (x -> y)
- data Request request response x = Request request (response -> x)
- data ParseRequest x z
- data EitherFunctor l r x
- eitherFunctor :: (l x -> y) -> (r x -> y) -> EitherFunctor l r x -> y
- yield :: Monad m => x -> Coroutine (Yield x) m ()
- await :: Monad m => Coroutine (Await x) m x
- request :: Monad m => x -> Coroutine (Request x y) m y
- requestParse :: (Monad m, MonoidNull y) => Parser [x] y -> Coroutine (ParseRequest x) m (y, Maybe (Parser [x] y))
- concatYields :: (Monad m, Foldable f) => Coroutine (Yield (f x)) m r -> Coroutine (Yield x) m r
- concatAwaits :: (Monad m, Foldable f) => Coroutine (Await x) m r -> Coroutine (Await (f x)) m r
- awaitYieldResolver :: SeesawResolver (Await x) (Yield x) s1 s2
- awaitMaybeYieldResolver :: SeesawResolver (Await (Maybe x)) (Yield x) s1 s2
- awaitYieldChunkResolver :: SeesawResolver (Await [x]) (Yield [x]) s1 s2
- requestsResolver :: SeesawResolver (Request x y) (Request y x) s1 s2
- tickerYieldResolver :: SeesawResolver (Request (Ticker x) [x]) (Yield [x]) (Request (Ticker x) [x]) (Yield [x])
- tickerRequestResolver :: SeesawResolver (Request (Ticker x) [x]) (Request [x] [x]) (Request (Ticker x) [x]) (Request [x] [x])
- lazyTickerRequestResolver :: SeesawResolver (Request (Ticker x) ([x], Either x (Ticker x))) (Request [x] [x]) (Request (Ticker x) ([x], Either x (Ticker x))) (Request [x] [x])
- parserRequestResolver :: Monoid y => SeesawResolver (Request (Parser [x] y) y) (Request [x] [x]) (Request (Parser [x] y) y) (Request [x] [x])
- lazyParserRequestResolver :: SeesawResolver (ParseRequest x) (Request [x] [x]) (ParseRequest x) (Request [x] [x])
- liftedTickerYieldResolver :: (Functor s1, Functor s2) => (forall a. Request (Ticker x) [x] a -> s1 a) -> (forall a. Yield [x] a -> s2 a) -> SeesawResolver (Request (Ticker x) [x]) (Yield [x]) s1 s2
- liftedTickerRequestResolver :: (Functor s1, Functor s2) => (forall a. Request (Ticker x) [x] a -> s1 a) -> (forall a. Request [x] [x] a -> s2 a) -> SeesawResolver (Request (Ticker x) [x]) (Request [x] [x]) s1 s2
- liftedLazyTickerRequestResolver :: (Functor s1, Functor s2) => (forall a. Request [x] [x] a -> s2 a) -> SeesawResolver (Request (Ticker x) ([x], Either x (Ticker x))) (Request [x] [x]) s1 s2
- liftedParserRequestResolver :: (Functor s1, Functor s2, Monoid y) => (forall a. Request (Parser [x] y) y a -> s1 a) -> (forall a. Request [x] [x] a -> s2 a) -> SeesawResolver (Request (Parser [x] y) y) (Request [x] [x]) s1 s2
- nestedLazyParserRequestResolver :: (Functor s1, Functor s2) => SeesawResolver (ParseRequest x) (Request [x] [x]) (EitherFunctor s1 (ParseRequest x)) (EitherFunctor s2 (Request [x] [x]))

# Suspension functors

data ParseRequest x z Source

Functor (ParseRequest x) |

data EitherFunctor l r x Source

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

(Functor l, Functor r) => Functor (EitherFunctor l r) | |

(Functor p, Functor s) => ChildFunctor (EitherFunctor p s) |

eitherFunctor :: (l x -> y) -> (r x -> y) -> EitherFunctor l r x -> ySource

Like `either`

for the EitherFunctor data type.

yield :: Monad m => x -> Coroutine (Yield x) m ()Source

Suspend the current coroutine yielding a value.

await :: Monad m => Coroutine (Await x) m xSource

Suspend the current coroutine until a value is provided.

request :: Monad m => x -> Coroutine (Request x y) m ySource

Suspend yielding a request and awaiting the response.

requestParse :: (Monad m, MonoidNull y) => Parser [x] y -> Coroutine (ParseRequest x) m (y, Maybe (Parser [x] y))Source

Suspend yielding a request and awaiting the response.

# Utility functions

concatYields :: (Monad m, Foldable f) => Coroutine (Yield (f x)) m r -> Coroutine (Yield x) m rSource

Converts a coroutine yielding collections of values into one yielding single values.

concatAwaits :: (Monad m, Foldable f) => Coroutine (Await x) m r -> Coroutine (Await (f x)) m rSource

Converts a coroutine awaiting single values into one awaiting collections of values.

# Resolvers for running pairs of coroutines

awaitYieldResolver :: SeesawResolver (Await x) (Yield x) s1 s2Source

A `SeesawResolver`

for running two coroutines in parallel, one of which `await`

s values while the other `yield`

s
them. The yielding coroutine must not terminate before the other one.

awaitMaybeYieldResolver :: SeesawResolver (Await (Maybe x)) (Yield x) s1 s2Source

A `SeesawResolver`

for running two coroutines in parallel, one of which `await`

s values while the other `yield`

s
them. If the yielding coroutine terminates before the awaiting one, the latter will receive `Nothing`

.

awaitYieldChunkResolver :: SeesawResolver (Await [x]) (Yield [x]) s1 s2Source

A `SeesawResolver`

for running two coroutines in parallel, one of which `await`

s non-empty lists of values while
the other `yield`

s them. If the yielding coroutine dies, the awaiting coroutine receives empty lists.

requestsResolver :: SeesawResolver (Request x y) (Request y x) s1 s2Source

A `SeesawResolver`

for running two `request`

ing coroutines in parallel. One coroutine's request becomes the other's
response, and vice versa.

tickerYieldResolver :: SeesawResolver (Request (Ticker x) [x]) (Yield [x]) (Request (Ticker x) [x]) (Yield [x])Source

A `SeesawResolver`

for running two coroutines in parallel. One coroutine produces data in chunks, the other
consumes data in chunks. The boundaries of the two kinds of chunks need not be the same, as the consumed chunks
are determined by a `Ticker`

provided by the consumer's input request.

tickerRequestResolver :: SeesawResolver (Request (Ticker x) [x]) (Request [x] [x]) (Request (Ticker x) [x]) (Request [x] [x])Source

Like `tickerYieldResolver`

, the only difference being that the producing coroutine sends its chunks using `request`

rather than `yield`

. The feedback received from `request`

is the unconsumed remainder of the chunk, which lets the
coroutine know when its sibling terminates.

lazyTickerRequestResolver :: SeesawResolver (Request (Ticker x) ([x], Either x (Ticker x))) (Request [x] [x]) (Request (Ticker x) ([x], Either x (Ticker x))) (Request [x] [x])Source

Like `tickerRequestResolver`

, except the consuming coroutine requests receive both the selected prefix of the input
chunk and a peek at either the next unconsumed input item, if any, or the final `Ticker`

value. Chunks sent by the
producing coroutine never get combined for the consuming coroutine. This allows better synchronization between the
two coroutines. It also leaks the information about the produced chunk boundaries into the consuming coroutine, so
this resolver should be used with caution.

parserRequestResolver :: Monoid y => SeesawResolver (Request (Parser [x] y) y) (Request [x] [x]) (Request (Parser [x] y) y) (Request [x] [x])Source

lazyParserRequestResolver :: SeesawResolver (ParseRequest x) (Request [x] [x]) (ParseRequest x) (Request [x] [x])Source

Like `parserRequestResolver`

, except the consuming coroutine requests receive both the selected prefix of the input
chunk and a peek at either the next unconsumed input item, if any, or the final `Parser`

value. Chunks sent by the
producing coroutine never get combined for the consuming coroutine. This allows better synchronization between the
two coroutines. It also leaks the information about the produced chunk boundaries into the consuming coroutine, so
this resolver should be used with caution.

liftedTickerYieldResolver :: (Functor s1, Functor s2) => (forall a. Request (Ticker x) [x] a -> s1 a) -> (forall a. Yield [x] a -> s2 a) -> SeesawResolver (Request (Ticker x) [x]) (Yield [x]) s1 s2Source

A generic version of `tickerYieldResolver`

, allowing coroutines with `Request`

and `Yield`

functors embedded in
other functors.

liftedTickerRequestResolver :: (Functor s1, Functor s2) => (forall a. Request (Ticker x) [x] a -> s1 a) -> (forall a. Request [x] [x] a -> s2 a) -> SeesawResolver (Request (Ticker x) [x]) (Request [x] [x]) s1 s2Source

A generic version of `tickerRequestResolver`

, allowing coroutines with `Request`

functors embedded in other
functors.

liftedLazyTickerRequestResolver :: (Functor s1, Functor s2) => (forall a. Request [x] [x] a -> s2 a) -> SeesawResolver (Request (Ticker x) ([x], Either x (Ticker x))) (Request [x] [x]) s1 s2Source

A generic version of `lazyTickerRequestResolver`

, allowing coroutines with `Request`

functors embedded in other
functors.

liftedParserRequestResolver :: (Functor s1, Functor s2, Monoid y) => (forall a. Request (Parser [x] y) y a -> s1 a) -> (forall a. Request [x] [x] a -> s2 a) -> SeesawResolver (Request (Parser [x] y) y) (Request [x] [x]) s1 s2Source

A generic version of `parserRequestResolver`

, allowing coroutines with `Request`

functors embedded in other
functors.

nestedLazyParserRequestResolver :: (Functor s1, Functor s2) => SeesawResolver (ParseRequest x) (Request [x] [x]) (EitherFunctor s1 (ParseRequest x)) (EitherFunctor s2 (Request [x] [x]))Source

A generic version of `lazyParserRequestResolver`

, allowing coroutines with `Request`

functors embedded in other
functors.