Skip to content

[Repo Assist] feat: add TaskSeq.map2, map2Async, iter2, iter2Async (124 tests)#322

Draft
github-actions[bot] wants to merge 2 commits intomainfrom
repo-assist/feat-map2-iter2-2026-03-e776df67506f52b6
Draft

[Repo Assist] feat: add TaskSeq.map2, map2Async, iter2, iter2Async (124 tests)#322
github-actions[bot] wants to merge 2 commits intomainfrom
repo-assist/feat-map2-iter2-2026-03-e776df67506f52b6

Conversation

@github-actions
Copy link
Contributor

@github-actions github-actions bot commented Mar 9, 2026

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

Implements the first batch of '2'-functions from the README roadmap (exists2 / map2 / fold2 / iter2 and related), covering the most commonly used pair:

TaskSeq.iter2      : ('T -> 'U -> unit)        -> TaskSeq<'T> -> TaskSeq<'U> -> Task(unit)
TaskSeq.iter2Async : ('T -> 'U -> #Task(unit)) -> TaskSeq<'T> -> TaskSeq<'U> -> Task(unit)
TaskSeq.map2       : ('T -> 'U -> 'V)          -> TaskSeq<'T> -> TaskSeq<'U> -> TaskSeq<'V>
TaskSeq.map2Async  : ('T -> 'U -> #Task<'V>)   -> TaskSeq<'T> -> TaskSeq<'U> -> TaskSeq<'V>

Semantics (matching zip): when the two input sequences have different lengths, iteration stops at the shorter sequence — excess elements in the longer sequence are silently ignored.

Files changed

  • src/FSharp.Control.TaskSeq/TaskSeqInternal.fsiter2, iter2Async, map2, map2Async implementations; placed adjacent to iter and map respectively
  • src/FSharp.Control.TaskSeq/TaskSeq.fs — wrapper static members
  • src/FSharp.Control.TaskSeq/TaskSeq.fsi — public signature with XML doc; placed after iteriAsync and mapiAsync
  • src/FSharp.Control.TaskSeq.Test/TaskSeq.Map2Iter2.Tests.fs124 new tests: null checks, empty sequences, truncation, type mixing, side-effect sequences, immutable variants
  • 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 iter2/iter2Async and map2/map2Async as ✅ in the table; update checklist

Implementation notes

The implementations follow the exact same pattern as zip/zip3 (manual enumerator loop, let mutable go = true, stop when either sequence is exhausted). This keeps them consistent with the existing codebase rather than layering on top of zip.

map2/map2Async return a lazy taskSeq { ... } (no allocation until enumerated). iter2/iter2Async return an eager task { ... } that exhausts both sequences immediately, matching iter behaviour.

AI Disclosure

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

Test Status

Build: succeeded (Release configuration, netstandard2.1)
Tests: 4654 passed, 2 skipped (existing skips), 0 failed — full suite
New tests: 124 tests in TaskSeq.Map2Iter2.Tests.fs
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 first batch of '2'-functions from the README roadmap:

- TaskSeq.iter2  : apply a side-effecting action to pairs of elements
- TaskSeq.iter2Async : async variant of iter2
- TaskSeq.map2   : build a new TaskSeq by mapping pairs of elements
- TaskSeq.map2Async  : async variant of map2

All four functions stop at the shorter sequence (matching zip semantics).
Includes 124 new tests in TaskSeq.Map2Iter2.Tests.fs.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

0 participants