{"id":28454926,"url":"https://github.com/fsprojects/fsharp.control.taskseq","last_synced_at":"2025-06-28T16:33:03.544Z","repository":{"id":61521340,"uuid":"549866063","full_name":"fsprojects/FSharp.Control.TaskSeq","owner":"fsprojects","description":"A computation expression and module for seamless working with IAsyncEnumerable\u003c'T\u003e as if it is just another sequence","archived":false,"fork":false,"pushed_at":"2025-03-12T14:09:14.000Z","size":727,"stargazers_count":102,"open_issues_count":23,"forks_count":8,"subscribers_count":4,"default_branch":"main","last_synced_at":"2025-06-06T21:14:17.105Z","etag":null,"topics":["computation-expressions","fsharp","iasyncenumerable","library","module","package","task","taskseq","tasksequence"],"latest_commit_sha":null,"homepage":"","language":"F#","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/fsprojects.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2022-10-11T21:30:00.000Z","updated_at":"2025-05-26T09:49:10.000Z","dependencies_parsed_at":"2023-02-10T04:00:59.876Z","dependency_job_id":"98d1dd70-3333-48a0-bc8f-bf6dd0fc431d","html_url":"https://github.com/fsprojects/FSharp.Control.TaskSeq","commit_stats":{"total_commits":339,"total_committers":7,"mean_commits":48.42857142857143,"dds":"0.11504424778761058","last_synced_commit":"4cc8154129bd00654c6855390ca2ed9df25a5845"},"previous_names":[],"tags_count":9,"template":false,"template_full_name":null,"purl":"pkg:github/fsprojects/FSharp.Control.TaskSeq","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fsprojects%2FFSharp.Control.TaskSeq","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fsprojects%2FFSharp.Control.TaskSeq/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fsprojects%2FFSharp.Control.TaskSeq/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fsprojects%2FFSharp.Control.TaskSeq/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/fsprojects","download_url":"https://codeload.github.com/fsprojects/FSharp.Control.TaskSeq/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fsprojects%2FFSharp.Control.TaskSeq/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":262460324,"owners_count":23314715,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["computation-expressions","fsharp","iasyncenumerable","library","module","package","task","taskseq","tasksequence"],"created_at":"2025-06-06T21:14:22.597Z","updated_at":"2025-06-28T16:33:03.537Z","avatar_url":"https://github.com/fsprojects.png","language":"F#","readme":"[![build][buildstatus_img]][buildstatus]\n[![test][teststatus_img]][teststatus]\n[![Nuget](https://buildstats.info/nuget/FSharp.Control.TaskSeq?includePreReleases=true)](https://www.nuget.org/packages/FSharp.Control.TaskSeq/)\n\n# TaskSeq\u003c!-- omit in toc --\u003e\n\nAn implementation of [`IAsyncEnumerable\u003c'T\u003e`][3] as a computation expression: `taskSeq { ... }` with an accompanying `TaskSeq` module and functions, that allow seamless use of asynchronous sequences similar to F#'s native `seq` and `task` CE's.\n\n* Latest stable version: [0.4.0 is on NuGet][nuget].\n\n## Release notes\u003c!-- omit in toc --\u003e\n\nSee [Releases](https://github.com/fsprojects/FSharp.Control.TaskSeq/releases) for the an extensive version history of `TaskSeq`. See [Status overview](#status--planning) below for a progress report.\n\n-----------------------------------------\n\n## Table of contents\u003c!-- omit in toc --\u003e\n\n\u003c!--\n    This index can be auto-generated with VS Code's Markdown All in One extension.\n    The ToC will be updated-on-save, or can be generated on command by using\n    Ctrl-Shift-P: \"Create table of contents\".\n    More info: https://marketplace.visualstudio.com/items?itemName=yzhang.markdown-all-in-one#table-of-contents\n--\u003e\n\n- [Overview](#overview)\n  - [Module functions](#module-functions)\n  - [`taskSeq` computation expressions](#taskseq-computation-expressions)\n  - [Installation](#installation)\n  - [Examples](#examples)\n- [Choosing between `AsyncSeq` and `TaskSeq`](#choosing-between-asyncseq-and-taskseq)\n- [Status \\\u0026 planning](#status--planning)\n  - [Implementation progress](#implementation-progress)\n  - [Progress `taskSeq` CE](#progress-taskseq-ce)\n  - [Progress and implemented `TaskSeq` module functions](#progress-and-implemented-taskseq-module-functions)\n- [More information](#more-information)\n  - [Further reading on `IAsyncEnumerable`](#further-reading-on-iasyncenumerable)\n  - [Further reading on resumable state machines](#further-reading-on-resumable-state-machines)\n  - [Further reading on computation expressions](#further-reading-on-computation-expressions)\n- [Building \\\u0026 testing](#building--testing)\n  - [Prerequisites](#prerequisites)\n  - [Build the solution](#build-the-solution)\n  - [Run the tests](#run-the-tests)\n  - [Run the CI command](#run-the-ci-command)\n  - [Advanced](#advanced)\n  - [Get help](#get-help)\n- [Work in progress](#work-in-progress)\n- [Current set of `TaskSeq` utility functions](#current-set-of-taskseq-utility-functions)\n\n-----------------------------------------\n\n## Overview\n\nThe `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, sequential enumeration over some resource. For instance, an event stream or a REST API interface with pagination, asynchronous reading over a list of files and accumulating the results, where each action can be modeled as a [`MoveNextAsync`][4] call on the [`IAsyncEnumerator\u003c'T\u003e`][3] given by a call to [`GetAsyncEnumerator()`][6].\n\nSince the introduction of `task` in F# the call for a native implementation of _task sequences_ has grown, in particular because proper iteration over an `IAsyncEnumerable` has proven challenging, especially if one wants to avoid mutable variables. This library is an answer to that call and applies the same _resumable state machine_ approach with `taskSeq`.\n\n### Module functions\n\nAs with `seq` and `Seq`, this library comes with a bunch of well-known collection functions, like `TaskSeq.empty`, `isEmpty` or `TaskSeq.map`, `iter`, `collect`, `fold` and `TaskSeq.find`, `pick`, `choose`, `filter`, `takeWhile`. Where applicable, these come with async variants, like `TaskSeq.mapAsync` `iterAsync`, `collectAsync`, `foldAsync` and `TaskSeq.findAsync`, `pickAsync`, `chooseAsync`, `filterAsync`, `takeWhileAsync` which allows the applied function to be asynchronous.\n\n[See below](#current-set-of-taskseq-utility-functions) for a full list of currently implemented functions and their variants.\n\n### `taskSeq` computation expressions\n\nThe `taskSeq` computation expression can be used just like using `seq`.\nAdditionally, it adds support for working with `Task`s through `let!` and\nlooping over both normal and asynchronous sequences (ones that implement\n`IAsyncEnumerable\u003c'T\u003e'`). You can use `yield!` and `yield` and there's support\nfor `use` and `use!`, `try-with` and `try-finally` and `while` loops within\nthe task sequence expression:\n\n### Installation\n\nDotnet Nuget\n\n```cmd\ndotnet add package FSharp.Control.TaskSeq\n```\n\nFor a specific project:\n\n```cmd\ndotnet add myproject.fsproj package FSharp.Control.TaskSeq\n```\n\nF# Interactive (FSI):\n\n```f#\n// latest version\n\u003e #r \"nuget: FSharp.Control.TaskSeq\"\n\n// or with specific version\n\u003e #r \"nuget: FSharp.Control.TaskSeq, 0.4.0\"\n```\n\nPaket:\n\n```cmd\ndotnet paket add FSharp.Control.TaskSeq --project \u003cproject\u003e\n```\n\nPackage Manager:\n\n```cmd\nPM\u003e NuGet\\Install-Package FSharp.Control.TaskSeq\n```\n\nAs package reference in `fsproj` or `csproj` file:\n\n```xml\n\u003c!-- replace version with most recent version --\u003e\n\u003cPackageReference Include=\"FSharp.Control.TaskSeq\" Version=\"0.4.0\" /\u003e\n```\n\n### Examples\n\n```f#\nopen System.IO\nopen FSharp.Control\n\n// singleton is fine\nlet helloTs = taskSeq { yield \"Hello, World!\" }\n\n// cold-started, that is, delay-executed\nlet f() = task {\n    // using toList forces execution of whole sequence\n    let! hello = TaskSeq.toList helloTs  // toList returns a Task\u003c'T list\u003e\n    return List.head hello\n}\n\n// can be mixed with normal sequences\nlet oneToTen = taskSeq { yield! [1..10] }\n\n// can be used with F#'s task and async in a for-loop\nlet f() = task { for x in oneToTen do printfn \"Number %i\" x }\nlet g() = async { for x in oneToTen do printfn \"Number %i\" x }\n\n// returns a delayed sequence of IAsyncEnumerable\u003cstring\u003e\nlet allFilesAsLines() = taskSeq {\n    let files = Directory.EnumerateFiles(@\"c:\\temp\")\n    for file in files do\n        // await\n        let! contents = File.ReadAllLinesAsync file\n        // return all lines\n        yield! contents\n}\n\nlet write file =\n    allFilesAsLines()\n\n    // synchronous map function on asynchronous task sequence\n    |\u003e TaskSeq.map (fun x -\u003e x.Replace(\"a\", \"b\"))\n\n    // asynchronous map\n    |\u003e TaskSeq.mapAsync (fun x -\u003e task { return \"hello: \" + x })\n\n    // asynchronous iter\n    |\u003e TaskSeq.iterAsync (fun data -\u003e File.WriteAllTextAsync(fileName, data))\n\n\n// infinite sequence\nlet feedFromTwitter user pwd = taskSeq {\n    do! loginToTwitterAsync(user, pwd)\n    while true do\n       let! message = getNextNextTwitterMessageAsync()\n       yield message\n}\n```\n\n## Choosing between `AsyncSeq` and `TaskSeq`\n\nThe [`AsyncSeq`][11] and `TaskSeq` libraries both operate on asynchronous sequences, but there are a few fundamental differences. The most notable being that the former _does not_ implement `IAsyncEnumerable\u003c'T\u003e`, though it does have a type of that name with different semantics (not surprising; it predates the definition of the modern one). Another key difference is that `TaskSeq` uses `ValueTask`s for the asynchronous computations, whereas `AsyncSeq` uses F#'s `Async\u003c'T\u003e`.\n\nThere are more differences:\n\n|                            | `TaskSeq`                                                                       | `AsyncSeq`                                                           |\n|----------------------------|---------------------------------------------------------------------------------|----------------------------------------------------------------------|\n| **Frameworks**             | .NET 5.0+, NetStandard 2.1                                                      | .NET 5.0+, NetStandard 2.0 and 2.1, .NET Framework 4.6.1+            |\n| **F# concept of**          | `task`                                                                          | `async`                                                              |\n| **Underlying type**        | [`Generic.IAsyncEnumerable\u003c'T\u003e`][3] \u003csup\u003e[note #1](#tsnote1 \"Full name System.Collections.Generic.IAsyncEnumerable\u0026lt;'T\u003e.\")\u003c/sup\u003e| Its own type, also called `IAsyncEnumerable\u003c'T\u003e`\u003csup\u003e[note #1](#tsnote1 \"Full name FSharp.Control.IAsyncEnumerable\u0026lt;'T\u003e.\")\u003c/sup\u003e |\n| **Implementation**         | State machine (statically compiled)                                             | No state machine, continuation style                                 |\n| **Semantics**              | `seq`-like: on-demand                                                           | `seq`-like: on-demand                                                |\n| **Disposability**          | Asynchronous, through [`IAsyncDisposable`][7]                                   | Synchronous, through `IDisposable`                                   |\n| **Support `let!`**         | All `task`-like: `Async\u003c'T\u003e`, `Task\u003c'T\u003e`, `ValueTask\u003c'T\u003e` or any `GetAwaiter()` | `Async\u003c'T\u003e` only                                                     |\n| **Support `do!`**          | `Async\u003cunit\u003e`, `Task\u003cunit\u003e` and `Task`, `ValueTask\u003cunit\u003e` and `ValueTask`       | `Async\u003cunit\u003e` only                                                   |\n| **Support `yield!`**       | [`IAsyncEnumerable\u003c'T\u003e`][3] (= `TaskSeq`), `AsyncSeq`, any sequence             | `AsyncSeq`                                                           |\n| **Support `for`**          | [`IAsyncEnumerable\u003c'T\u003e`][3] (= `TaskSeq`), `AsyncSeq`, any sequence             | `AsyncSeq`, any sequence                                             |\n| **Behavior with `yield`**  | Zero allocations; no `Task` or even `ValueTask` created                         | Allocates an F# `Async` wrapped in a singleton `AsyncSeq`            |\n| **Conversion to other**    | `TaskSeq.toAsyncSeq`                                                            | [`AsyncSeq.toAsyncEnum`][22]                                         |\n| **Conversion from other**  | Implicit (`yield!`) or `TaskSeq.ofAsyncSeq`                                     | [`AsyncSeq.ofAsyncEnum`][23]                                         |\n| **Recursion in `yield!`**  | **No** (requires F# support, upcoming)                                          | Yes                                                                  |\n| **Iteration semantics**    | [Two operations][6], 'Next' is a value task, 'Current' must be called separately| One operation, 'Next' is `Async`, returns `option` with 'Current'    |\n| **`MoveNextAsync`**        | [Returns `ValueTask\u003cbool\u003e`][4]                                                  | Returns `Async\u003c'T option\u003e`                                           |\n| **[`Current`][5]**         | [Returns `'T`][5]                                                               | n/a                                                                  |\n| **Cancellation**           | See [#133][], until 0.3.0: use `GetAsyncEnumerator(cancelToken)`                | Implicit token flows to all subtasks per `async` semantics           |\n| **Performance**            | Very high, negligible allocations                                               | Slower, more allocations, due to using `async` and cont style        |\n| **Parallelism**            | Unclear, interface is meant for _sequential/async_ processing                   | Supported by extension functions                                     |\n\n\u003csup\u003e¹⁾ \u003ca id=\"tsnote1\"\u003e\u003c/a\u003e_Both `AsyncSeq` and `TaskSeq` use a type called `IAsyncEnumerable\u003c'T\u003e`, but only `TaskSeq` uses the type from the BCL Generic Collections. `AsyncSeq` supports .NET Framework 4.6.x and NetStandard 2.0 as well, which do not have this type in the BCL._\u003c/sup\u003e\n\n## Status \u0026 planning\n\nThe `TaskSeq` project already has a wide array of functions and functionalities, see overview below. The current status is: *STABLE*. However, certain features we'd really like to add:\n\n- [x] Take existing `taskSeq` resumable code from F# and fix it. **DONE**\n- [x] Add almost all functions from `Seq` that could apply to `TaskSeq` (full overview below). **MOSTLY DONE, STILL TODO**\n- [ ] Add remaining relevant functions from `Seq`. **PLANNED FOR 0.4.x**\n  - [x] `min` / `max` / `minBy` / `maxBy` \u0026 async variant (see [#221])\n  - [x] `insertAt` / `updateAt` and related (see [#236])\n  - [ ] `average` / `averageBy`, `sum` and related\n  - [x] `forall` / `forallAsync` (see [#240])\n  - [x] `skip` / `drop` / `truncate` / `take` (see [#209])\n  - [ ] `chunkBySize` / `windowed`\n  - [ ] `compareWith`\n  - [ ] `distinct`\n  - [ ] `exists2` / `map2` / `fold2` / `iter2` and related '2'-functions\n  - [ ] `mapFold`\n  - [ ] `pairwise` / `allpairs` / `permute` / `distinct` / `distinctBy`\n  - [ ] `replicate`\n  - [ ] `reduce` / `scan`\n  - [ ] `unfold`\n- [x] Publish package on Nuget, **DONE, PUBLISHED SINCE: 7 November 2022**. See https://www.nuget.org/packages/FSharp.Control.TaskSeq\n- [x] Make `TaskSeq` interoperable with `Task` by expanding the latter with a `for .. in .. do` that acceps task sequences\n- [x] Add to/from functions to seq, list, array\n- [ ] Add applicable functions from `AsyncSeq`. **PLANNED FOR 0.5-alpha**\n- [ ] (Better) support for cancellations\n  - [ ] Make the tasks cancellable with token (see [#133]). **PLANNED FOR 0.5-alpha**\n  - [ ] Support `ConfiguredCancelableAsyncEnumerable` (see [#167]). **PLANNED FOR 0.5-alpha**\n  - [ ] Interop with `cancellableTask` and `valueTask` from [`IcedTasks`][24]\n- [ ] Interop with `AsyncSeq`.\n- [ ] (maybe) Support any awaitable type in the function lib (that is: where a `Task` is required, accept a `ValueTask` and `Async` as well)\n- [ ] Add `TaskEx` functionality (separate lib). **DISCUSSION**\n- [ ] Move documentation to \u003chttps://fsprojects.github.io\u003e\n\n### Implementation progress\n\n * As of 9 November 2022: [Nuget package available][21]. In this phase, we will frequently update the package, see [release notes.txt](release-notes.txt). Current version:\n * Major update: 17 March 2024, version 0.4.0\n\n[![Nuget](https://img.shields.io/nuget/vpre/FSharp.Control.TaskSeq)](https://www.nuget.org/packages/FSharp.Control.TaskSeq/)\n\n### Progress `taskSeq` CE\n\nThe _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!][issues].\n\n### Progress and implemented `TaskSeq` module functions\n\nWe 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 by `AsyncSeq`. Each implemented function is documented through XML doc comments to provide the necessary context-sensitive help.\n\nThis is what has been implemented so far, is planned or skipped:\n\n| Done             | `Seq`              | `TaskSeq`            | Variants                  | Remarks                                                                                                                                                                                                                                                                                                                |\n|------------------|--------------------|----------------------|---------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|\n| \u0026#x2753;         | `allPairs`         | `allPairs`           |                           | [note #1](#note1 \"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.\") |\n| \u0026#x2705; [#81][] | `append`           | `append`             |                           | |\n| \u0026#x2705; [#81][] |                    |                      | `appendSeq`               | |\n| \u0026#x2705; [#81][] |                    |                      | `prependSeq`              | |\n|                  | `average`          | `average`            |                           | |\n|                  | `averageBy`        | `averageBy`          | `averageByAsync`          | |\n| \u0026#x2753;         | `cache`            | `cache`              |                           | [note #1](#note1 \"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.\") |\n| \u0026#x2705; [#67][] | `cast`             | `cast`               |                           | |\n| \u0026#x2705; [#67][] |                    |                      | `box`                     | |\n| \u0026#x2705; [#67][] |                    |                      | `unbox`                   | |\n| \u0026#x2705; [#23][] | `choose`           | `choose`             | `chooseAsync`             | |\n|                  | `chunkBySize`      | `chunkBySize`        |                           | |\n| \u0026#x2705; [#11][] | `collect`          | `collect`            | `collectAsync`            | |\n| \u0026#x2705; [#11][] |                    | `collectSeq`         | `collectSeqAsync`         | |\n|                  | `compareWith`      | `compareWith`        | `compareWithAsync`        | |\n| \u0026#x2705; [#69][] | `concat`           | `concat`             |                           | |\n| \u0026#x2705; [#237][]| `concat` (list)    | `concat` (list)      |                           | |\n| \u0026#x2705; [#237][]| `concat` (array)   | `concat` (array)     |                           | |\n| \u0026#x2705; [#237][]| `concat` (r-array) | `concat` (r-array)   |                           | |\n| \u0026#x2705; [#237][]| `concat` (seq)     | `concat` (seq)       |                           | |\n| \u0026#x2705; [#70][] | `contains`         | `contains`           |                           | |\n| \u0026#x2705; [#82][] | `delay`            | `delay`              |                           | |\n|                  | `distinct`         | `distinct`           |                           | |\n|                  | `distinctBy`       | `dictinctBy`         | `distinctByAsync`         | |\n| \u0026#x2705; [#209][]|                    | `drop`               |                           | |\n| \u0026#x2705; [#2][]  | `empty`            | `empty`              |                           | |\n| \u0026#x2705; [#23][] | `exactlyOne`       | `exactlyOne`         |                           | |\n| \u0026#x2705; [#83][] | `except`           | `except`             |                           | |\n| \u0026#x2705; [#83][] |                    | `exceptOfSeq`        |                           | |\n| \u0026#x2705; [#70][] | `exists`           | `exists`             | `existsAsync`             | |\n|                  | `exists2`          | `exists2`            |                           | |\n| \u0026#x2705; [#23][] | `filter`           | `filter`             | `filterAsync`             | |\n| \u0026#x2705; [#23][] | `find`             | `find`               | `findAsync`               | |\n| \u0026#x1f6ab;        | `findBack`         |                      |                           | [note #2](#note2 \"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 'Back' iterators.\") |\n| \u0026#x2705; [#68][] | `findIndex`        | `findIndex`          | `findIndexAsync`          | |\n| \u0026#x1f6ab;        | `findIndexBack`    | n/a                  | n/a                       | [note #2](#note2 \"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 'Back' iterators.\") |\n| \u0026#x2705; [#2][]  | `fold`             | `fold`               | `foldAsync`               | |\n|                  | `fold2`            | `fold2`              | `fold2Async`              | |\n| \u0026#x1f6ab;        | `foldBack`         |                      |                           | [note #2](#note2 \"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 'Back' iterators.\") |\n| \u0026#x1f6ab;        | `foldBack2`        |                      |                           | [note #2](#note2 \"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 'Back' iterators.\") |\n| \u0026#x2705; [#240][]| `forall`           | `forall`             | `forallAsync`             | |\n|                  | `forall2`          | `forall2`            | `forall2Async`            | |\n| \u0026#x2753;         | `groupBy`          | `groupBy`            | `groupByAsync`            | [note #1](#note1 \"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.\") |\n| \u0026#x2705; [#23][] | `head`             | `head`               |                           | |\n| \u0026#x2705; [#68][] | `indexed`          | `indexed`            |                           | |\n| \u0026#x2705; [#69][] | `init`             | `init`               | `initAsync`               | |\n| \u0026#x2705; [#69][] | `initInfinite`     | `initInfinite`       | `initInfiniteAsync`       | |\n| \u0026#x2705; [#236][]| `insertAt`         | `insertAt`           |                           | |\n| \u0026#x2705; [#236][]| `insertManyAt`     | `insertManyAt`       |                           | |\n| \u0026#x2705; [#23][] | `isEmpty`          | `isEmpty`            |                           | |\n| \u0026#x2705; [#23][] | `item`             | `item`               |                           | |\n| \u0026#x2705; [#2][]  | `iter`             | `iter`               | `iterAsync`               | |\n|                  | `iter2`            | `iter2`              | `iter2Async`              | |\n| \u0026#x2705; [#2][]  | `iteri`            | `iteri`              | `iteriAsync`              | |\n|                  | `iteri2`           | `iteri2`             | `iteri2Async`             | |\n| \u0026#x2705; [#23][] | `last`             | `last`               |                           | |\n| \u0026#x2705; [#53][] | `length`           | `length`             |                           | |\n| \u0026#x2705; [#53][] |                    | `lengthBy`           | `lengthByAsync`           | |\n| \u0026#x2705; [#2][]  | `map`              | `map`                | `mapAsync`                | |\n|                  | `map2`             | `map2`               | `map2Async`               | |\n|                  | `map3`             | `map3`               | `map3Async`               | |\n|                  | `mapFold`          | `mapFold`            | `mapFoldAsync`            | |\n| \u0026#x1f6ab;        | `mapFoldBack`      |                      |                           | [note #2](#note2 \"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 'Back' iterators.\") |\n| \u0026#x2705; [#2][]  | `mapi`             | `mapi`               | `mapiAsync`               | |\n|                  | `mapi2`            | `mapi2`              | `mapi2Async`              | |\n| \u0026#x2705; [#221][]| `max`              | `max`                |                           | |\n| \u0026#x2705; [#221][]| `maxBy`            | `maxBy`              | `maxByAsync`              | |\n| \u0026#x2705; [#221][]| `min`              | `min`                |                           | |\n| \u0026#x2705; [#221][]| `minBy`            | `minBy`              | `minByAsync`              | |\n| \u0026#x2705; [#2][]  | `ofArray`          | `ofArray`            |                           | |\n| \u0026#x2705; [#2][]  |                    | `ofAsyncArray`       |                           | |\n| \u0026#x2705; [#2][]  |                    | `ofAsyncList`        |                           | |\n| \u0026#x2705; [#2][]  |                    | `ofAsyncSeq`         |                           | |\n| \u0026#x2705; [#2][]  | `ofList`           | `ofList`             |                           | |\n| \u0026#x2705; [#2][]  |                    | `ofTaskList`         |                           | |\n| \u0026#x2705; [#2][]  |                    | `ofResizeArray`      |                           | |\n| \u0026#x2705; [#2][]  |                    | `ofSeq`              |                           | |\n| \u0026#x2705; [#2][]  |                    | `ofTaskArray`        |                           | |\n| \u0026#x2705; [#2][]  |                    | `ofTaskList`         |                           | |\n| \u0026#x2705; [#2][]  |                    | `ofTaskSeq`          |                           | |\n|                  | `pairwise`         | `pairwise`           |                           | |\n|                  | `permute`          | `permute`            | `permuteAsync`            | |\n| \u0026#x2705; [#23][] | `pick`             | `pick`               | `pickAsync`               | |\n| \u0026#x1f6ab;        | `readOnly`         |                      |                           | [note #3](#note3 \"The motivation for 'readOnly' in 'Seq' is that a cast from a mutable array or list to a 'seq\u003c_\u003e' is valid and can be cast back, leading to a mutable sequence. Since 'TaskSeq' doesn't implement 'IEnumerable\u003c_\u003e', such casts are not possible.\") |\n|                  | `reduce`           | `reduce`             | `reduceAsync`             | |\n| \u0026#x1f6ab;        | `reduceBack`       |                      |                           | [note #2](#note2 \"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 'Back' iterators.\") |\n| \u0026#x2705; [#236][]| `removeAt`         | `removeAt`           |                           | |\n| \u0026#x2705; [#236][]| `removeManyAt`     | `removeManyAt`       |                           | |\n|                  | `replicate`        | `replicate`          |                           | |\n| \u0026#x2753;         | `rev`              |                      |                           | [note #1](#note1 \"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.\") |\n|                  | `scan`             | `scan`               | `scanAsync`               | |\n| \u0026#x1f6ab;        | `scanBack`         |                      |                           | [note #2](#note2 \"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 'Back' iterators.\") |\n| \u0026#x2705; [#90][] | `singleton`        | `singleton`          |                           | |\n| \u0026#x2705; [#209][]| `skip`             | `skip`               |                           | |\n| \u0026#x2705; [#219][]| `skipWhile`        | `skipWhile`          | `skipWhileAsync`          | |\n| \u0026#x2705; [#219][]|                    | `skipWhileInclusive` | `skipWhileInclusiveAsync` | |\n| \u0026#x2753;         | `sort`             |                      |                           | [note #1](#note1 \"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.\") |\n| \u0026#x2753;         | `sortBy`           |                      |                           | [note #1](#note1 \"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.\") |\n| \u0026#x2753;         | `sortByAscending`  |                      |                           | [note #1](#note1 \"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.\") |\n| \u0026#x2753;         | `sortByDescending` |                      |                           | [note #1](#note1 \"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.\") |\n| \u0026#x2753;         | `sortWith`         |                      |                           | [note #1](#note1 \"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.\") |\n|                  | `splitInto`        | `splitInto`          |                           | |\n|                  | `sum`              | `sum`                |                           | |\n|                  | `sumBy`            | `sumBy`              | `sumByAsync`              | |\n| \u0026#x2705; [#76][] | `tail`             | `tail`               |                           | |\n| \u0026#x2705; [#209][]| `take`             | `take`               |                           | |\n| \u0026#x2705; [#126][]| `takeWhile`        | `takeWhile`          | `takeWhileAsync`          | |\n| \u0026#x2705; [#126][]|                    | `takeWhileInclusive` | `takeWhileInclusiveAsync` | |\n| \u0026#x2705; [#2][]  | `toArray`          | `toArray`            | `toArrayAsync`            | |\n| \u0026#x2705; [#2][]  |                    | `toIList`            | `toIListAsync`            | |\n| \u0026#x2705; [#2][]  | `toList`           | `toList`             | `toListAsync`             | |\n| \u0026#x2705; [#2][]  |                    | `toResizeArray`      | `toResizeArrayAsync`      | |\n| \u0026#x2705; [#2][]  |                    | `toSeq`              | `toSeqAsync`              | |\n|                  |                    | […]                  |                           | |\n| \u0026#x2753;         | `transpose`        |                      |                           | [note #1](#note1 \"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.\") |\n| \u0026#x2705; [#209][]| `truncate`         | `truncate`           |                           | |\n| \u0026#x2705; [#23][] | `tryExactlyOne`    | `tryExactlyOne`      | `tryExactlyOneAsync`      | |\n| \u0026#x2705; [#23][] | `tryFind`          | `tryFind`            | `tryFindAsync`            | |\n| \u0026#x1f6ab;        | `tryFindBack`      |                      |                           | [note #2](#note2 \"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 'Back' iterators.\") |\n| \u0026#x2705; [#68][] | `tryFindIndex`     | `tryFindIndex`       | `tryFindIndexAsync`       | |\n| \u0026#x1f6ab;        | `tryFindIndexBack` |                      |                           | [note #2](#note2 \"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 'Back' iterators.\") |\n| \u0026#x2705; [#23][] | `tryHead`          | `tryHead`            |                           | |\n| \u0026#x2705; [#23][] | `tryItem`          | `tryItem`            |                           | |\n| \u0026#x2705; [#23][] | `tryLast`          | `tryLast`            |                           | |\n| \u0026#x2705; [#23][] | `tryPick`          | `tryPick`            | `tryPickAsync`            | |\n| \u0026#x2705; [#76][] |                    | `tryTail`            |                           | |\n|                  | `unfold`           | `unfold`             | `unfoldAsync`             | |\n| \u0026#x2705; [#236][]| `updateAt`         | `updateAt`           |                           | |\n| \u0026#x2705; [#217][]| `where`            | `where`              | `whereAsync`              | |\n|                  | `windowed`         | `windowed`           |                           | |\n| \u0026#x2705; [#2][]  | `zip`              | `zip`                |                           | |\n|                  | `zip3`             | `zip3`               |                           | |\n|                  |                    | `zip4`               |                           | |\n\n\n\u003csup\u003e¹⁾ \u003ca id=\"note1\"\u003e\u003c/a\u003e_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._\u003c/sup\u003e\n\u003csup\u003e²⁾ \u003ca id=\"note2\"\u003e\u003c/a\u003e_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._\u003c/sup\u003e\n\u003csup\u003e³⁾ \u003ca id=\"note3\"\u003e\u003c/a\u003e_The motivation for `readOnly` in `Seq` is that a cast from a mutable array or list to a `seq\u003c_\u003e` is valid and can be cast back, leading to a mutable sequence. Since `TaskSeq` doesn't implement `IEnumerable\u003c_\u003e`, such casts are not possible._\u003c/sup\u003e\n\n## More information\n\n### Further reading on `IAsyncEnumerable`\n\n- A good C#-based introduction [can be found in this blog][8].\n- [An MSDN article][9] written shortly after it was introduced.\n- Converting a `seq` to an `IAsyncEnumerable` [demo gist][10] as an example, though `TaskSeq` contains many more utility functions and uses a slightly different approach.\n\n### Further reading on resumable state machines\n\n- A state machine from a monadic perspective in F# [can be found here][12], which works with the pre-F# 6.0 non-resumable internals.\n- The [original RFC for F# 6.0 on resumable state machines][13]\n- The [original RFC for introducing `task`][14] to F# 6.0.\n- A [pre F# 6.0 `TaskBuilder`][15] that motivated the `task` CE later added to F# Core.\n- [MSDN Documentation on `task`][16] and [`async`][17].\n\n### Further reading on computation expressions\n\n- [Docs on MSDN][18] form a good summary and starting point.\n- Arguably the best [step-by-step tutorial to using and building computation expressions][19] by Scott Wlaschin.\n\n## Building \u0026 testing\n\nTLDR: just run `build`. Or load the `sln` file in Visual Studio or VS Code and compile.\n\n### Prerequisites\n\nAt the very least, to get the source to compile, you'll need:\n\n- .NET 6 or .NET 7 Preview\n- F# 6.0 or 7.0 compiler\n- To use `build.cmd`, the `dotnet` command must be accessible from your path.\n\nJust check-out this repo locally. Then, from the root of the repo, you can do:\n\n### Build the solution\n\n```bash\nbuild [build] [release|debug]\n```\n\nWith no arguments, defaults to `release`.\n\n### Run the tests\n\n```bash\nbuild test [release|debug]\n```\n\nWith no arguments, defaults to `release`. By default, all tests are output to the console. If you don't want that, you can use `--logger console;verbosity=summary`.\nFurthermore, no TRX file is generated and the `--blame-xxx` flags aren't set.\n\n### Run the CI command\n\n```bash\nbuild ci [release|debug]\n```\n\nWith no arguments, defaults to `release`. This will run `dotnet test` with the `--blame-xxx` settings enabled to [prevent hanging tests][1] caused by\nan [xUnit runner bug][2].\n\nThere are no special CI environment variables that need to be set for running this locally.\n\n### Advanced\n\nYou can pass any additional options that are valid for `dotnet test` and `dotnet build` respectively. However,\nthese cannot be the very first argument, so you should either use `build build --myadditionalOptions fizz buzz`, or\njust specify the build-kind, i.e. this is fine:\n\n```bash\nbuild debug --verbosity detailed\nbuild test --logger console;verbosity=summary\n```\n\nAt this moment, additional options cannot have quotes in them.\n\nCommand modifiers, like `release` and `debug`, can be specified with `-` or `/` if you so prefer: `dotnet build /release`.\n\n### Get help\n\n```bash\nbuild help\n```\n\nFor more info, see this PR: \u003chttps://github.com/fsprojects/FSharp.Control.TaskSeq/pull/29\u003e.\n\n## Work in progress\n\nThe `taskSeq` CE using the statically compilable _resumable state machine_ approach is based on, and draw heavily from [Don Symes `taskSeq.fs`][20] as used to test the resumable state machine in the F# core compiler.\n\nOn top of that, this library adds a set of `TaskSeq` module functions, with their `Async` variants, on par with `Seq` and `AsyncSeq`.\n\n## Current set of `TaskSeq` utility functions\n\nThe following are the current surface area of the `TaskSeq` utility functions, ordered alphabetically.\n\n```f#\nmodule TaskSeq =\n    val append: source1: TaskSeq\u003c'T\u003e -\u003e source2: TaskSeq\u003c'T\u003e -\u003e TaskSeq\u003c'T\u003e\n    val appendSeq: source1: TaskSeq\u003c'T\u003e -\u003e source2: seq\u003c'T\u003e -\u003e TaskSeq\u003c'T\u003e\n    val box: source: TaskSeq\u003c'T\u003e -\u003e TaskSeq\u003cobj\u003e\n    val cast: source: TaskSeq\u003cobj\u003e -\u003e TaskSeq\u003c'T\u003e\n    val choose: chooser: ('T -\u003e 'U option) -\u003e source: TaskSeq\u003c'T\u003e -\u003e TaskSeq\u003c'U\u003e\n    val chooseAsync: chooser: ('T -\u003e #Task\u003c'U option\u003e) -\u003e source: TaskSeq\u003c'T\u003e -\u003e TaskSeq\u003c'U\u003e\n    val collect: binder: ('T -\u003e #TaskSeq\u003c'U\u003e) -\u003e source: TaskSeq\u003c'T\u003e -\u003e TaskSeq\u003c'U\u003e\n    val collectAsync: binder: ('T -\u003e #Task\u003c'TSeqU\u003e) -\u003e source: TaskSeq\u003c'T\u003e -\u003e TaskSeq\u003c'U\u003e when 'TSeqU :\u003e TaskSeq\u003c'U\u003e\n    val collectSeq: binder: ('T -\u003e #seq\u003c'U\u003e) -\u003e source: TaskSeq\u003c'T\u003e -\u003e TaskSeq\u003c'U\u003e\n    val collectSeqAsync: binder: ('T -\u003e #Task\u003c'SeqU\u003e) -\u003e source: TaskSeq\u003c'T\u003e -\u003e TaskSeq\u003c'U\u003e when 'SeqU :\u003e seq\u003c'U\u003e\n    val concat: sources: TaskSeq\u003c#TaskSeq\u003c'T\u003e\u003e -\u003e TaskSeq\u003c'T\u003e\n    val concat: sources: TaskSeq\u003c'T seq\u003e -\u003e TaskSeq\u003c'T\u003e\n    val concat: sources: TaskSeq\u003c'T list\u003e -\u003e TaskSeq\u003c'T\u003e\n    val concat: sources: TaskSeq\u003c'T array\u003e -\u003e TaskSeq\u003c'T\u003e\n    val concat: sources: TaskSeq\u003cResizeArray\u003c'T\u003e\u003e -\u003e TaskSeq\u003c'T\u003e\n    val contains\u003c'T when 'T: equality\u003e : value: 'T -\u003e source: TaskSeq\u003c'T\u003e -\u003e Task\u003cbool\u003e\n    val delay: generator: (unit -\u003e TaskSeq\u003c'T\u003e) -\u003e TaskSeq\u003c'T\u003e\n    val drop: count: int -\u003e source: TaskSeq\u003c'T\u003e -\u003e TaskSeq\u003c'T\u003e\n    val empty\u003c'T\u003e : TaskSeq\u003c'T\u003e\n    val exactlyOne: source: TaskSeq\u003c'T\u003e -\u003e Task\u003c'T\u003e\n    val except\u003c'T when 'T: equality\u003e : itemsToExclude: TaskSeq\u003c'T\u003e -\u003e source: TaskSeq\u003c'T\u003e -\u003e TaskSeq\u003c'T\u003e\n    val exceptOfSeq\u003c'T when 'T: equality\u003e : itemsToExclude: seq\u003c'T\u003e -\u003e source: TaskSeq\u003c'T\u003e -\u003e TaskSeq\u003c'T\u003e\n    val exists: predicate: ('T -\u003e bool) -\u003e source: TaskSeq\u003c'T\u003e -\u003e Task\u003cbool\u003e\n    val existsAsync: predicate: ('T -\u003e #Task\u003cbool\u003e) -\u003e source: TaskSeq\u003c'T\u003e -\u003e Task\u003cbool\u003e\n    val filter: predicate: ('T -\u003e bool) -\u003e source: TaskSeq\u003c'T\u003e -\u003e TaskSeq\u003c'T\u003e\n    val filterAsync: predicate: ('T -\u003e #Task\u003cbool\u003e) -\u003e source: TaskSeq\u003c'T\u003e -\u003e TaskSeq\u003c'T\u003e\n    val find: predicate: ('T -\u003e bool) -\u003e source: TaskSeq\u003c'T\u003e -\u003e Task\u003c'T\u003e\n    val findAsync: predicate: ('T -\u003e #Task\u003cbool\u003e) -\u003e source: TaskSeq\u003c'T\u003e -\u003e Task\u003c'T\u003e\n    val findIndex: predicate: ('T -\u003e bool) -\u003e source: TaskSeq\u003c'T\u003e -\u003e Task\u003cint\u003e\n    val findIndexAsync: predicate: ('T -\u003e #Task\u003cbool\u003e) -\u003e source: TaskSeq\u003c'T\u003e -\u003e Task\u003cint\u003e\n    val fold: folder: ('State -\u003e 'T -\u003e 'State) -\u003e state: 'State -\u003e source: TaskSeq\u003c'T\u003e -\u003e Task\u003c'State\u003e\n    val foldAsync: folder: ('State -\u003e 'T -\u003e #Task\u003c'State\u003e) -\u003e state: 'State -\u003e source: TaskSeq\u003c'T\u003e -\u003e Task\u003c'State\u003e\n    val forall: predicate: ('T -\u003e bool) -\u003e source: TaskSeq\u003c'T\u003e -\u003e Task\u003cbool\u003e\n    val forallAsync: predicate: ('T -\u003e #Task\u003cbool\u003e) -\u003e source: TaskSeq\u003c'T\u003e -\u003e Task\u003cbool\u003e\n    val head: source: TaskSeq\u003c'T\u003e -\u003e Task\u003c'T\u003e\n    val indexed: source: TaskSeq\u003c'T\u003e -\u003e TaskSeq\u003cint * 'T\u003e\n    val init: count: int -\u003e initializer: (int -\u003e 'T) -\u003e TaskSeq\u003c'T\u003e\n    val initAsync: count: int -\u003e initializer: (int -\u003e #Task\u003c'T\u003e) -\u003e TaskSeq\u003c'T\u003e\n    val initInfinite: initializer: (int -\u003e 'T) -\u003e TaskSeq\u003c'T\u003e\n    val initInfiniteAsync: initializer: (int -\u003e #Task\u003c'T\u003e) -\u003e TaskSeq\u003c'T\u003e\n    val insertAt: position:int -\u003e value:'T -\u003e source: TaskSeq\u003c'T\u003e -\u003e TaskSeq\u003c'T\u003e\n    val insertManyAt: position:int -\u003e values:TaskSeq\u003c'T\u003e -\u003e source: TaskSeq\u003c'T\u003e -\u003e TaskSeq\u003c'T\u003e\n    val isEmpty: source: TaskSeq\u003c'T\u003e -\u003e Task\u003cbool\u003e\n    val item: index: int -\u003e source: TaskSeq\u003c'T\u003e -\u003e Task\u003c'T\u003e\n    val iter: action: ('T -\u003e unit) -\u003e source: TaskSeq\u003c'T\u003e -\u003e Task\u003cunit\u003e\n    val iterAsync: action: ('T -\u003e #Task\u003cunit\u003e) -\u003e source: TaskSeq\u003c'T\u003e -\u003e Task\u003cunit\u003e\n    val iteri: action: (int -\u003e 'T -\u003e unit) -\u003e source: TaskSeq\u003c'T\u003e -\u003e Task\u003cunit\u003e\n    val iteriAsync: action: (int -\u003e 'T -\u003e #Task\u003cunit\u003e) -\u003e source: TaskSeq\u003c'T\u003e -\u003e Task\u003cunit\u003e\n    val last: source: TaskSeq\u003c'T\u003e -\u003e Task\u003c'T\u003e\n    val length: source: TaskSeq\u003c'T\u003e -\u003e Task\u003cint\u003e\n    val lengthBy: predicate: ('T -\u003e bool) -\u003e source: TaskSeq\u003c'T\u003e -\u003e Task\u003cint\u003e\n    val lengthByAsync: predicate: ('T -\u003e #Task\u003cbool\u003e) -\u003e source: TaskSeq\u003c'T\u003e -\u003e Task\u003cint\u003e\n    val lengthOrMax: max: int -\u003e source: TaskSeq\u003c'T\u003e -\u003e Task\u003cint\u003e\n    val map: mapper: ('T -\u003e 'U) -\u003e source: TaskSeq\u003c'T\u003e -\u003e TaskSeq\u003c'U\u003e\n    val mapAsync: mapper: ('T -\u003e #Task\u003c'U\u003e) -\u003e source: TaskSeq\u003c'T\u003e -\u003e TaskSeq\u003c'U\u003e\n    val mapi: mapper: (int -\u003e 'T -\u003e 'U) -\u003e source: TaskSeq\u003c'T\u003e -\u003e TaskSeq\u003c'U\u003e\n    val mapiAsync: mapper: (int -\u003e 'T -\u003e #Task\u003c'U\u003e) -\u003e source: TaskSeq\u003c'T\u003e -\u003e TaskSeq\u003c'U\u003e\n    val max: source: TaskSeq\u003c'T\u003e -\u003e Task\u003c'T\u003e when 'T: comparison\n    val max: source: TaskSeq\u003c'T\u003e -\u003e Task\u003c'T\u003e when 'T: comparison\n    val maxBy: projection: ('T -\u003e 'U) -\u003e source: TaskSeq\u003c'T\u003e -\u003e Task\u003c'T\u003e when 'U: comparison\n    val minBy: projection: ('T -\u003e 'U) -\u003e source: TaskSeq\u003c'T\u003e -\u003e Task\u003c'T\u003e when 'U: comparison\n    val maxByAsync: projection: ('T -\u003e #Task\u003c'U\u003e) -\u003e source: TaskSeq\u003c'T\u003e -\u003e Task\u003c'T\u003e when 'U: comparison\n    val minByAsync: projection: ('T -\u003e #Task\u003c'U\u003e) -\u003e source: TaskSeq\u003c'T\u003e -\u003e Task\u003c'T\u003e when 'U: comparison    val ofArray: source: 'T[] -\u003e TaskSeq\u003c'T\u003e\n    val ofAsyncArray: source: Async\u003c'T\u003e array -\u003e TaskSeq\u003c'T\u003e\n    val ofAsyncList: source: Async\u003c'T\u003e list -\u003e TaskSeq\u003c'T\u003e\n    val ofAsyncSeq: source: seq\u003cAsync\u003c'T\u003e\u003e -\u003e TaskSeq\u003c'T\u003e\n    val ofList: source: 'T list -\u003e TaskSeq\u003c'T\u003e\n    val ofResizeArray: source: ResizeArray\u003c'T\u003e -\u003e TaskSeq\u003c'T\u003e\n    val ofSeq: source: seq\u003c'T\u003e -\u003e TaskSeq\u003c'T\u003e\n    val ofTaskArray: source: #Task\u003c'T\u003e array -\u003e TaskSeq\u003c'T\u003e\n    val ofTaskList: source: #Task\u003c'T\u003e list -\u003e TaskSeq\u003c'T\u003e\n    val ofTaskSeq: source: seq\u003c#Task\u003c'T\u003e\u003e -\u003e TaskSeq\u003c'T\u003e\n    val pick: chooser: ('T -\u003e 'U option) -\u003e source: TaskSeq\u003c'T\u003e -\u003e Task\u003c'U\u003e\n    val pickAsync: chooser: ('T -\u003e #Task\u003c'U option\u003e) -\u003e source: TaskSeq\u003c'T\u003e -\u003e Task\u003c'U\u003e\n    val prependSeq: source1: seq\u003c'T\u003e -\u003e source2: TaskSeq\u003c'T\u003e -\u003e TaskSeq\u003c'T\u003e\n    val removeAt: position:int -\u003e source: TaskSeq\u003c'T\u003e -\u003e TaskSeq\u003c'T\u003e\n    val removeManyAt: position:int -\u003e count:int -\u003e source: TaskSeq\u003c'T\u003e -\u003e TaskSeq\u003c'T\u003e\n    val singleton: source: 'T -\u003e TaskSeq\u003c'T\u003e\n    val skip: count: int -\u003e source: TaskSeq\u003c'T\u003e -\u003e TaskSeq\u003c'T\u003e\n    val tail: source: TaskSeq\u003c'T\u003e -\u003e Task\u003cTaskSeq\u003c'T\u003e\u003e\n    val take: count: int -\u003e source: TaskSeq\u003c'T\u003e -\u003e TaskSeq\u003c'T\u003e\n    val takeWhile: predicate: ('T -\u003e bool) -\u003e source: TaskSeq\u003c'T\u003e -\u003e Task\u003cTaskSeq\u003c'T\u003e\u003e\n    val takeWhileAsync: predicate: ('T -\u003e #Task\u003cbool\u003e) -\u003e source: TaskSeq\u003c'T\u003e -\u003e Task\u003cTaskSeq\u003c'T\u003e\u003e\n    val takeWhileInclusive: predicate: ('T -\u003e bool) -\u003e source: TaskSeq\u003c'T\u003e -\u003e Task\u003cTaskSeq\u003c'T\u003e\u003e\n    val takeWhileInclusiveAsync: predicate: ('T -\u003e #Task\u003cbool\u003e) -\u003e source: TaskSeq\u003c'T\u003e -\u003e Task\u003cTaskSeq\u003c'T\u003e\u003e\n    val toArray: source: TaskSeq\u003c'T\u003e -\u003e 'T[]\n    val toArrayAsync: source: TaskSeq\u003c'T\u003e -\u003e Task\u003c'T[]\u003e\n    val toIListAsync: source: TaskSeq\u003c'T\u003e -\u003e Task\u003cIList\u003c'T\u003e\u003e\n    val toList: source: TaskSeq\u003c'T\u003e -\u003e 'T list\n    val toListAsync: source: TaskSeq\u003c'T\u003e -\u003e Task\u003c'T list\u003e\n    val toResizeArrayAsync: source: TaskSeq\u003c'T\u003e -\u003e Task\u003cResizeArray\u003c'T\u003e\u003e\n    val toSeq: source: TaskSeq\u003c'T\u003e -\u003e seq\u003c'T\u003e\n    val truncate: count: int -\u003e source: TaskSeq\u003c'T\u003e -\u003e TaskSeq\u003c'T\u003e\n    val tryExactlyOne: source: TaskSeq\u003c'T\u003e -\u003e Task\u003c'T option\u003e\n    val tryFind: predicate: ('T -\u003e bool) -\u003e source: TaskSeq\u003c'T\u003e -\u003e Task\u003c'T option\u003e\n    val tryFindAsync: predicate: ('T -\u003e #Task\u003cbool\u003e) -\u003e source: TaskSeq\u003c'T\u003e -\u003e Task\u003c'T option\u003e\n    val tryFindIndex: predicate: ('T -\u003e bool) -\u003e source: TaskSeq\u003c'T\u003e -\u003e Task\u003cint option\u003e\n    val tryFindIndexAsync: predicate: ('T -\u003e #Task\u003cbool\u003e) -\u003e source: TaskSeq\u003c'T\u003e -\u003e Task\u003cint option\u003e\n    val tryHead: source: TaskSeq\u003c'T\u003e -\u003e Task\u003c'T option\u003e\n    val tryItem: index: int -\u003e source: TaskSeq\u003c'T\u003e -\u003e Task\u003c'T option\u003e\n    val tryLast: source: TaskSeq\u003c'T\u003e -\u003e Task\u003c'T option\u003e\n    val tryPick: chooser: ('T -\u003e 'U option) -\u003e source: TaskSeq\u003c'T\u003e -\u003e Task\u003c'U option\u003e\n    val tryPickAsync: chooser: ('T -\u003e #Task\u003c'U option\u003e) -\u003e source: TaskSeq\u003c'T\u003e -\u003e Task\u003c'U option\u003e\n    val tryTail: source: TaskSeq\u003c'T\u003e -\u003e Task\u003cTaskSeq\u003c'T\u003e option\u003e\n    val where: predicate: ('T -\u003e bool) -\u003e source: TaskSeq\u003c'T\u003e -\u003e TaskSeq\u003c'T\u003e\n    val whereAsync: predicate: ('T -\u003e #Task\u003cbool\u003e) -\u003e source: TaskSeq\u003c'T\u003e -\u003e TaskSeq\u003c'T\u003e\n    val unbox\u003c'U when 'U: struct\u003e : source: TaskSeq\u003cobj\u003e -\u003e TaskSeq\u003c'U\u003e\n    val updateAt: position:int -\u003e value:'T -\u003e source: TaskSeq\u003c'T\u003e -\u003e TaskSeq\u003c'T\u003e\n    val zip: source1: TaskSeq\u003c'T\u003e -\u003e source2: TaskSeq\u003c'U\u003e -\u003e TaskSeq\u003c'T * 'U\u003e\n```\n\n[buildstatus]: https://github.com/fsprojects/FSharp.Control.TaskSeq/actions/workflows/main.yaml\n[buildstatus_img]: https://github.com/fsprojects/FSharp.Control.TaskSeq/actions/workflows/main.yaml/badge.svg\n[teststatus]: https://github.com/fsprojects/FSharp.Control.TaskSeq/actions/workflows/test.yaml\n[teststatus_img]: https://github.com/fsprojects/FSharp.Control.TaskSeq/actions/workflows/test.yaml/badge.svg\n\n[1]: https://github.com/fsprojects/FSharp.Control.TaskSeq/pull/25\n[2]: https://github.com/xunit/xunit/issues/2587\n[3]: https://learn.microsoft.com/en-us/dotnet/api/system.collections.generic.iasyncenumerable-1?view=net-6.0\n[4]: https://learn.microsoft.com/en-us/dotnet/api/system.collections.generic.iasyncenumerator-1.movenextasync?view=net-6.0\n[5]: https://learn.microsoft.com/en-us/dotnet/api/system.collections.generic.iasyncenumerator-1.current?view=net-6.0\n[6]: https://learn.microsoft.com/en-us/dotnet/api/system.collections.generic.iasyncenumerable-1.getasyncenumerator?view=net-6.0\n[7]: https://learn.microsoft.com/en-us/dotnet/api/system.iasyncdisposable?view=net-6.0\n[8]: https://stu.dev/iasyncenumerable-introduction/\n[9]: https://learn.microsoft.com/en-us/archive/msdn-magazine/2019/november/csharp-iterating-with-async-enumerables-in-csharp-8\n[10]: https://gist.github.com/akhansari/d88812b742aa6be1c35b4f46bd9f8532\n[11]: https://fsprojects.github.io/FSharp.Control.AsyncSeq/AsyncSeq.html\n[12]: http://blumu.github.io/ResumableMonad/TheResumableMonad.html\n[13]: https://github.com/fsharp/fslang-design/blob/main/FSharp-6.0/FS-1087-resumable-code.md\n[14]: https://github.com/fsharp/fslang-design/blob/main/FSharp-6.0/FS-1097-task-builder.md\n[15]: https://github.com/rspeele/TaskBuilder.fs/\n[16]: https://learn.microsoft.com/en-us/dotnet/fsharp/language-reference/task-expressions\n[17]: https://learn.microsoft.com/en-us/dotnet/fsharp/language-reference/async-expressions\n[18]: https://learn.microsoft.com/en-us/dotnet/fsharp/language-reference/computation-expressions\n[19]: https://fsharpforfunandprofit.com/series/computation-expressions/\n[20]: https://github.com/dotnet/fsharp/blob/d5312aae8aad650f0043f055bb14c3aa8117e12e/tests/benchmarks/CompiledCodeBenchmarks/TaskPerf/TaskPerf/taskSeq.fs\n[21]: https://www.nuget.org/packages/FSharp.Control.TaskSeq#versions-body-tab\n[22]: https://fsprojects.github.io/FSharp.Control.AsyncSeq/reference/fsharp-control-asyncseq.html#toAsyncEnum\n[23]: https://fsprojects.github.io/FSharp.Control.AsyncSeq/reference/fsharp-control-asyncseq.html#fromAsyncEnum\n[24]: https://github.com/TheAngryByrd/IcedTasks\n\n[#2]: https://github.com/fsprojects/FSharp.Control.TaskSeq/pull/2\n[#11]: https://github.com/fsprojects/FSharp.Control.TaskSeq/pull/11\n[#23]: https://github.com/fsprojects/FSharp.Control.TaskSeq/pull/23\n[#53]: https://github.com/fsprojects/FSharp.Control.TaskSeq/pull/53\n[#67]: https://github.com/fsprojects/FSharp.Control.TaskSeq/pull/67\n[#68]: https://github.com/fsprojects/FSharp.Control.TaskSeq/pull/68\n[#69]: https://github.com/fsprojects/FSharp.Control.TaskSeq/pull/69\n[#70]: https://github.com/fsprojects/FSharp.Control.TaskSeq/pull/70\n[#76]: https://github.com/fsprojects/FSharp.Control.TaskSeq/pull/76\n[#81]: https://github.com/fsprojects/FSharp.Control.TaskSeq/pull/81\n[#82]: https://github.com/fsprojects/FSharp.Control.TaskSeq/pull/82\n[#83]: https://github.com/fsprojects/FSharp.Control.TaskSeq/pull/83\n[#90]: https://github.com/fsprojects/FSharp.Control.TaskSeq/pull/90\n[#126]: https://github.com/fsprojects/FSharp.Control.TaskSeq/pull/126\n[#133]: https://github.com/fsprojects/FSharp.Control.TaskSeq/issues/133\n[#167]: https://github.com/fsprojects/FSharp.Control.TaskSeq/issues/167\n[#209]: https://github.com/fsprojects/FSharp.Control.TaskSeq/issues/209\n[#217]: https://github.com/fsprojects/FSharp.Control.TaskSeq/issues/217\n[#219]: https://github.com/fsprojects/FSharp.Control.TaskSeq/issues/219\n[#221]: https://github.com/fsprojects/FSharp.Control.TaskSeq/issues/221\n[#237]: https://github.com/fsprojects/FSharp.Control.TaskSeq/issues/237\n[#236]: https://github.com/fsprojects/FSharp.Control.TaskSeq/issues/236\n[#240]: https://github.com/fsprojects/FSharp.Control.TaskSeq/issues/240\n\n[issues]: https://github.com/fsprojects/FSharp.Control.TaskSeq/issues\n[nuget]: https://www.nuget.org/packages/FSharp.Control.TaskSeq/\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffsprojects%2Ffsharp.control.taskseq","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ffsprojects%2Ffsharp.control.taskseq","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffsprojects%2Ffsharp.control.taskseq/lists"}