Skip to content

[Repo Assist] Add AsyncSeq.splitAt — split at index, returning first N as array and remainder as AsyncSeq#267

Merged
dsyme merged 3 commits intomainfrom
repo-assist/improve-splitat-cc1b1026bf3ab37b
Mar 7, 2026
Merged

[Repo Assist] Add AsyncSeq.splitAt — split at index, returning first N as array and remainder as AsyncSeq#267
dsyme merged 3 commits intomainfrom
repo-assist/improve-splitat-cc1b1026bf3ab37b

Conversation

@github-actions
Copy link
Contributor

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

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

Summary

Adds AsyncSeq.splitAt, mirroring Seq.splitAt:

val splitAt : count:int -> source:AsyncSeq<'T> -> Async<'T array * AsyncSeq<'T>>

Returns an Async computation that yields:

  • the first count elements as a 'T array
  • the remaining elements as a new AsyncSeq<'T>

The source is enumerated once — the underlying enumerator is shared across the split boundary. The returned remainder AsyncSeq lazily produces remaining elements and disposes the enumerator when fully consumed.

Usage Example

let source = asyncSeq { yield 1; yield 2; yield 3; yield 4; yield 5 }
let first, rest = AsyncSeq.splitAt 3 source |> Async.RunSynchronously
// first: [| 1; 2; 3 |]
// rest:  asyncSeq yielding 4, 5

let restArr = rest |> AsyncSeq.toArrayAsync |> Async.RunSynchronously
// [| 4; 5 |]
```

Edge cases handled:
- `count = 0` → empty first array, full remainder
- `count >= length` → all elements in first array, empty remainder
- empty source → empty first array, empty remainder
- negative `count` → raises `ArgumentException`

## Implementation Notes

- Placed after `tail` in `AsyncSeq.fs`, adjacent to `skip`/`take`/`tail`
- Manual enumerator management (no `use`) allows the enumerator to be handed off to the remainder `AsyncSeq`; `try/finally` in the `asyncSeq` block ensures proper disposal
- Signature added to `AsyncSeq.fsi`
- `RELEASE_NOTES.md` updated with a 4.7.0 entry

## Test Status

✅ All **293 tests pass** (287 pre-existing + **6 new tests** for `splitAt`):

```
Passed!  - Failed: 0, Passed: 293, Skipped: 0, Total: 293

New tests cover: normal split, count=0, count≥length, empty source, exact split, and negative count.

Generated by Repo Assist ·

To install this agentic workflow, run

gh aw add githubnext/agentics/workflows/repo-assist.md@10f087607af87e4e89439161f1e5d4724235f396

… array and remainder as AsyncSeq

Mirrors Seq.splitAt. Source is enumerated once; remainder is produced lazily.
6 new tests; 293/293 total pass.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@dsyme dsyme marked this pull request as ready for review March 7, 2026 19:00
@dsyme dsyme merged commit ced9d2e into main Mar 7, 2026
1 check passed
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.

1 participant