LanguageExt.Core

LanguageExt.Core Effects Pipes

This feature of language-ext is based on the wonderful work of Gabriella Gonzalez on the Haskell Pipes library. I have had to make some significant changes to make it work in C#, but the essence is the same, and the core types and composition of the components is exactly the same.

Conventional stream programming forces you to choose only two of the following three features:

  1. Effects
  2. Streaming
  3. Composability

If you sacrifice Effects you get IEnumerable, which you can transform using composable functions in constant space, but without interleaving effects (other than of the imperative kind).

If you sacrifice Streaming you get 'Traverse' and 'Sequence', which are composable and effectful, but do not return a single result until the whole list has first been processed and loaded into memory.

If you sacrifice Composability you write a tightly coupled for loops, and fire off imperative side-effects like they're going out of style. Which is streaming and effectful, but is not modular or separable.

Pipes gives you all three features: effectful, streaming, and composable programming. Pipes also provides a wide variety of stream programming abstractions which are all subsets of a single unified machinery:

On top of that, Pipes has more advanced features, including bi-directional streaming. This comes into play when fusing clients and servers:

All of these are connectable and you can combine them together in clever and unexpected ways because they all share the same underlying type.

The pipes ecosystem decouples stream processing stages from each other so that you can mix and match diverse stages to produce useful streaming programs. If you are a library writer, pipes lets you package up streaming components into a reusable interface. If you are an application writer, pipes lets you connect pre-made streaming components with minimal effort to produce a highly-efficient program that streams data in constant memory.

To enforce loose coupling, components can only communicate using two commands:

Pipes has four types of components built around these two commands:

Pipes uses parametric polymorphism (i.e. generics) to overload all operations.

You've probably noticed this overloading already:

This overloading is great when it works, but when connections fail they produce type errors that appear intimidating at first. This section explains the underlying types so that you can work through type errors intelligently.

Producer, Consumer, Pipe, and Effect are all special cases of a single underlying type: Proxy. This overarching type permits fully bidirectional communication on both an upstream and downstream interface.

You can think of it as having the following shape:

Proxy<RT, UOut, UIn, DIn, DOut, A>

      Upstream | Downstream
          +---------+
          |         |
    UOut ◄--       ◄-- DIn   -- Information flowing upstream
          |         |
    UIn --►        --► DOut  -- Information flowing downstream
          |    |    |
          +----|----+
               |
               A
    

The four core types do not use the upstream flow of information. This means that the UOut and DIn in the above diagram go unused unless you use the more advanced features.

Pipes uses type synonyms to hide unused inputs or outputs and clean up type signatures. These type synonyms come in two flavors:

The concrete type synonyms use Unit to close unused inputs and Void (the uninhabited type) to close unused outputs:

When you compose Proxy using | all you are doing is placing them side by side and fusing them laterally. For example, when you compose a Producer, Pipe, and a Consumer, you can think of information flowing like this:

            Producer                Pipe                 Consumer
         +------------+          +------------+          +-------------+
         |            |          |            |          |             |
   Void ◄--          ◄--  Unit   ◄--         ◄--  Unit  ◄--           ◄-- Unit
         |  readLine  |          |  parseInt  |          |  writeLine  |
   Unit --►         --► string  --►          --► string --►           --► Void
         |     |      |          |    |       |          |      |      |
         +-----|------+          +----|-------+          +------|------+
               v                     v                       v
               ()                    ()                      ()

Composition fuses away the intermediate interfaces, leaving behind an Effect:

                       Effect
        +-----------------------------------+
        |                                   |
  Void ◄--                                 ◄-- Unit
        |  readLine | parseInt | writeLine  |
  Unit --►                                 --► Void
        |                                   |
        +----------------|------------------+
                        Unit

Contents

Sub modules

Client
Consumer
Effect
Enumerate
Extensions
Pipe
Producer
PureProxy
Queue
RequestRespond
Resource
Server

class Proxy <RT, UOut, UIn, DIn, DOut, A> Source #

where RT : struct, HasCancel<RT>

A Proxy is a monad transformer that receives and sends information on both an upstream and downstream interface. It is the base type for all of the key other important types in the Pipes ecosystem, like Producer, Consumer, Pipe, etc.

Diagrammatically, you can think of a Proxy as having the following shape:

    Upstream | Downstream
        +---------+
        |         |
  UOut ◄--       ◄-- DIn
        |         |
  UIn  --►       --► DOut
        |    |    |
        +----|----+
             A

You can connect proxies together in five different ways:

  1. Connect pull-based streams
  2. Connect push-based streams
  3. Chain folds
  4. Chain unfolds
  5. Sequence proxies

The type variables signify:

  • UOut and Uin - The upstream interface, where UOut go out and UIn come in
  • DOut and DIn - The downstream interface, where DOut go out and DIn come in
  • RT - The runtime of the transformed effect monad
  • A - The return value

Parameters

type RT

Aff system runtime

type UOut

Upstream out type

type UIn

Upstream in type

type DIn

Downstream in type

type DOut

Downstream uut type

type A

The monadic bound variable - it doesn't flow up or down stream, it works just like any bound monadic variable. If the effect represented by the Proxy ends, then this will be the result value.

When composing Proxy sub-types (like Producer, Pipe, Consumer, etc.)

Methods

method Proxy<RT, UOut, UIn, DIn, DOut, A> ToProxy () Source #

When working with sub-types, like Producer, calling this will effectively cast the sub-type to the base.

Parameters

returns

A general Proxy type from a more specialised type

method Proxy<RT, UOut, UIn, DIn, DOut, B> Bind <B> (Func<A, Proxy<RT, UOut, UIn, DIn, DOut, B>> f) Source #

Monadic bind operation, for chaining Proxy computations together.

Parameters

type B

The mapped bound value type

param f

The bind function

returns

A new Proxy that represents the composition of this Proxy and the result of the bind operation

method Proxy<RT, UOut, UIn, DIn, DOut, B> Map <B> (Func<A, B> f) Source #

Lifts a pure function into the Proxy domain, causing it to map the bound value within

Parameters

type B

The mapped bound value type

param f

The map function

returns

A new Proxy that represents the composition of this Proxy and the result of the map operation

method Proxy<RT, UOut, UIn, C1, C, A> For <C1, C> (Func<DOut, Proxy<RT, UOut, UIn, C1, C, DIn>> body) Source #

For(body) loops over the Proxy p replacing each yield with body

Parameters

param body

Any yield found in the Proxy will be replaced with this function. It will be composed so that the value yielded will be passed to the argument of the function. That returns a Proxy to continue the processing of the computation

returns

A new Proxy that represents the composition of this Proxy and the function provided

method Proxy<RT, UOut, UIn, DIn, DOut, B> Action <B> (Proxy<RT, UOut, UIn, DIn, DOut, B> r) Source #

Applicative action

Invokes this Proxy, then the Proxy r

Parameters

param r

Proxy to run after this one

method Proxy<RT, UOutA, AUInA, DIn, DOut, A> PairEachRequestWithRespond <UOutA, AUInA> ( Func<UOut, Proxy<RT, UOutA, AUInA, UOut, UIn, A>> lhs) Source #

Used by the various composition functions and when composing proxies with the | operator. You usually wouldn't need to call this directly, instead either pipe them using | or call Proxy.compose(lhs, rhs)

(f +>> p) pairs each 'request' in this with a 'respond' in lhs.

method Proxy<RT, UOutA, AUInA, DIn, DOut, A> ReplaceRequest <UOutA, AUInA> ( Func<UOut, Proxy<RT, UOutA, AUInA, DIn, DOut, UIn>> lhs) Source #

Used by the various composition functions and when composing proxies with the | operator. You usually wouldn't need to call this directly, instead either pipe them using | or call Proxy.compose(lhs, rhs)

method Proxy<RT, UOut, UIn, DInC, DOutC, A> PairEachRespondWithRequest <DInC, DOutC> ( Func<DOut, Proxy<RT, DIn, DOut, DInC, DOutC, A>> rhs) Source #

Used by the various composition functions and when composing proxies with the | operator. You usually wouldn't need to call this directly, instead either pipe them using | or call Proxy.compose(lhs, rhs)

method Proxy<RT, UOut, UIn, DInC, DOutC, A> ReplaceRespond <DInC, DOutC> ( Func<DOut, Proxy<RT, UOut, UIn, DInC, DOutC, DIn>> rhs) Source #

Used by the various composition functions and when composing proxies with the | operator. You usually wouldn't need to call this directly, instead either pipe them using | or call Proxy.compose(lhs, rhs)

method Proxy<RT, DOut, DIn, UIn, UOut, A> Reflect () Source #

Reverse the arrows of the Proxy to find its dual.

Parameters

returns

The dual of this

method Proxy<RT, UOut, UIn, DIn, DOut, A> Observe () Source #

Observe(lift (Pure(r))) = Observe(Pure(r))
Observe(lift (m.Bind(f))) = Observe(lift(m.Bind(x => lift(f(x)))))

This correctness comes at a small cost to performance, so use this function sparingly. This function is a convenience for low-level pipes implementers. You do not need to use observe if you stick to the safe API.

method Proxy<RT, UOut, UIn, DIn, DOut, B> SelectMany <B> (Func<A, Proxy<RT, UOut, UIn, DIn, DOut, B>> f) Source #

Monadic bind operation, enables usage in LINQ expressions

Parameters

type B

The new bound value type

param f

The bind function

returns

The result of the bind composition

method Proxy<RT, UOut, UIn, DIn, DOut, C> SelectMany <B, C> ( Func<A, Proxy<RT, UOut, UIn, DIn, DOut, B>> f, Func<A, B, C> project) Source #

Monadic bind operation, followed by a mapping projection, enables usage in LINQ expressions

Parameters

type C

The new bound value type

param f

The bind function

param prject

The mapping projection function

returns

The result of the bind and mapping composition

method Proxy<RT, UOut, UIn, DIn, DOut, B> Select <B> (Func<A, B> f) Source #

Functor map operation, enables usage in LINQ expressions

Parameters

type B

The new bound value type

param f

Map function

returns

The result of the lifted function applied to the bound value

class Pure <RT, UOut, UIn, DIn, DOut, A> Source #

where RT : struct, HasCancel<RT>

One of the algebraic cases of the Proxy type. This type represents a pure value. It can be thought of as the terminating value of the computation, as there's not continuation attached to this case.

Parameters

type RT

Aff system runtime

type UOut

Upstream out type

type UIn

Upstream in type

type DIn

Downstream in type

type DOut

Downstream uut type

type A

The monadic bound variable - it doesn't flow up or down stream, it works just like any bound monadic variable. If the effect represented by the Proxy ends, then this will be the result value.

When composing Proxy sub-types (like Producer, Pipe, Consumer, etc.)

Fields

field A Value Source #

Constructors

constructor Pure (A value) Source #

Methods

method Proxy<RT, UOut, UIn, DIn, DOut, A> ToProxy () Source #

When working with sub-types, like Producer, calling this will effectively cast the sub-type to the base.

Parameters

returns

A general Proxy type from a more specialised type

method Proxy<RT, UOut, UIn, DIn, DOut, B> Bind <B> (Func<A, Proxy<RT, UOut, UIn, DIn, DOut, B>> f) Source #

Monadic bind operation, for chaining Proxy computations together

Parameters

type B

The mapped bound value type

param f

The bind function

returns

A new Proxy that represents the composition of this Proxy and the result of the bind operation

method Proxy<RT, UOut, UIn, DIn, DOut, B> Map <B> (Func<A, B> f) Source #

Lifts a pure function into the Proxy domain, causing it to map the bound value within

Parameters

type B

The mapped bound value type

param f

The map function

returns

A new Proxy that represents the composition of this Proxy and the result of the map operation

method Proxy<RT, UOut, UIn, C1, C, A> For <C1, C> (Func<DOut, Proxy<RT, UOut, UIn, C1, C, DIn>> body) Source #

For(body) loops over the Proxy p replacing each yield with body

Parameters

param body

Any yield found in the Proxy will be replaced with this function. It will be composed so that the value yielded will be passed to the argument of the function. That returns a Proxy to continue the processing of the computation

returns

method Proxy<RT, UOut, UIn, DIn, DOut, B> Action <B> (Proxy<RT, UOut, UIn, DIn, DOut, B> r) Source #

Applicative action

Invokes this Proxy, then the Proxy r

Parameters

param r

Proxy to run after this one

method Proxy<RT, UOutA, AUInA, DIn, DOut, A> PairEachRequestWithRespond <UOutA, AUInA> ( Func<UOut, Proxy<RT, UOutA, AUInA, UOut, UIn, A>> _) Source #

Used by the various composition functions and when composing proxies with the | operator. You usually wouldn't need to call this directly, instead either pipe them using | or call Proxy.compose(lhs, rhs)

(f +>> p) pairs each 'request' in this with a 'respond' in lhs.

method Proxy<RT, UOutA, AUInA, DIn, DOut, A> ReplaceRequest <UOutA, AUInA> ( Func<UOut, Proxy<RT, UOutA, AUInA, DIn, DOut, UIn>> _) Source #

Used by the various composition functions and when composing proxies with the | operator. You usually wouldn't need to call this directly, instead either pipe them using | or call Proxy.compose(lhs, rhs)

method Proxy<RT, UOut, UIn, DInC, DOutC, A> PairEachRespondWithRequest <DInC, DOutC> ( Func<DOut, Proxy<RT, DIn, DOut, DInC, DOutC, A>> _) Source #

Used by the various composition functions and when composing proxies with the | operator. You usually wouldn't need to call this directly, instead either pipe them using | or call Proxy.compose(lhs, rhs)

method Proxy<RT, UOut, UIn, DInC, DOutC, A> ReplaceRespond <DInC, DOutC> ( Func<DOut, Proxy<RT, UOut, UIn, DInC, DOutC, DIn>> _) Source #

Used by the various composition functions and when composing proxies with the | operator. You usually wouldn't need to call this directly, instead either pipe them using | or call Proxy.compose(lhs, rhs)

method Proxy<RT, DOut, DIn, UIn, UOut, A> Reflect () Source #

Reverse the arrows of the Proxy to find its dual.

Parameters

returns

The dual of `this1

method Proxy<RT, UOut, UIn, DIn, DOut, A> Observe () Source #

Observe(lift (Pure(r))) = Observe(Pure(r))
Observe(lift (m.Bind(f))) = Observe(lift(m.Bind(x => lift(f(x)))))

This correctness comes at a small cost to performance, so use this function sparingly. This function is a convenience for low-level pipes implementers. You do not need to use observe if you stick to the safe API.

method void Deconstruct (out A value) Source #

class M <RT, UOut, UIn, DIn, DOut, A> Source #

where RT : struct, HasCancel<RT>

One of the algebraic cases of the Proxy type. This type lifts an Aff<RT, A> monadic computation into the Proxy monad. This is how the Proxy system can cause real-world effects.

Parameters

type RT

Aff system runtime

type UOut

Upstream out type

type UIn

Upstream in type

type DIn

Downstream in type

type DOut

Downstream uut type

type A

The monadic bound variable - it doesn't flow up or down stream, it works just like any bound monadic variable. If the effect represented by the Proxy ends, then this will be the result value.

When composing Proxy sub-types (like Producer, Pipe, Consumer, etc.)

Fields

field Aff<RT, Proxy<RT, UOut, UIn, DIn, DOut, A>> Value Source #

Constructors

constructor M (Aff<RT, Proxy<RT, UOut, UIn, DIn, DOut, A>> value) Source #

Methods

method Proxy<RT, UOut, UIn, DIn, DOut, A> ToProxy () Source #

When working with sub-types, like Producer, calling this will effectively cast the sub-type to the base.

Parameters

returns

A general Proxy type from a more specialised type

method Proxy<RT, UOut, UIn, DIn, DOut, S> Bind <S> (Func<A, Proxy<RT, UOut, UIn, DIn, DOut, S>> f) Source #

Monadic bind operation, for chaining Proxy computations together

Parameters

type B

The mapped bound value type

param f

The bind function

returns

A new Proxy that represents the composition of this Proxy and the result of the bind operation

method Proxy<RT, UOut, UIn, DIn, DOut, S> Map <S> (Func<A, S> f) Source #

Lifts a pure function into the Proxy domain, causing it to map the bound value within

Parameters

type B

The mapped bound value type

param f

The map function

returns

A new Proxy that represents the composition of this Proxy and the result of the map operation

method Proxy<RT, UOut, UIn, C1, C, A> For <C1, C> (Func<DOut, Proxy<RT, UOut, UIn, C1, C, DIn>> body) Source #

For(body) loops over the Proxy p replacing each yield with body

Parameters

param body

Any yield found in the Proxy will be replaced with this function. It will be composed so that the value yielded will be passed to the argument of the function. That returns a Proxy to continue the processing of the computation

returns

method Proxy<RT, UOut, UIn, DIn, DOut, S> Action <S> (Proxy<RT, UOut, UIn, DIn, DOut, S> r) Source #

Applicative action

Invokes this Proxy, then the Proxy r

Parameters

param r

Proxy to run after this one

method Proxy<RT, UOutA, AUInA, DIn, DOut, A> PairEachRequestWithRespond <UOutA, AUInA> ( Func<UOut, Proxy<RT, UOutA, AUInA, UOut, UIn, A>> fb1) Source #

Used by the various composition functions and when composing proxies with the | operator. You usually wouldn't need to call this directly, instead either pipe them using | or call Proxy.compose(lhs, rhs)

(f +>> p) pairs each 'request' in this with a 'respond' in fb1.

method Proxy<RT, UOutA, AUInA, DIn, DOut, A> ReplaceRequest <UOutA, AUInA> ( Func<UOut, Proxy<RT, UOutA, AUInA, DIn, DOut, UIn>> lhs) Source #

Used by the various composition functions and when composing proxies with the | operator. You usually wouldn't need to call this directly, instead either pipe them using | or call Proxy.compose(lhs, rhs)

method Proxy<RT, UOut, UIn, DInC, DOutC, A> PairEachRespondWithRequest <DInC, DOutC> ( Func<DOut, Proxy<RT, DIn, DOut, DInC, DOutC, A>> rhs) Source #

Used by the various composition functions and when composing proxies with the | operator. You usually wouldn't need to call this directly, instead either pipe them using | or call Proxy.compose(lhs, rhs)

method Proxy<RT, UOut, UIn, DInC, DOutC, A> ReplaceRespond <DInC, DOutC> ( Func<DOut, Proxy<RT, UOut, UIn, DInC, DOutC, DIn>> rhs) Source #

Used by the various composition functions and when composing proxies with the | operator. You usually wouldn't need to call this directly, instead either pipe them using | or call Proxy.compose(lhs, rhs)

method Proxy<RT, DOut, DIn, UIn, UOut, A> Reflect () Source #

Reverse the arrows of the Proxy to find its dual.

Parameters

returns

The dual of `this1

method Proxy<RT, UOut, UIn, DIn, DOut, A> Observe () Source #

Observe(lift (Pure(r))) = Observe(Pure(r))
Observe(lift (m.Bind(f))) = Observe(lift(m.Bind(x => lift(f(x)))))

This correctness comes at a small cost to performance, so use this function sparingly. This function is a convenience for low-level pipes implementers. You do not need to use observe if you stick to the safe API.

method void Deconstruct (out Aff<RT, Proxy<RT, UOut, UIn, DIn, DOut, A>> value) Source #

class Proxy Source #

The static Proxy class is the Prelude of the Pipes system.

Methods

method Pure<A> Pure <A> (A value) Source #

Monad return / pure

method Consumer<A, A> awaiting <A> () Source #

Wait for a value to flow from upstream (whilst in a Pipe or a Consumer)

method Producer<A, Unit> yield <A> (A value) Source #

Send a value flowing downstream (whilst in a Producer or a Pipe)

method Queue<RT, A, Unit> Queue <RT, A> () Source #

where RT : struct, HasCancel<RT>

Create a queue

A Queue is a Producer with an Enqueue, and a Done to cancel the operation

method Producer<X, Unit> yieldAll <X> (IEnumerable<X> xs) Source #

Create a Producer from an IEnumerable. This will automatically yield each value of the IEnumerable down stream

Parameters

type X

Type of the value to yield

param xs

Items to yield

returns

Producer

method Producer<X, Unit> yieldAll <X> (IAsyncEnumerable<X> xs) Source #

Create a Producer from an IAsyncEnumerable. This will automatically yield each value of the IEnumerable down stream

Parameters

type X

Type of the value to yield

param xs

Items to yield

returns

Producer

method Producer<X, Unit> yieldAll <X> (IObservable<X> xs) Source #

Create a Producer from an IObservable. This will automatically yield each value of the IObservable down stream

Parameters

type X

Type of the value to yield

param xs

Items to yield

returns

Producer

method Lift<RT, R> lift <RT, R> (Eff<RT, R> ma) Source #

where RT : struct, HasCancel<RT>

Lift the Eff monad into the monad transformer

method Lift<RT, R> lift <RT, R> (Aff<RT, R> ma) Source #

where RT : struct, HasCancel<RT>

Lift the Aff monad into the monad transformer

method Lift<RT, R> lift <RT, R> (Eff<R> ma) Source #

where RT : struct, HasCancel<RT>

Lift the Eff monad into the monad transformer

method Lift<RT, R> lift <RT, R> (Aff<R> ma) Source #

where RT : struct, HasCancel<RT>

Lift the Aff monad into the monad transformer

method Lift<RT, R> use <RT, R> (Eff<RT, R> ma) Source #

where RT : struct, HasCancel<RT>
where R : IDisposable

Lift the Eff monad into the monad transformer

method Lift<RT, R> use <RT, R> (Aff<RT, R> ma) Source #

where RT : struct, HasCancel<RT>
where R : IDisposable

Lift the Aff monad into the monad transformer

method Lift<RT, R> use <RT, R> (Eff<R> ma) Source #

where RT : struct, HasCancel<RT>
where R : IDisposable

Lift the Eff monad into the monad transformer

method Lift<RT, R> use <RT, R> (Aff<R> ma) Source #

where RT : struct, HasCancel<RT>
where R : IDisposable

Lift the Aff monad into the monad transformer

method Release<Unit> release <A> (A value) Source #

Release a previously used resource

method Producer<RT, OUT, Unit> repeat <RT, OUT, R> (Producer<RT, OUT, R> ma) Source #

where RT : struct, HasCancel<RT>

Repeat the Producer indefinitely

method Consumer<RT, IN, Unit> repeat <RT, IN, R> (Consumer<RT, IN, R> ma) Source #

where RT : struct, HasCancel<RT>

Repeat the Consumer indefinitely

method Pipe<RT, IN, OUT, Unit> repeat <RT, IN, OUT, R> (Pipe<RT, IN, OUT, R> ma) Source #

where RT : struct, HasCancel<RT>

Repeat the Pipe indefinitely

method Proxy<RT, A1, A, B1, B, R> lift <RT, A1, A, B1, B, R> (Aff<R> ma) Source #

where RT : struct, HasCancel<RT>

Lift am IO monad into the Proxy monad transformer

method Proxy<RT, A1, A, B1, B, R> lift <RT, A1, A, B1, B, R> (Eff<R> ma) Source #

where RT : struct, HasCancel<RT>

Lift am IO monad into the Proxy monad transformer

method Proxy<RT, A1, A, B1, B, R> lift <RT, A1, A, B1, B, R> (Aff<RT, R> ma) Source #

where RT : struct, HasCancel<RT>

Lift am IO monad into the Proxy monad transformer

method Proxy<RT, A1, A, B1, B, R> lift <RT, A1, A, B1, B, R> (Eff<RT, R> ma) Source #

where RT : struct, HasCancel<RT>

Lift am IO monad into the Proxy monad transformer

method Proxy<RT, A1, A, B1, B, R> use <RT, A1, A, B1, B, R> (Aff<R> ma) Source #

where RT : struct, HasCancel<RT>
where R : IDisposable

Lift am IO monad into the Proxy monad transformer

method Proxy<RT, A1, A, B1, B, R> use <RT, A1, A, B1, B, R> (Eff<R> ma) Source #

where RT : struct, HasCancel<RT>
where R : IDisposable

Lift am IO monad into the Proxy monad transformer

method Proxy<RT, A1, A, B1, B, R> use <RT, A1, A, B1, B, R> (Aff<RT, R> ma) Source #

where RT : struct, HasCancel<RT>
where R : IDisposable

Lift am IO monad into the Proxy monad transformer

method Proxy<RT, A1, A, B1, B, R> use <RT, A1, A, B1, B, R> (Eff<RT, R> ma) Source #

where RT : struct, HasCancel<RT>
where R : IDisposable

Lift am IO monad into the Proxy monad transformer

method Proxy<RT, A1, A, B1, B, R> use <RT, A1, A, B1, B, R> (Aff<R> ma, Func<R, Unit> dispose) Source #

where RT : struct, HasCancel<RT>

Lift am IO monad into the Proxy monad transformer

method Proxy<RT, A1, A, B1, B, R> use <RT, A1, A, B1, B, R> (Eff<R> ma, Func<R, Unit> dispose) Source #

where RT : struct, HasCancel<RT>

Lift am IO monad into the Proxy monad transformer

method Proxy<RT, A1, A, B1, B, R> use <RT, A1, A, B1, B, R> (Aff<RT, R> ma, Func<R, Unit> dispose) Source #

where RT : struct, HasCancel<RT>

Lift am IO monad into the Proxy monad transformer

method Proxy<RT, A1, A, B1, B, R> use <RT, A1, A, B1, B, R> (Eff<RT, R> ma, Func<R, Unit> dispose) Source #

where RT : struct, HasCancel<RT>

Lift am IO monad into the Proxy monad transformer

method Proxy<RT, A1, A, B1, B, Unit> release <RT, A1, A, B1, B, R> (R dispose) Source #

where RT : struct, HasCancel<RT>

Release a previously used resource

method Pipe<RT, A, A, R> cat <RT, A, R> () Source #

where RT : struct, HasCancel<RT>

The identity Pipe, simply replicates its upstream value and propagates it downstream

method Proxy<RT, UOut, UIn, UOut, UIn, A> pull <RT, UOut, UIn, A> (UOut a1) Source #

where RT : struct, HasCancel<RT>

Forward requests followed by responses

pull = request | respond | pull

pull is the identity of the pull category.

method Proxy<RT, UOut, UIn, UOut, UIn, A> push <RT, UOut, UIn, A> (UIn a) Source #

where RT : struct, HasCancel<RT>

push = respond | request | push

push is the identity of the push category.

method Proxy<RT, X1, X, DIn, DOut, DIn> respond <RT, X1, X, DIn, DOut> (DOut value) Source #

where RT : struct, HasCancel<RT>

Send a value of type DOut downstream and block waiting for a reply of type DIn

respond is the identity of the respond category.

method Proxy<RT, UOut, UIn, Y1, Y, UIn> request <RT, UOut, UIn, Y1, Y> (UOut value) Source #

where RT : struct, HasCancel<RT>

Send a value of type UOut upstream and block waiting for a reply of type UIn

request is the identity of the request category.

method Proxy<RT, DOut, DIn, UIn, UOut, R> reflect <RT, UOut, UIn, DIn, DOut, R> ( Proxy<RT, UOut, UIn, DIn, DOut, R> p) Source #

where RT : struct, HasCancel<RT>

reflect transforms each streaming category into its dual:

The request category is the dual of the respond category

 reflect . respond = request
 reflect . (f | g) = reflect . f | reflect . g
 reflect . request = respond
 reflect . (f | g) = reflect . f | reflect . g

The pull category is the dual of the push category

 reflect . push = pull
 reflect . (f | g) = reflect . f | reflect . g
 reflect . pull = push
 reflect . (f | g) = reflect . f | reflect . g

method Producer<RT, OUT_B, A> ForEach <RT, OUT_A, OUT_B, A> ( this Producer<RT, OUT_A, A> p, Func<OUT_A, Producer<RT, OUT_B, Unit>> body) Source #

where RT : struct, HasCancel<RT>

p.ForEach(body) loops over the Producer p replacing each yield with body

Producer b r -> (b -> Producer c ()) -> Producer c r

method Effect<RT, A> ForEach <RT, OUT, A> ( this Producer<RT, OUT, A> p, Func<OUT, Effect<RT, Unit>> fb) Source #

where RT : struct, HasCancel<RT>

p.ForEach(body) loops over Producer p replacing each yield with body

Producer b r -> (b -> Effect ()) -> Effect r

method Consumer<RT, IN, A> ForEach <RT, IN, OUT, A> ( this Pipe<RT, IN, OUT, A> p0, Func<OUT, Consumer<RT, IN, Unit>> fb) Source #

where RT : struct, HasCancel<RT>

p.ForEach(body) loops over Pipe p replacing each yield with body

Pipe x b r -> (b -> Consumer x ()) -> Consumer x r

method Pipe<RT, IN, OUT, R> ForEach <RT, IN, B, OUT, R> ( this Pipe<RT, IN, B, R> p0, Func<B, Pipe<RT, IN, OUT, Unit>> fb) Source #

where RT : struct, HasCancel<RT>

p.ForEach(body) loops over Pipe p replacing each yield with body

Pipe x b r -> (b -> Pipe x c ()) -> Pipe x c r

method Proxy<RT, UOut, UIn, DIn, DOut, B> compose <RT, UOut, UIn, DIn, DOut, A, B> ( Proxy<RT, UOut, UIn, DIn, DOut, A> p1, Proxy<RT, Unit, A, DIn, DOut, B> p2) Source #

where RT : struct, HasCancel<RT>

compose(draw, p) loops over p replacing each await with draw

method Effect<RT, A> compose <RT, OUT, A> ( Effect<RT, OUT> p1, Consumer<RT, OUT, A> p2) Source #

where RT : struct, HasCancel<RT>

compose(draw, p) loops over p replacing each await with draw

Effect b -> Consumer b c -> Effect c

method Consumer<RT, A, C> compose <RT, A, B, C> ( Consumer<RT, A, B> p1, Consumer<RT, B, C> p2) Source #

where RT : struct, HasCancel<RT>

compose(draw, p) loops over p replacing each await with draw

Consumer a b -> Consumer b c -> Consumer a c

method Producer<RT, OUT, C> compose <RT, OUT, IN, C> ( Producer<RT, OUT, IN> p1, Pipe<RT, IN, OUT, C> p2) Source #

where RT : struct, HasCancel<RT>

compose(draw, p) loops over p replacing each await with draw

Producer y b -> Pipe b y m c -> Producer y c

method Pipe<RT, A, Y, C> compose <RT, Y, A, B, C> ( Pipe<RT, A, Y, B> p1, Pipe<RT, B, Y, C> p2) Source #

where RT : struct, HasCancel<RT>

compose(draw, p) loops over p replacing each await with draw

Pipe a y b -> Pipe b y c -> Pipe a y c

method Proxy<RT, A1, A, Y1, Y, C> compose <RT, A1, A, Y1, Y, B, C> ( Proxy<RT, Unit, B, Y1, Y, C> p2, Proxy<RT, A1, A, Y1, Y, B> p1) Source #

where RT : struct, HasCancel<RT>

method Proxy<RT, A1, A, Y1, Y, C> compose <RT, A1, A, B1, B, Y1, Y, C> ( Func<B1, Proxy<RT, A1, A, Y1, Y, B>> fb1, Proxy<RT, B1, B, Y1, Y, C> p0) Source #

where RT : struct, HasCancel<RT>

Replaces each request or respond in p0 with fb1.

method Proxy<RT, A1, A, C1, C, R> compose <RT, A1, A, B1, B, C1, C, R> ( Proxy<RT, A1, A, B1, B, R> p, Func<B, Proxy<RT, B1, B, C1, C, R>> fb) Source #

where RT : struct, HasCancel<RT>

compose(p, f) pairs each respond in p with a request in f.

method Proxy<RT, A1, A, C1, C, R> compose <RT, A1, A, B1, B, C1, C, R> ( Func<B1, Proxy<RT, A1, A, B1, B, R>> fb1, Proxy<RT, B1, B, C1, C, R> p) Source #

where RT : struct, HasCancel<RT>

compose(f, p) pairs each request in p with a respond in f

method Proxy<RT, A1, A, C1, C, R> compose <RT, A1, A, B, C1, C, R> ( Proxy<RT, A1, A, Unit, B, R> p1, Proxy<RT, Unit, B, C1, C, R> p2) Source #

where RT : struct, HasCancel<RT>

Pipe composition

method Effect<RT, R> compose <RT, B, R> ( Producer<RT, B, R> p1, Consumer<RT, B, R> p2) Source #

where RT : struct, HasCancel<RT>

Pipe composition

Producer b r -> Consumer b r -> Effect m r

method Producer<RT, C, R> compose <RT, B, C, R> ( Producer<RT, B, R> p1, Pipe<RT, B, C, R> p2) Source #

where RT : struct, HasCancel<RT>

Pipe composition

Producer b r -> Pipe b c r -> Producer c r

method Consumer<RT, A, R> compose <RT, A, B, R> ( Pipe<RT, A, B, R> p1, Consumer<RT, B, R> p2) Source #

where RT : struct, HasCancel<RT>

Pipe composition

Pipe a b r -> Consumer b r -> Consumer a r

method Pipe<RT, A, C, R> compose <RT, A, B, C, R> ( Pipe<RT, A, B, R> p1, Pipe<RT, B, C, R> p2) Source #

where RT : struct, HasCancel<RT>

Pipe composition

Pipe a b r -> Pipe b c r -> Pipe a c r

method Func<A, Proxy<RT, X1, X, C1, C, A1>> compose <RT, X1, X, A1, A, B1, B, C1, C> ( Func<A, Proxy<RT, X1, X, B1, B, A1>> fa, Func<B, Proxy<RT, X1, X, C1, C, B1>> fb) Source #

where RT : struct, HasCancel<RT>

Compose two unfolds, creating a new unfold

This is the composition operator of the respond category.

method Func<A, Proxy<RT, X1, X, C1, C, A1>> Then <RT, X1, X, A1, A, B1, B, C1, C> ( this Func<A, Proxy<RT, X1, X, B1, B, A1>> fa, Func<B, Proxy<RT, X1, X, C1, C, B1>> fb) Source #

where RT : struct, HasCancel<RT>

Compose two unfolds, creating a new unfold

This is the composition operator of the respond category.

method Proxy<RT, X1, X, C1, C, A1> compose <RT, X1, X, A1, B1, C1, C, B> ( Proxy<RT, X1, X, B1, B, A1> p0, Func<B, Proxy<RT, X1, X, C1, C, B1>> fb) Source #

where RT : struct, HasCancel<RT>

compose(p, f) replaces each respond in p with f.

method Proxy<RT, X1, X, C1, C, A1> Then <RT, X1, X, A1, B1, C1, C, B> ( this Proxy<RT, X1, X, B1, B, A1> p0, Func<B, Proxy<RT, X1, X, C1, C, B1>> fb) Source #

where RT : struct, HasCancel<RT>

compose(p, f) replaces each respond in p with f.

method Func<C1, Proxy<RT, A1, A, Y1, Y, C>> compose <RT, A1, A, B1, B, Y1, Y, C1, C> ( Func<B1, Proxy<RT, A1, A, Y1, Y, B>> fb1, Func<C1, Proxy<RT, B1, B, Y1, Y, C>> fc1) Source #

where RT : struct, HasCancel<RT>

Compose two folds, creating a new fold

(f | g) x = f | g x

| is the composition operator of the request category.

method Proxy<RT, A1, A, B1, B, R> observe <RT, A1, A, B1, B, R> ( Proxy<RT, A1, A, B1, B, R> p0) Source #

where RT : struct, HasCancel<RT>

observe(lift (Pure(r))) = observe(Pure(r))
observe(lift (m.Bind(f))) = observe(lift(m.Bind(x => lift(f(x)))))

This correctness comes at a small cost to performance, so use this function sparingly. This function is a convenience for low-level pipes implementers. You do not need to use observe if you stick to the safe API.

method A closed <A> (Void value) Source #

Absurd function

Parameters

param value

Void is supposed to represent void, nothing can be constructed from void and so this method just throws ApplicationException("closed")

method Proxy<RT, A1, A, B1, B, S> apply <RT, A1, A, B1, B, R, S> (Proxy<RT, A1, A, B1, B, Func<R, S>> pf, Proxy<RT, A1, A, B1, B, R> px) Source #

where RT : struct, HasCancel<RT>

Applicative apply

method Proxy<RT, A1, A, B1, B, S> Apply <RT, A1, A, B1, B, R, S> (this Proxy<RT, A1, A, B1, B, Func<R, S>> pf, Proxy<RT, A1, A, B1, B, R> px) Source #

where RT : struct, HasCancel<RT>

Applicative apply

method Proxy<RT, A1, A, B1, B, S> Action <RT, A1, A, B1, B, R, S> (this Proxy<RT, A1, A, B1, B, R> l, Proxy<RT, A1, A, B1, B, S> r) Source #

where RT : struct, HasCancel<RT>

Applicative action

method Proxy<RT, A1, A, B1, B, R> Pure <RT, A1, A, B1, B, R> (R value) Source #

where RT : struct, HasCancel<RT>

Monad return / pure

method Lift<RT, (A, B)> collect <RT, A, B> (Effect<RT, A> ma, Effect<RT, B> mb) Source #

where RT : struct, HasCancel<RT>

Creates a non-yielding producer that returns the result of the effects

method Lift<RT, (A, B, C)> collect <RT, A, B, C> (Effect<RT, A> ma, Effect<RT, B> mb, Effect<RT, C> mc) Source #

where RT : struct, HasCancel<RT>

Creates a non-yielding producer that returns the result of the effects

method Lift<RT, (A, B, C, D)> collect <RT, A, B, C, D> (Effect<RT, A> ma, Effect<RT, B> mb, Effect<RT, C> mc, Effect<RT, D> md) Source #

where RT : struct, HasCancel<RT>

Creates a non-yielding producer that returns the result of the effects

method Lift<RT, (A, B, C, D, E)> collect <RT, A, B, C, D, E> (Effect<RT, A> ma, Effect<RT, B> mb, Effect<RT, C> mc, Effect<RT, D> md, Effect<RT, E> me) Source #

where RT : struct, HasCancel<RT>

Creates a non-yielding producer that returns the result of the effects

method ProducerLift<RT, (A, B), Unit> yield <RT, A, B> (Effect<RT, A> ma, Effect<RT, B> mb) Source #

where RT : struct, HasCancel<RT>

Creates a non-yielding producer that returns the result of the effects

method ProducerLift<RT, (A, B, C), Unit> yield <RT, A, B, C> (Effect<RT, A> ma, Effect<RT, B> mb, Effect<RT, C> mc) Source #

where RT : struct, HasCancel<RT>

Creates a non-yielding producer that returns the result of the effects

method ProducerLift<RT, (A, B, C, D), Unit> yield <RT, A, B, C, D> (Effect<RT, A> ma, Effect<RT, B> mb, Effect<RT, C> mc, Effect<RT, D> md) Source #

where RT : struct, HasCancel<RT>

Creates a non-yielding producer that returns the result of the effects

method ProducerLift<RT, (A, B, C, D, E), Unit> yield <RT, A, B, C, D, E> (Effect<RT, A> ma, Effect<RT, B> mb, Effect<RT, C> mc, Effect<RT, D> md, Effect<RT, E> me) Source #

where RT : struct, HasCancel<RT>

Creates a non-yielding producer that returns the result of the effects

method Pipe<A, A, Unit> filter <A> (Func<A, bool> f) Source #

Only forwards values that satisfy the predicate.

method Pipe<A, B, Unit> map <A, B> (Func<A, B> f) Source #

Map the output of the pipe (not the bound value as is usual with Map)

method Pipe<IN, OUT, Unit> foldWhile <IN, OUT> (OUT Initial, Func<OUT, IN, OUT> Fold, Func<OUT, bool> State) Source #

Folds values coming down-stream, when the predicate returns false the folded value is yielded

Parameters

param Initial

Initial state

param Fold

Fold operation

param WhileState

Predicate

returns

A pipe that folds

method Pipe<IN, OUT, Unit> foldUntil <IN, OUT> (OUT Initial, Func<OUT, IN, OUT> Fold, Func<OUT, bool> State) Source #

Folds values coming down-stream, when the predicate returns true the folded value is yielded

Parameters

param Initial

Initial state

param Fold

Fold operation

param UntilState

Predicate

returns

A pipe that folds

method Pipe<IN, OUT, Unit> foldWhile <IN, OUT> (OUT Initial, Func<OUT, IN, OUT> Fold, Func<IN, bool> Value) Source #

Folds values coming down-stream, when the predicate returns false the folded value is yielded

Parameters

param Initial

Initial state

param Fold

Fold operation

param WhileValue

Predicate

returns

A pipe that folds

method Pipe<IN, OUT, Unit> foldUntil <IN, OUT> (OUT Initial, Func<OUT, IN, OUT> Fold, Func<IN, bool> Value) Source #

Folds values coming down-stream, when the predicate returns true the folded value is yielded

Parameters

param Initial

Initial state

param Fold

Fold operation

param UntilValue

Predicate

returns

A pipe that folds

class Void Source #

Meant to represent void, but we can't construct a System.Void.

A void is the initial object in a category, equivalent to an empty set, and because there are no values in an empty set there's no way to construct a type of void. We use this type in the pipes system to represent a a 'closed' path.