Skip to content

[Repo Assist] feat: add TaskSeq.iteri2, iteri2Async, mapi2, mapi2Async - #330

Closed
github-actions[bot] wants to merge 2 commits into
mainfrom
repo-assist/feat-iteri2-mapi2-2026-03-2e22432f4ae35c5a
Closed

[Repo Assist] feat: add TaskSeq.iteri2, iteri2Async, mapi2, mapi2Async#330
github-actions[bot] wants to merge 2 commits into
mainfrom
repo-assist/feat-iteri2-mapi2-2026-03-2e22432f4ae35c5a

Conversation

@github-actions

Copy link
Copy Markdown
Contributor

🤖 This is a draft PR from Repo Assist, an automated AI assistant.

Implements the indexed-pair variants from the README roadmap:

TaskSeq.iteri2 :(int -> 'T -> 'U -> unit)-> TaskSeq<'T>-> TaskSeq<'U>-> Task(unit)
TaskSeq.iteri2Async :(int -> 'T -> 'U -> #Task(unit))-> TaskSeq<'T>-> TaskSeq<'U>-> Task(unit)
TaskSeq.mapi2 :(int -> 'T -> 'U -> 'V)-> TaskSeq<'T>-> TaskSeq<'U>-> TaskSeq<'V>
TaskSeq.mapi2Async :(int -> 'T -> 'U -> #Task<'V>)-> TaskSeq<'T>-> TaskSeq<'U>-> TaskSeq<'V>

Semantics: iteration stops when either sequence is exhausted — excess elements in the longer sequence are silently ignored. This matches zip, map2, and iter2.

Files changed

  • src/FSharp.Control.TaskSeq/TaskSeqInternal.fsiteri2, iteri2Async, mapi2, mapi2Async implementations; placed adjacent to the existing iter/map functions
  • src/FSharp.Control.TaskSeq/TaskSeq.fs — wrapper static members, after iteriAsync and mapiAsync
  • src/FSharp.Control.TaskSeq/TaskSeq.fsi — public signatures with XML doc; placed after iteriAsync and mapiAsync respectively
  • src/FSharp.Control.TaskSeq.Test/TaskSeq.Iteri2Mapi2.Tests.fs — new test file with null checks, empty sequences, truncation tests, index verification, type mixing, and side-effect tests
  • src/FSharp.Control.TaskSeq.Test/FSharp.Control.TaskSeq.Test.fsproj — new test file reference
  • release-notes.txt — entry under v0.6.0
  • README.md — mark iteri2/iteri2Async and mapi2/mapi2Async as ✅

Implementation notes

The implementations follow the manual enumerator-loop pattern used by zip/zip3 (and the pending map2/iter2 in PR #322). This is independent of PR #322 — these functions can be merged in any order.

For mapi2Async, an explicit upcast :> Task<_> is needed on the mapper call to help the F# compiler resolve the Bind overload (same pattern needed when using #Task<_> inside a taskSeq block without going through the Action DU).

AI Disclosure

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

Test Status

Build: succeeded (Release configuration, netstandard2.1)
Tests: 4651 passed, 2 skipped (existing skips), 0 failed — full suite
Formatting:dotnet fantomas . --check passes

Generated by Repo Assist ·

To install this agentic workflow, run

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

Implements the indexed-pair variants from the README roadmap:
TaskSeq.iteri2 : (int -> 'T -> 'U -> unit) -> TaskSeq<'T> -> TaskSeq<'U> -> Task<unit>
TaskSeq.iteri2Async : (int -> 'T -> 'U -> #Task<unit>) -> TaskSeq<'T> -> TaskSeq<'U> -> Task<unit>
TaskSeq.mapi2 : (int -> 'T -> 'U -> 'V) -> TaskSeq<'T> -> TaskSeq<'U> -> TaskSeq<'V>
TaskSeq.mapi2Async : (int -> 'T -> 'U -> #Task<'V>) -> TaskSeq<'T> -> TaskSeq<'U> -> TaskSeq<'V>
Semantics: iteration stops at the shorter sequence (matching zip/map2/iter2).
Files changed:
- TaskSeqInternal.fs: iteri2, iteri2Async, mapi2, mapi2Async implementations
- TaskSeq.fs: public static members
- TaskSeq.fsi: XML-documented signatures after iteriAsync and mapiAsync
- TaskSeq.Iteri2Mapi2.Tests.fs: new test file
- FSharp.Control.TaskSeq.Test.fsproj: add test file reference
- README.md: mark iteri2/iteri2Async and mapi2/mapi2Async as implemented
- release-notes.txt: add entry under v0.6.0
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Sign up for freeto 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.

1 participant

@dsyme