FSharp.Control.TaskSeq 0.2.0

There is a newer version of this package available.
See the version list below for details.
dotnet add package FSharp.Control.TaskSeq --version 0.2.0
NuGet\Install-Package FSharp.Control.TaskSeq -Version 0.2.0
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="FSharp.Control.TaskSeq" Version="0.2.0" />
For projects that support PackageReference, copy this XML node into the project file to reference the package.
paket add FSharp.Control.TaskSeq --version 0.2.0
#r "nuget: FSharp.Control.TaskSeq, 0.2.0"
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
// Install FSharp.Control.TaskSeq as a Cake Addin
#addin nuget:?package=FSharp.Control.TaskSeq&version=0.2.0

// Install FSharp.Control.TaskSeq as a Cake Tool
#tool nuget:?package=FSharp.Control.TaskSeq&version=0.2.0


An implementation of IAsyncEnumerable<'T> as a taskSeq CE for F# with accompanying TaskSeq module.

The IAsyncEnumerable interface was added to .NET in .NET Core 3.0 and is part of .NET Standard 2.1. The main use-case was for iterative asynchronous enumeration over some resource. For instance, an event stream or a REST API interface with pagination, where each page is a MoveNextAsync call on the IAsyncEnumerator<'T> given by a call to GetAsyncEnumerator(). It has been relatively challenging to work properly with this type and dealing with each step being asynchronous, and the enumerator implementing IAsyncDisposable as well, which requires careful handling.

Table of contents

Implementation progress

As of 6 November 2022:

taskSeq CE

The resumable state machine backing the taskSeq CE is now finished and restartability (not to be confused with resumability) has been implemented and stabilized. Full support for empty task sequences is done. Focus is now on adding functionality there, like adding more useful overloads for yield and let!. Suggestions are welcome!

TaskSeq module functions

We are working hard on getting a full set of module functions on TaskSeq that can be used with IAsyncEnumerable sequences. Our guide is the set of F# Seq functions in F# Core and, where applicable, the functions provided from AsyncSeq. Each implemented function is documented through XML doc comments to provide the necessary context-sensitive help.

The following is the progress report:

Done Seq TaskSeq Variants Remarks
allPairs allPairs note #1
#81 append append
#81 appendSeq
#81 prependSeq
average average
averageBy averageBy averageByAsync
cache cache note #1
#67 cast cast
#67 box
#67 unbox
#23 choose choose chooseAsync
chunkBySize chunkBySize
#11 collect collect collectAsync
#11 collectSeq collectSeqAsync
compareWith compareWith compareWithAsync
#69 concat concat
#70 contains contains
#82 delay delay
distinct distinct
distinctBy dictinctBy distinctByAsync
#2 empty empty
#23 exactlyOne exactlyOne
except except
#70 exists exists existsAsync
exists2 exists2
#23 filter filter filterAsync
#23 find find findAsync
🚫 findBack note #2
#68 findIndex findIndex findIndexAsync
🚫 findIndexBack n/a n/a note #2
#2 fold fold foldAsync
fold2 fold2 fold2Async
🚫 foldBack note #2
🚫 foldBack2 note #2
forall forall forallAsync
forall2 forall2 forall2Async
groupBy groupBy groupByAsync note #1
#23 head head
#68 indexed indexed
#69 init init initAsync
#69 initInfinite initInfinite initInfiniteAsync
insertAt insertAt
insertManyAt insertManyAt
#23 isEmpty isEmpty
#23 item item
#2 iter iter iterAsync
iter2 iter2 iter2Async
#2 iteri iteri iteriAsync
iteri2 iteri2 iteri2Async
#23 last last
#53 length length
#53 lengthBy lengthByAsync
#2 map map mapAsync
map2 map2 map2Async
map3 map3 map3Async
mapFold mapFold mapFoldAsync
🚫 mapFoldBack note #2
#2 mapi mapi mapiAsync
mapi2 mapi2 mapi2Async
max max
maxBy maxBy maxByAsync
min min
minBy minBy minByAsync
#2 ofArray ofArray
#2 ofAsyncArray
#2 ofAsyncList
#2 ofAsyncSeq
#2 ofList ofList
#2 ofTaskList
#2 ofResizeArray
#2 ofSeq
#2 ofTaskArray
#2 ofTaskList
#2 ofTaskSeq
pairwise pairwise
permute permute permuteAsync
#23 pick pick pickAsync
🚫 readOnly note #3
reduce reduce reduceAsync
🚫 reduceBack note #2
removeAt removeAt
removeManyAt removeManyAt
replicate replicate
rev note #1
scan scan scanAsync
🚫 scanBack note #2
singleton singleton
skip skip
skipWhile skipWhile skipWhileAsync
sort note #1
sortBy note #1
sortByAscending note #1
sortByDescending note #1
sortWith note #1
splitInto splitInto
sum sum
sumBy sumBy sumByAsync
#76 tail tail
take take
takeWhile takeWhile takeWhileAsync
#2 toArray toArray toArrayAsync
#2 toIList toIListAsync
#2 toList toList toListAsync
#2 toResizeArray toResizeArrayAsync
#2 toSeq toSeqAsync
transpose note #1
truncate truncate
#23 tryExactlyOne tryExactlyOne tryExactlyOneAsync
#23 tryFind tryFind tryFindAsync
🚫 tryFindBack note #2
#68 tryFindIndex tryFindIndex tryFindIndexAsync
🚫 tryFindIndexBack note #2
#23 tryHead tryHead
#23 tryItem tryItem
#23 tryLast tryLast
#23 tryPick tryPick tryPickAsync
#76 tryTail
unfold unfold unfoldAsync
updateAt updateAt
where where whereAsync
windowed windowed
#2 zip zip
zip3 zip3

<sup>¹⁾ <a id="note1"></a>These functions require a form of pre-materializing through TaskSeq.cache, similar to the approach taken in the corresponding Seq functions. It doesn't make much sense to have a cached async sequence. However, AsyncSeq does implement these, so we'll probably do so eventually as well.</sup>
<sup>²⁾ <a id="note2"></a>Because of the async nature of TaskSeq sequences, iterating from the back would be bad practice. Instead, materialize the sequence to a list or array and then apply the xxxBack iterators.</sup>
<sup>³⁾ <a id="note3"></a>The motivation for readOnly in Seq is that a cast from a mutable array or list to a seq<_> is valid and can be cast back, leading to a mutable sequence. Since TaskSeq doesn't implement IEnumerable<_>, such casts are not possible.</sup>

More information

Futher reading IAsyncEnumerable

  • A good C#-based introduction can be found in this blog.
  • An MSDN article written shortly after it was introduced.
  • Converting a seq to an IAsyncEnumerable demo gist as an example, though TaskSeq contains many more utility functions and uses a slightly different approach.
  • If you're looking for using IAsyncEnumerable with async and not task, the excellent AsyncSeq library should be used. While TaskSeq is intended to consume async just like task does, it won't create an AsyncSeq type (at least not yet). If you want classic Async and parallelism, you should get this library instead.

Futher reading on resumable state machines

Further reading on computation expressions

Product Compatible and additional computed target framework versions.
.NET net5.0 was computed.  net5.0-windows was computed.  net6.0 was computed.  net6.0-android was computed.  net6.0-ios was computed.  net6.0-maccatalyst was computed.  net6.0-macos was computed.  net6.0-tvos was computed.  net6.0-windows was computed.  net7.0 was computed.  net7.0-android was computed.  net7.0-ios was computed.  net7.0-maccatalyst was computed.  net7.0-macos was computed.  net7.0-tvos was computed.  net7.0-windows was computed.  net8.0 was computed.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed. 
.NET Core netcoreapp3.0 was computed.  netcoreapp3.1 was computed. 
.NET Standard netstandard2.1 is compatible. 
MonoAndroid monoandroid was computed. 
MonoMac monomac was computed. 
MonoTouch monotouch was computed. 
Tizen tizen60 was computed. 
Xamarin.iOS xamarinios was computed. 
Xamarin.Mac xamarinmac was computed. 
Xamarin.TVOS xamarintvos was computed. 
Xamarin.WatchOS xamarinwatchos was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages (8)

Showing the top 5 NuGet packages that depend on FSharp.Control.TaskSeq:

Package Downloads

Efficient event sourced decisions and data


Efficient event sourced decisions and data


Efficient event streaming pipelines


Efficient event sourced decisions and data


Efficient event sourced decisions and data

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last updated
0.4.0 11,554 3/17/2024
0.4.0-alpha.1 38,017 6/5/2023
0.3.0 103,174 11/28/2022
0.2.2 1,543 11/10/2022
0.2.1 657 11/10/2022
0.2.0 340 11/9/2022
0.1.1 328 11/9/2022
0.1.0 405 11/9/2022

      - moved from NET 6.0, to NetStandard 2.1 for greater compatibility, no functional changes
      - move to minimally necessary FSharp.Core version: 6.0.2
      - updated readme with progress overview, corrected meta info, added release notes
      - updated meta info in nuget package and added readme
      - initial release