FSharpPlus


SeqT<Monad<bool>, 'T>

This is the the Monad Transformer for seq<'T> so it adds sequencing to existing monads by composing then with seq<'T>.

Any monad can be composed, but a very typical usage is when combined with Async or Task, which gives rise to what's called async sequences.

Therefore the AsyncSeq library can be considered a specialization of this monad in Async.

The original post from AsyncSeq can be found here and we can run those examples with SeqT by adapting the code.

In order to do so we need to be aware of the design differences of both implementations.

AsyncSeq

SeqT

Notes

AsyncSeq<'T>

SeqT<Async<bool>, 'T>

asyncSeq { .. }

monad.plus { .. }

At some point it needs to be inferred as SeqT<Async<bool>, 'T>, or it can be specified with type parameters: monad<SeqT<Async<bool>, 'T>>.plus

let! x = y

let! x = SeqT.lift y

No auto lifting. Lifting should be explicit.

do! x

do! SeqT.lift x

''

for x in s

let! x = s

When s: AsyncSeq<'T> otherwise for is still ok with regular sequences.

AsyncSeq.[function]

SeqT.[function]

See differences in functions below.

AsyncSeq.[function]Async

SeqT.[function]M

''

AsyncSeq.skip

SeqT.drop

.skip is available but consistently with F# collections, it throws when the sequence doesn't have enough elements.

AsyncSeq.take

SeqT.truncate

.take is available but consistently with F# collections, it throws when the sequence doesn't have enough elements.

AsyncSeq.toBlockingSequence

SeqT.run >> Async.RunSynchronously

Not really the same but semantically equivalent.

AsyncSeq.toListAsync

SeqT.runAsList

AsyncSeq.toArrayAsync

SeqT.runAsArray

AsyncSeq.zipWith

SeqT.map2

Aligned with F# collections.

AsyncSeq.zipWithAsync

SeqT.map2M

''

AsyncSeq.ofObservable

Observable.toAsyncSeq

.toTaskSeq is also available.

AsyncSeq.toObservable

Observable.ofAsyncSeq

.ofTaskSeq is also available.

Examples

#r "nuget: FSharpPlus"

open System
open System.Net
open FSharpPlus
open FSharpPlus.Data

let urls =
  [ "http://bing.com"; "http://yahoo.com";
    "http://google.com"; "http://msn.com"; ]

// Asynchronous sequence that returns URLs and lengths
// of the downloaded HTML. Web pages from a given list
// are downloaded asynchronously in sequence.
let pages: SeqT<_, _> = monad.plus {
    use wc = new WebClient ()
    for url in urls do
        try
            let! html = wc.AsyncDownloadString (Uri url) |> SeqT.lift
            yield url, html.Length
        with _ ->
            yield url, -1 }


// Print URL of pages that are smaller than 100k
let printPages =
    pages
    |> SeqT.filter (fun (_, len) -> len < 100000)
    |> SeqT.map fst
    |> SeqT.iter (printfn "%s")
 
printPages |> Async.Start

To make it work with tasks simply add |> Async.StartAsTask between wc.AsyncDownloadString (Uri url) and |> SeqT.lift then run eveything but the printPages |> Async.Start.

namespace System
namespace System.Net
type WebClient = inherit Component new: unit -> unit member CancelAsync: unit -> unit member DownloadData: address: string -> byte[] + 1 overload member DownloadDataAsync: address: Uri -> unit + 1 overload member DownloadDataTaskAsync: address: string -> Task<byte[]> + 1 overload member DownloadFile: address: string * fileName: string -> unit + 1 overload member DownloadFileAsync: address: Uri * fileName: string -> unit + 1 overload member DownloadFileTaskAsync: address: string * fileName: string -> Task + 1 overload member DownloadString: address: string -> string + 1 overload ...
<summary>Provides common methods for sending data to and receiving data from a resource identified by a URI.</summary>
val wc: System.Net.WebClient
val uri: System.Uri
Multiple items
type Uri = interface ISerializable new: uriString: string -> unit + 6 overloads member Equals: comparand: obj -> bool member GetComponents: components: UriComponents * format: UriFormat -> string member GetHashCode: unit -> int member GetLeftPart: part: UriPartial -> string member IsBaseOf: uri: Uri -> bool member IsWellFormedOriginalString: unit -> bool member MakeRelative: toUri: Uri -> string member MakeRelativeUri: uri: Uri -> Uri ...
<summary>Provides an object representation of a uniform resource identifier (URI) and easy access to the parts of the URI.</summary>

--------------------
System.Uri(uriString: string) : System.Uri
System.Uri(uriString: string, creationOptions: inref<System.UriCreationOptions>) : System.Uri
System.Uri(uriString: string, uriKind: System.UriKind) : System.Uri
System.Uri(baseUri: System.Uri, relativeUri: string) : System.Uri
System.Uri(baseUri: System.Uri, relativeUri: System.Uri) : System.Uri
val async: AsyncBuilder
<summary>Builds an asynchronous workflow using computation expression syntax.</summary>
<example id="async-1"><code lang="fsharp"> let sleepExample() = async { printfn "sleeping" do! Async.Sleep 10 printfn "waking up" return 6 } sleepExample() |&gt; Async.RunSynchronously </code></example>
System.Net.WebClient.DownloadString(address: System.Uri) : string
System.Net.WebClient.DownloadString(address: string) : string
namespace FSharpPlus
namespace FSharpPlus.Data
val urls: string list
val pages: SeqT<Async<bool>,(string * int)>
Multiple items
static member SeqTOperations.SeqT: source: 'Monad<seq<'T>> -> SeqT<'Monad<bool>,'T> (requires member (>>=) and member Return)

--------------------
active recognizer SeqT: SeqT<'Monad<bool>,'T> -> 'Monad<'T seq>

--------------------
module SeqT from FSharpPlus.Data.SeqT_V2

--------------------
[<Struct>] type SeqT<'monad,'t> = | SeqT of IEnumerableM<'monad,'t> interface IEnumerableM<'monad,'t> static member ( *> ) : x: SeqT<'Monad<bool>,'T> * y: SeqT<'Monad<bool>,'U> -> SeqT<'Monad<bool>,'U> (requires member (>>=) and member Return and member Delay) static member (<!>) : x: SeqT<'Monad<bool>,'T> * f: ('T -> 'U) -> SeqT<'Monad<bool>,'U> (requires member Delay and member (>>=) and member Return) static member ( <* ) : x: SeqT<'Monad<bool>,'U> * y: SeqT<'Monad<bool>,'T> -> SeqT<'Monad<bool>,'U> (requires member (>>=) and member Return and member Delay) static member (<*>) : f: SeqT<'Monad<bool>,('T -> 'U)> * x: SeqT<'Monad<bool>,'T> -> SeqT<'Monad<bool>,'U> (requires member (>>=) and member Return) static member (<|>) : x: SeqT<'Monad<bool>,'T> * y: SeqT<'Monad<bool>,'T> -> SeqT<'Monad<bool>,'T> (requires member Delay and member Return and member (>>=)) static member (>>=) : x: SeqT<'Monad<bool>,'T> * f: ('T -> SeqT<'Monad<bool>,'U>) -> SeqT<'Monad<bool>,'U> (requires member (>>=) and member Return) static member CallCC: f: (('T -> SeqT<'MonadCont<'R>,'U>) -> SeqT<'a5,'a7>) -> SeqT<'MonadCont<'R>,'T> (requires member (>>=) and member Return and member (>>=) and member (>>=) and member Using and member (>>=) and member Return and member CallCC and member (>>=) and member (>>=) and member Return) static member Catch: m: SeqT<'MonadError<'E1>,'T> * h: ('E1 -> SeqT<'MonadError<'E2>,'T>) -> SeqT<'MonadError<'E2>,'T> (requires member (>>=) and member (>>=) and member Using and member (>>=) and member Return and member Catch and member (>>=) and member Return and member (>>=) and member Using and member (>>=) and member Return and member (>>=) and member Return and member (>>=) and member (>>=) and member Return) static member Delay: body: (unit -> SeqT<'Monad<bool>,'T>) -> SeqT<'Monad<bool>,'T> ...
val monad<'monad<'t>> : MonadFxBuilder<'monad<'t>>
<summary> Creates a (lazy) monadic computation expression with side-effects (see http://fsprojects.github.io/FSharpPlus/computation-expressions.html for more information) </summary>
val wc: WebClient
val url: string
val html: string
member WebClient.AsyncDownloadString: address: Uri -> Async<string>
member WebClient.AsyncDownloadString: uri: Uri -> Async<string>
<summary>Returns an asynchronous computation that, when run, will wait for the download of the given URI.</summary>
<param name="address">The URI to retrieve.</param>
<returns>An asynchronous computation that will wait for the download of the URI.</returns>
<example id="async-download-string"><code lang="fsharp"> open System let client = new WebClient() Uri("https://www.w3.org") |&gt; client.AsyncDownloadString |&gt; Async.RunSynchronously </code> This will download the server response from https://www.w3.org </example>
Multiple items
type Uri = interface ISerializable new: uriString: string -> unit + 6 overloads member Equals: comparand: obj -> bool member GetComponents: components: UriComponents * format: UriFormat -> string member GetHashCode: unit -> int member GetLeftPart: part: UriPartial -> string member IsBaseOf: uri: Uri -> bool member IsWellFormedOriginalString: unit -> bool member MakeRelative: toUri: Uri -> string member MakeRelativeUri: uri: Uri -> Uri ...
<summary>Provides an object representation of a uniform resource identifier (URI) and easy access to the parts of the URI.</summary>

--------------------
Uri(uriString: string) : Uri
Uri(uriString: string, creationOptions: inref<UriCreationOptions>) : Uri
Uri(uriString: string, uriKind: UriKind) : Uri
Uri(baseUri: Uri, relativeUri: string) : Uri
Uri(baseUri: Uri, relativeUri: Uri) : Uri
Multiple items
val lift: source: 'Monad<'T> -> SeqT<'Monad<bool>,'T> (requires member (>>=) and member Map and member Return)

--------------------
val lift: x: 'Monad<'T> -> SeqT<'Monad<seq<'T>>> (requires member (>>=) and member Map and member Return)
<summary> Embed a Monad&lt;'T&gt; into a SeqT&lt;'Monad&lt;seq&lt;'T&gt;&gt;&gt; </summary>
property String.Length: int with get
val printPages: Async<unit>
val filter: f: ('T -> bool) -> source: SeqT<'Monad<bool>,'T> -> SeqT<'Monad<bool>,'T> (requires member Delay and member (>>=) and member Return)
val len: int
Multiple items
val map: f: ('T -> 'U) -> source: SeqT<'Monad<bool>,'T> -> SeqT<'Monad<bool>,'U> (requires member Delay and member (>>=) and member Return)

--------------------
val map: f: ('T -> 'U) -> SeqT<'Monad<seq<'T>> -> SeqT<'Monad<seq<'U>> (requires member Map)
val fst: tuple: ('T1 * 'T2) -> 'T1
<summary>Return the first element of a tuple, <c>fst (a,b) = a</c>.</summary>
<param name="tuple">The input tuple.</param>
<returns>The first value.</returns>
<example id="fst-example"><code lang="fsharp"> fst ("first", 2) // Evaluates to "first" </code></example>
val iter: f: ('T -> unit) -> source: SeqT<'Monad<bool>,'T> -> 'Monad<unit> (requires member (>>=) and member Delay and member Using and member Return and member (>>=))
val printfn: format: Printf.TextWriterFormat<'T> -> 'T
<summary>Print to <c>stdout</c> using the given format, and add a newline.</summary>
<param name="format">The formatter.</param>
<returns>The formatted result.</returns>
<example>See <c>Printf.printfn</c> (link: <see cref="M:Microsoft.FSharp.Core.PrintfModule.PrintFormatLine``1" />) for examples.</example>
Multiple items
module Async from FSharpPlus
<summary> Additional operations on Async </summary>

--------------------
type Async = static member AsBeginEnd: computation: ('Arg -> Async<'T>) -> ('Arg * AsyncCallback * obj -> IAsyncResult) * (IAsyncResult -> 'T) * (IAsyncResult -> unit) static member AwaitEvent: event: IEvent<'Del,'T> * ?cancelAction: (unit -> unit) -> Async<'T> (requires delegate and 'Del :> Delegate) static member AwaitIAsyncResult: iar: IAsyncResult * ?millisecondsTimeout: int -> Async<bool> static member AwaitTask: task: Task<'T> -> Async<'T> + 1 overload static member AwaitWaitHandle: waitHandle: WaitHandle * ?millisecondsTimeout: int -> Async<bool> static member CancelDefaultToken: unit -> unit static member Catch: computation: Async<'T> -> Async<Choice<'T,exn>> static member Choice: computations: seq<Async<'T option>> -> Async<'T option> static member FromBeginEnd: beginAction: (AsyncCallback * obj -> IAsyncResult) * endAction: (IAsyncResult -> 'T) * ?cancelAction: (unit -> unit) -> Async<'T> + 3 overloads static member FromContinuations: callback: (('T -> unit) * (exn -> unit) * (OperationCanceledException -> unit) -> unit) -> Async<'T> ...
<summary>Holds static members for creating and manipulating asynchronous computations.</summary>
<remarks> See also <a href="https://docs.microsoft.com/en-us/dotnet/fsharp/language-reference/asynchronous-workflows">F# Language Guide - Async Workflows</a>. </remarks>
<category index="1">Async Programming</category>


--------------------
type Async<'T>
<summary> An asynchronous computation, which, when run, will eventually produce a value of type T, or else raises an exception. </summary>
<remarks> This type has no members. Asynchronous computations are normally specified either by using an async expression or the static methods in the <see cref="T:Microsoft.FSharp.Control.FSharpAsync`1" /> type. See also <a href="https://docs.microsoft.com/en-us/dotnet/fsharp/language-reference/asynchronous-workflows">F# Language Guide - Async Workflows</a>. </remarks>
<namespacedoc><summary> Library functionality for asynchronous programming, events and agents. See also <a href="https://docs.microsoft.com/en-us/dotnet/fsharp/language-reference/asynchronous-workflows">Asynchronous Programming</a>, <a href="https://docs.microsoft.com/en-us/dotnet/fsharp/language-reference/members/events">Events</a> and <a href="https://docs.microsoft.com/en-us/dotnet/fsharp/language-reference/lazy-expressions">Lazy Expressions</a> in the F# Language Guide. </summary></namespacedoc>
<category index="1">Async Programming</category>
static member Async.Start: computation: Async<unit> * ?cancellationToken: Threading.CancellationToken -> unit