Skip to content

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

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

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

Conversation

@github-actions

Copy link
Copy Markdown
Contributor

🤖 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 freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

automationenhancementNew feature or requestrepo-assist

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

@dsyme