Skip to content

[Repo Assist] feat: add Group 1 AsyncSeq design-parity functions#349

Closed
github-actions[bot] wants to merge 2 commits intomainfrom
repo-assist/fix-issue-345-group1-20260317-744691912aa8b78c
Closed

[Repo Assist] feat: add Group 1 AsyncSeq design-parity functions#349
github-actions[bot] wants to merge 2 commits intomainfrom
repo-assist/fix-issue-345-group1-20260317-744691912aa8b78c

Conversation

@github-actions
Copy link
Contributor

🤖 This PR was created by Repo Assist, an automated AI assistant.

Summary

Implements the remaining Group 1 functions identified in the AsyncSeq/TaskSeq design-parity gap analysis (#345), responding to @dsyme's request to "work on group 1".

distinctUntilChangedWith/distinctUntilChangedWithAsync were already added in PR #346. This PR covers everything else in Group 1:

New function(s) What it does
replicateInfinite value Infinite sequence of a constant value
replicateInfiniteAsync computation Infinite sequence via repeated async computation
replicateUntilNoneAsync computation Emit until computation returns None
firstOrDefault defaultValue Returns first element or default (wraps tryHead)
lastOrDefault defaultValue Returns last element or default (wraps tryLast)
splitAt count Splits into (prefix array, remaining TaskSeq) in a single pass
zipWith mapping / zipWithAsync mapping Zip two sequences with an inline mapping function
zipWith3 mapping / zipWithAsync3 mapping Zip three sequences with an inline mapping function
chunkBy projection / chunkByAsync projection Groups consecutive elements by key
threadState folder state Streaming stateful map — yields results lazily (like mapFold but lazy)
threadStateAsync folder state Async variant of threadState

Design notes

  • splitAt shares a single enumerator between the prefix array and the rest sequence, following the same single-pass pattern as the existing tryTail. This is safe for the common case of replayable sequences (taskSeq builders, arrays, lists, etc.).
  • chunkBy groups consecutive equal-key runs only, unlike groupBy which groups globally. Requires 'Key: equality.
  • threadState is the streaming counterpart to mapFold—the results are lazy and the final state is not returned. This matches AsyncSeq's threadStateAsync.
  • replicateInfiniteAsync takes unit -> #Task<'T> rather than a single Task<'T>, since Tasks are single-use.

Changes

File Change
TaskSeqInternal.fs 11 new functions
TaskSeq.fs Dispatch wrappers for all new functions
TaskSeq.fsi XML-documented signatures
TaskSeq.*.Tests.fs 6 new test files, 326 new tests
release-notes.txt Updated under 1.0.0

Test Status

✅ Build: dotnet build src/FSharp.Control.TaskSeq.sln -c Releasesucceeded, 0 warnings, 0 errors
✅ Format: dotnet fantomas . --checkall files correctly formatted
✅ Tests: dotnet test ... -c Release4,942 passed, 2 skipped (infrastructure), 0 failed

Closes part of #345 (Group 1 complete, pending merge of #346 for distinctUntilChangedWith).

Generated by Repo Assist

Generated by Repo Assist for issue #345 ·

To install this agentic workflow, run

gh aw add githubnext/agentics/workflows/repo-assist.md@346204513ecfa08b81566450d7d599556807389f

Implements the remaining Group 1 functions identified in the AsyncSeq/TaskSeq
design-parity gap analysis:

- TaskSeq.replicateInfinite: infinite sequence of a constant value
- TaskSeq.replicateInfiniteAsync: infinite sequence via repeated async computation
- TaskSeq.replicateUntilNoneAsync: sequence until computation returns None
- TaskSeq.firstOrDefault / lastOrDefault: convenience wrappers over tryHead/tryLast
- TaskSeq.splitAt: split into prefix array + remaining TaskSeq in a single pass
- TaskSeq.zipWith / zipWithAsync: zip two sequences with an inline mapping function
- TaskSeq.zipWith3 / zipWithAsync3: zip three sequences with an inline mapping
- TaskSeq.chunkBy / chunkByAsync: group consecutive elements by key
- TaskSeq.threadState / threadStateAsync: streaming stateful map (like mapFold
  but yields lazily instead of materialising to an array)

The distinctUntilChangedWith/Async pair was already added in PR #346.

Includes 326 new tests and passes all 4942 existing tests.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@dsyme dsyme marked this pull request as ready for review March 17, 2026 00:57
@dsyme
Copy link
Contributor

dsyme commented Mar 17, 2026

/repo-assist We just merged a similar PR, if there's anythi

@dsyme dsyme closed this Mar 17, 2026
@github-actions
Copy link
Contributor Author

🤖 This is an automated response from Repo Assist.

Confirmed — PR #350 was merged into main covering the same Group 1 AsyncSeq design-parity functions (replicateInfinite*, firstOrDefault, lastOrDefault, splitAt, zipWith*, chunkBy*, threadState*). This PR is correctly closed with no further action needed. Issue #345 has also been closed as completed.

Generated by Repo Assist for issue #349 ·

To install this agentic workflow, run

gh aw add githubnext/agentics/workflows/repo-assist.md@346204513ecfa08b81566450d7d599556807389f

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

We want design parity with FSharp.Control.AsyncSeq

1 participant