Skip to content

AsyncArrow? #10

@eulerfx

Description

@eulerfx

The types:

type AsyncArrow<'a, 'b> = 'a -> Async<'b>

type AsyncFilter<'a, 'b, 'c, 'd> = AsyncArrow<'a, 'b> -> AsyncArrow<'c, 'd>

type AsyncFilter<'a, 'b> = AsyncArrow<'a, 'b> -> AsyncArrow<'a, 'b>

The async arrow type can have many interpretations and is particularly well suited at representing an async request-reply protocol. Data driven services are usually a composition of various request-reply interactions and it can be useful to reify the type.

The supported operations would be all those of arrows as seen here but also many others specific to Async and other types. Consider operations such as:

/// Invokes arrow g and then invokes f if successful (Choice1Of2).
val tryBefore (g:AsyncArrow<'a, Choice<'a, 'c>>) (f:AsyncArrow<'a, 'b>) : AsyncArrow<'a, Choice<'b, 'c>>

/// Creates an arrow which propagates its input into the output.
val strength (f:AsyncArrow<'a, 'b>) : AsyncArrow<'a, 'a * 'b>

/// Creates an arrow which filters inputs to the specified arrow.
val filterAsync (p:AsyncArrow<'a, bool>) (df:Async<'b>) (f:AsyncArrow<'a, 'b>) : AsyncArrow<'a, 'b>

Async filters represent mappings between arrows. A filter can be use to inject various cross-cutting concerns. For example, a timing filter:

  let timing (log:NLog.Logger) : AsyncFilter<_,_,_,_> =
    fun (f:AsyncArrow<'a, 'b>) a -> async { 
      let sw = System.Diagnostics.Stopwatch.StartNew()
      let! res = f a
      sw.Stop()
      log.Trace("Time Elapsed={0}", sw.ElapsedMilliseconds)
      return res 
    }

A filter can also change the input/output type of an arrow. This can be used for layering a JSON codec onto a request/reply protocol, for instance.

type AsyncSink<'a> = AsyncArrow<'a, unit>

A sink can be used to represent functions which are run solely for the side-effects. An example operation:

  let mergeAllPar (ss:seq<AsyncSink<'a>>) : AsyncSink<'a> =
    fun a -> ss |> Seq.map ((|>) a) |> Async.Parallel |> Async.Ignore

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions