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
Extensions
Iterator
Pipe
Producer
PureProxy
Queue
RequestRespond
Server

record Proxy <UOut, UIn, DIn, DOut, M, A> Source #

where M : Monad<M>

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 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<UOut, UIn, DIn, DOut, M, 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<UOut, UIn, DIn, DOut, M, B> Bind <B> (Func<A, Proxy<UOut, UIn, DIn, DOut, M, 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<UOut, UIn, DIn, DOut, M, 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<UOut, UIn, DIn, DOut, M, B> MapM <B> (Func<K<M, A>, K<M, B>> f) Source #

Map the lifted monad

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<UOut, UIn, C1, C, M, A> For <C1, C> (Func<DOut, Proxy<UOut, UIn, C1, C, M, 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<UOut, UIn, DIn, DOut, M, B> Action <B> (Proxy<UOut, UIn, DIn, DOut, M, B> r) Source #

Applicative action

Invokes this Proxy, then the Proxy r

Parameters

param r

Proxy to run after this one

method Proxy<UOutA, AUInA, DIn, DOut, M, A> PairEachRequestWithRespond <UOutA, AUInA> ( Func<UOut, Proxy<UOutA, AUInA, UOut, UIn, M, 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<UOutA, AUInA, DIn, DOut, M, A> ReplaceRequest <UOutA, AUInA> ( Func<UOut, Proxy<UOutA, AUInA, DIn, DOut, M, 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<UOut, UIn, DInC, DOutC, M, A> PairEachRespondWithRequest <DInC, DOutC> ( Func<DOut, Proxy<DIn, DOut, DInC, DOutC, M, 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<UOut, UIn, DInC, DOutC, M, A> ReplaceRespond <DInC, DOutC> ( Func<DOut, Proxy< UOut, UIn, DInC, DOutC, M, 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<DOut, DIn, UIn, UOut, M, A> Reflect () Source #

Reverse the arrows of the Proxy to find its dual.

Parameters

returns

The dual of this

method Proxy<UOut, UIn, DIn, DOut, M, 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<UOut, UIn, DIn, DOut, M, C> SelectMany <B, C> ( Func<A, Proxy<UOut, UIn, DIn, DOut, M, 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<UOut, UIn, DIn, DOut, M, 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

method string ToString () Source #

class Proxy <UOut, UIn, DIn, DOut, M> Source #

where M : Monad<M>

Monad transformer trait implementation for Proxy

Methods

method K<Proxy<UOut, UIn, DIn, DOut, M>, A> LiftIO <A> (IO<A> ma) Source #

method K<Proxy<UOut, UIn, DIn, DOut, M>, B> WithRunInIO <A, B> ( Func<Func<K<Proxy<UOut, UIn, DIn, DOut, M>, A>, IO<A>>, IO<B>> inner) Source #

class Proxy Source #

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

Methods

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<A, M, Unit> Queue <M, A> () Source #

where M : Monad<M>

Create a queue

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

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

where F : Foldable<F>

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 Producer<OUT, M, R> tail <OUT, M, R> (Producer<OUT, M, R> ma) Source #

where M : Monad<M>

method Consumer<IN, M, R> tail <IN, M, R> (Consumer<IN, M, R> ma) Source #

where M : Monad<M>

method Pipe<IN, OUT, M, R> tail <IN, OUT, M, R> (Pipe<IN, OUT, M, R> ma) Source #

where M : Monad<M>

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

where M : Monad<M>

Repeat the Producer indefinitely

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

where M : Monad<M>

Repeat the Consumer indefinitely

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

where M : Monad<M>

Repeat the Pipe indefinitely

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

where M : Monad<M>

Lift a monad into the Proxy monad transformer

method Proxy<A1, A, B1, B, M, R> liftIO <A1, A, B1, B, M, R> (IO<R> ma) Source #

where M : Monad<M>

Lift an IO monad into the Proxy monad transformer

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

where M : Monad<M>

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

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

where M : Monad<M>

Forward requests followed by responses

pull = request | respond | pull

pull is the identity of the pull category.

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

where M : Monad<M>

push = respond | request | push

push is the identity of the push category.

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

where M : Monad<M>

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<UOut, UIn, Y1, Y, M, UIn> request <UOut, UIn, Y1, Y, M> (UOut value) Source #

where M : Monad<M>

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<DOut, DIn, UIn, UOut, M, R> reflect <UOut, UIn, DIn, DOut, M, R> ( Proxy<UOut, UIn, DIn, DOut, M, R> p) Source #

where M : Monad<M>

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<OUT_B, M, A> ForEach <OUT_A, OUT_B, M, A> ( this Producer<OUT_A, M, A> p, Func<OUT_A, Producer<OUT_B, M, Unit>> body) Source #

where M : Monad<M>

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

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

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

where M : Monad<M>

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

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

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

where M : Monad<M>

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

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

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

where M : Monad<M>

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<UOut, UIn, DIn, DOut, M, B> compose <UOut, UIn, DIn, DOut, A, M, B> ( Proxy<UOut, UIn, DIn, DOut, M, A> p1, Proxy<Unit, A, DIn, DOut, M, B> p2) Source #

where M : Monad<M>

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

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

where M : Monad<M>

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

Effect b -> Consumer b c -> Effect c

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

where M : Monad<M>

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

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

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

where M : Monad<M>

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

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

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

where M : Monad<M>

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<A1, A, Y1, Y, M, C> compose <A1, A, Y1, Y, B, M, C> ( Proxy<Unit, B, Y1, Y, M, C> p2, Proxy<A1, A, Y1, Y, M, B> p1) Source #

where M : Monad<M>

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

where M : Monad<M>

Replaces each request or respond in p0 with fb1.

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

where M : Monad<M>

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

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

where M : Monad<M>

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

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

where M : Monad<M>

Pipe composition

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

where M : Monad<M>

Pipe composition

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

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

where M : Monad<M>

Pipe composition

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

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

where M : Monad<M>

Pipe composition

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

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

where M : Monad<M>

Pipe composition

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

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

where M : Monad<M>

Compose two unfolds, creating a new unfold

This is the composition operator of the respond category.

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

where M : Monad<M>

Compose two unfolds, creating a new unfold

This is the composition operator of the respond category.

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

where M : Monad<M>

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

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

where M : Monad<M>

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

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

where M : Monad<M>

Compose two folds, creating a new fold

(f | g) x = f | g x

| is the composition operator of the request category.

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

where M : Monad<M>

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<A1, A, B1, B, M, S> apply <A1, A, B1, B, R, M, S> ( Proxy<A1, A, B1, B, M, Func<R, S>> pf, Proxy<A1, A, B1, B, M, R> px) Source #

where M : Monad<M>

Applicative apply

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

where M : Monad<M>

Applicative apply

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

where M : Monad<M>

Applicative action

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

where M : Monad<M>

Monad return / pure

method K<M, (A, B)> collect <M, A, B> (Effect<M, A> ma, Effect<M, B> mb) Source #

where M : Monad<M>

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

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

where M : Monad<M>

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

method Producer<(A, B), M, Unit> yield <M, A, B> (Effect<M, A> ma, Effect<M, B> mb) Source #

where M : Monad<M>

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

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

where M : Monad<M>

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

record Pure <UOut, UIn, DIn, DOut, M, A> (A Value) Source #

where M : Monad<M>

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 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<UOut, UIn, DIn, DOut, M, 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<UOut, UIn, DIn, DOut, M, B> Bind <B> (Func<A, Proxy<UOut, UIn, DIn, DOut, M, 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<UOut, UIn, DIn, DOut, M, 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<UOut, UIn, DIn, DOut, M, B> MapM <B> (Func<K<M, A>, K<M, B>> f) Source #

Map the lifted monad

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<UOut, UIn, C1, C, M, A> For <C1, C> (Func<DOut, Proxy<UOut, UIn, C1, C, M, 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<UOut, UIn, DIn, DOut, M, B> Action <B> (Proxy<UOut, UIn, DIn, DOut, M, B> r) Source #

Applicative action

Invokes this Proxy, then the Proxy r

Parameters

param r

Proxy to run after this one

method Proxy<UOutA, AUInA, DIn, DOut, M, A> PairEachRequestWithRespond <UOutA, AUInA> ( Func<UOut, Proxy<UOutA, AUInA, UOut, UIn, M, 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<UOutA, AUInA, DIn, DOut, M, A> ReplaceRequest <UOutA, AUInA> ( Func<UOut, Proxy<UOutA, AUInA, DIn, DOut, M, 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<UOut, UIn, DInC, DOutC, M, A> PairEachRespondWithRequest <DInC, DOutC> ( Func<DOut, Proxy<DIn, DOut, DInC, DOutC, M, 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<UOut, UIn, DInC, DOutC, M, A> ReplaceRespond <DInC, DOutC> ( Func<DOut, Proxy<UOut, UIn, DInC, DOutC, M, 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<DOut, DIn, UIn, UOut, M, A> Reflect () Source #

Reverse the arrows of the Proxy to find its dual.

Parameters

returns

The dual of `this1

method Proxy<UOut, UIn, DIn, DOut, M, 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 #

method string ToString () Source #

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.

Methods

method string ToString () Source #