Skip to content

Add IAsyncEnumerable support to task computation expressions#347

Merged
TheAngryByrd merged 3 commits into
masterfrom
copilot/add-iasynceenumerable-support
Feb 25, 2026
Merged

Add IAsyncEnumerable support to task computation expressions#347
TheAngryByrd merged 3 commits into
masterfrom
copilot/add-iasynceenumerable-support

Conversation

Copilot AI commented Feb 24, 2026

Copy link
Copy Markdown
Contributor

Task-based computation expressions (taskResult, taskOption, taskValidation, taskValueOption, and their backgroundTask* variants) did not support for .. in .. iteration over IAsyncEnumerable<T> sequences.

Changes

Core builders (TaskResultCE.fs, TaskOptionCE.fs, TaskValidationCE.fs, TaskValueOptionCE.fs)

  • WhileAsync — async condition loop that awaits ValueTask<bool> before each iteration; built on this.While (not ResumableCode.While) so error/None short-circuit stops the loop without an extra MoveNextAsync() call. Implements both the static state machine (__useResumableCode) and dynamic paths.
  • For(#IAsyncEnumerable<'T>) — uses this.Using for async disposal of the enumerator + WhileAsync with e.MoveNextAsync().
  • Source(#IAsyncEnumerable<_>) — added in a separate [<AutoOpen>] extension module to avoid CLR signature conflicts with the existing Source(#seq<_>) method (both compile to the same generic signature on the same type).

backgroundTask* builders inherit from these base classes and gain support automatically.

Tests

  • TestHelpers.toAsyncEnumerable — minimal IAsyncEnumerable<T> wrapper over a list for test use.
  • Happy-path and early-exit (error/None) tests added for all seven affected CE builders.

Example

let items : IAsyncEnumerable<string> = getItemsAsync()

let! result =
    taskResult {
        for item in items do
            let! validated = validate item
            do! save validated
        return "done"
    }
// Stops iteration immediately on the first Error
Original prompt

This section details on the original issue you should resolve

<issue_title>IAsyncEnumerable</issue_title>
<issue_description>I noticed FSharp.Control.TaskSeq isn't supported with computation expressions like taskResult, any plans?
</issue_description>

<agent_instructions>- Make sure you've added tests and they pass

  • Make sure you've added documentation and doc comments
  • Make sure you've researched the implementation in IcedTasks</agent_instructions>

Comments on the Issue (you are @copilot in this section)

@TheAngryByrd 👋 While I wouldn't depend on `FSharp.Control.TaskSeq` for this, I'd accept a PR for handling `IAsyncEnumerable`. Here's an example of the [implementation in IcedTasks](https://github.com/TheAngryByrd/IcedTasks/blob/db0b55bd89f769e17744319bfc510486a5b1fc5f/src/IcedTasks/TaskBuilderBase.fs#L343-L357) someone could use for reference.

✨ Let Copilot coding agent set things up for you — coding agent works faster and does higher quality work when set up for your repo.

Copilot AI and others added 2 commits February 24, 2026 20:11
…n, taskValueOption CEs

Co-authored-by: TheAngryByrd <1490044+TheAngryByrd@users.noreply.github.com>
Co-authored-by: TheAngryByrd <1490044+TheAngryByrd@users.noreply.github.com>
Copilot AI changed the title [WIP] Add support for IAsyncEnumerable in computation expressions Add IAsyncEnumerable support to task computation expressions Feb 24, 2026
Copilot AI requested a review from TheAngryByrd February 24, 2026 20:18
@TheAngryByrd TheAngryByrd requested a review from Copilot February 25, 2026 02:07

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adds IAsyncEnumerable<T> support to task-based computation expressions, enabling for .. in .. iteration over async sequences with early exit on error/None conditions.

Changes:

  • Implemented WhileAsync and For(#IAsyncEnumerable<'T>) methods in core builder base classes
  • Added Source(#IAsyncEnumerable<_>) extension methods in separate auto-open modules to avoid CLR signature conflicts
  • Added test helper toAsyncEnumerable and comprehensive tests for all affected builders

Reviewed changes

Copilot reviewed 12 out of 12 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
tests/FsToolkit.ErrorHandling.Tests/TestHelpers.fs Added toAsyncEnumerable helper to create test IAsyncEnumerable<T> instances from lists
tests/FsToolkit.ErrorHandling.Tests/TaskValueOptionCE.fs Added tests for IAsyncEnumerable iteration in taskValueOption with happy path and early exit scenarios
tests/FsToolkit.ErrorHandling.Tests/TaskValidationCE.fs Added tests for IAsyncEnumerable iteration in taskValidation with happy path and early exit scenarios
tests/FsToolkit.ErrorHandling.Tests/TaskResultCE.fs Added tests for IAsyncEnumerable iteration in taskResult with happy path and early exit scenarios
tests/FsToolkit.ErrorHandling.Tests/TaskOptionCE.fs Added tests for IAsyncEnumerable iteration in taskOption with happy path and early exit scenarios
tests/FsToolkit.ErrorHandling.Tests/BackgroundTaskValueOptionCE.fs Added tests for IAsyncEnumerable iteration in backgroundTaskValueOption with happy path and early exit scenarios
tests/FsToolkit.ErrorHandling.Tests/BackgroundTaskResultCE.fs Added tests for IAsyncEnumerable iteration in backgroundTaskResult with happy path and early exit scenarios
tests/FsToolkit.ErrorHandling.Tests/BackgroundTaskOptionCE.fs Added tests for IAsyncEnumerable iteration in backgroundTaskOption with happy path and early exit scenarios
src/FsToolkit.ErrorHandling/TaskValueOptionCE.fs Implemented WhileAsync, For(#IAsyncEnumerable<'T>), and Source extension for TaskValueOptionBuilderBase
src/FsToolkit.ErrorHandling/TaskValidationCE.fs Implemented WhileAsync, For(#IAsyncEnumerable<'T>), and Source extension for TaskValidationBuilderBase
src/FsToolkit.ErrorHandling/TaskResultCE.fs Implemented WhileAsync, For(#IAsyncEnumerable<'T>), and Source extension for TaskResultBuilderBase
src/FsToolkit.ErrorHandling/TaskOptionCE.fs Implemented WhileAsync, For(#IAsyncEnumerable<'T>), and Source extension for TaskOptionBuilderBase

Comment thread src/FsToolkit.ErrorHandling/TaskResultCE.fs
Comment thread src/FsToolkit.ErrorHandling/TaskOptionCE.fs
Comment thread src/FsToolkit.ErrorHandling/TaskValidationCE.fs
Comment thread src/FsToolkit.ErrorHandling/TaskValueOptionCE.fs
@TheAngryByrd TheAngryByrd marked this pull request as ready for review February 25, 2026 02:20
@TheAngryByrd TheAngryByrd merged commit 45e1abd into master Feb 25, 2026
30 checks passed
@TheAngryByrd

Copy link
Copy Markdown
Collaborator

@copilot open a new PR and create gitbook docs to show off this new feature

TheAngryByrd added a commit that referenced this pull request Feb 27, 2026
- [Add IAsyncEnumerable support to task computation expressions](#347) Credits @Copilot
- [Add `valueTaskValueOption` CE for `ValueTask<'T voption>` computation expressions](#348) Credits @Copilot
- [Add `cancellableValueTaskOption` and `cancellableValueTaskResult` CEs for IcedTasks](#349) Credits @Copilot
- [Add `Source` overloads to `taskResultOption` CE for interop with `Result`, `TaskResult`, `Option`, `Task`, and `Async`](#351) Credits @Copilot
- [Add `requireSomeWith` and `requireNoneWith` for lazy error evaluation](#352) Credits @Copilot
- [Add `TaskResult.ofCatchTask`](#353) Credits @Copilot
- [Add comprehensive gitbook documentation for all public API surface](#354) Credits @Copilot
TheAngryByrd added a commit that referenced this pull request Feb 27, 2026
- [Add IAsyncEnumerable support to task computation expressions](#347) Credits @Copilot
- [Add `valueTaskValueOption` CE for `ValueTask<'T voption>` computation expressions](#348) Credits @Copilot
- [Add `cancellableValueTaskOption` and `cancellableValueTaskResult` CEs for IcedTasks](#349) Credits @Copilot
- [Add `Source` overloads to `taskResultOption` CE for interop with `Result`, `TaskResult`, `Option`, `Task`, and `Async`](#351) Credits @Copilot
- [Add `requireSomeWith` and `requireNoneWith` for lazy error evaluation](#352) Credits @Copilot
- [Add `TaskResult.ofCatchTask`](#353) Credits @Copilot
- [Add comprehensive gitbook documentation for all public API surface](#354) Credits @Copilot
TheAngryByrd added a commit that referenced this pull request Feb 27, 2026
- [Add IAsyncEnumerable support to task computation expressions](#347) Credits @Copilot
- [Add `valueTaskValueOption` CE for `ValueTask<'T voption>` computation expressions](#348) Credits @Copilot
- [Add `cancellableValueTaskOption` and `cancellableValueTaskResult` CEs for IcedTasks](#349) Credits @Copilot
- [Add `Source` overloads to `taskResultOption` CE for interop with `Result`, `TaskResult`, `Option`, `Task`, and `Async`](#351) Credits @Copilot
- [Add `requireSomeWith` and `requireNoneWith` for lazy error evaluation](#352) Credits @Copilot
- [Add `TaskResult.ofCatchTask`](#353) Credits @Copilot
- [Add comprehensive gitbook documentation for all public API surface](#354) Credits @Copilot

Remove AutoGPT subproject reference
TheAngryByrd added a commit that referenced this pull request Feb 27, 2026
- [Add IAsyncEnumerable support to task computation expressions](#347) Credits @Copilot
- [Add `valueTaskValueOption` CE for `ValueTask<'T voption>` computation expressions](#348) Credits @Copilot
- [Add `cancellableValueTaskOption` and `cancellableValueTaskResult` CEs for IcedTasks](#349) Credits @Copilot
- [Add `Source` overloads to `taskResultOption` CE for interop with `Result`, `TaskResult`, `Option`, `Task`, and `Async`](#351) Credits @Copilot
- [Add `requireSomeWith` and `requireNoneWith` for lazy error evaluation](#352) Credits @Copilot
- [Add `TaskResult.ofCatchTask`](#353) Credits @Copilot
- [Add comprehensive gitbook documentation for all public API surface](#354) Credits @Copilot

Remove AutoGPT subproject reference
TheAngryByrd added a commit that referenced this pull request Feb 27, 2026
- [Add IAsyncEnumerable support to task computation expressions](#347) Credits @Copilot
- [Add `valueTaskValueOption` CE for `ValueTask<'T voption>` computation expressions](#348) Credits @Copilot
- [Add `cancellableValueTaskOption` and `cancellableValueTaskResult` CEs for IcedTasks](#349) Credits @Copilot
- [Add `Source` overloads to `taskResultOption` CE for interop with `Result`, `TaskResult`, `Option`, `Task`, and `Async`](#351) Credits @Copilot
- [Add `requireSomeWith` and `requireNoneWith` for lazy error evaluation](#352) Credits @Copilot
- [Add `TaskResult.ofCatchTask`](#353) Credits @Copilot
- [Add comprehensive gitbook documentation for all public API surface](#354) Credits @Copilot
TheAngryByrd added a commit that referenced this pull request Feb 27, 2026
- [Add IAsyncEnumerable support to task computation expressions](#347) Credits @Copilot
- [Add `valueTaskValueOption` CE for `ValueTask<'T voption>` computation expressions](#348) Credits @Copilot
- [Add `cancellableValueTaskOption` and `cancellableValueTaskResult` CEs for IcedTasks](#349) Credits @Copilot
- [Add `Source` overloads to `taskResultOption` CE for interop with `Result`, `TaskResult`, `Option`, `Task`, and `Async`](#351) Credits @Copilot
- [Add `requireSomeWith` and `requireNoneWith` for lazy error evaluation](#352) Credits @Copilot
- [Add `TaskResult.ofCatchTask`](#353) Credits @Copilot
- [Add comprehensive gitbook documentation for all public API surface](#354) Credits @Copilot

Remove AutoGPT subproject reference
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

IAsyncEnumerable

3 participants