Skip to content

[Repo Assist] feat: add exists, forall, choose to LazyList module#253

Open
github-actions[bot] wants to merge 2 commits intomasterfrom
repo-assist/improve-lazylist-module-functions-2026-03-15-93c4a72d3a8894d4
Open

[Repo Assist] feat: add exists, forall, choose to LazyList module#253
github-actions[bot] wants to merge 2 commits intomasterfrom
repo-assist/improve-lazylist-module-functions-2026-03-15-93c4a72d3a8894d4

Conversation

@github-actions
Copy link
Contributor

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

Summary

LazyList was missing three common collection functions available in FSharp.Collections.List and Seq:

Function Description
LazyList.exists Returns true if any element satisfies the predicate (short-circuits on first match)
LazyList.forall Returns true if all elements satisfy the predicate (short-circuits on first mismatch)
LazyList.choose Applies an option-returning function; lazily yields Some values, skipping None

exists and forall are strict predicates: they traverse the list up to the first match/mismatch. choose follows the same lazy evaluation pattern as filter — the result list defers evaluation until consumed. This means choose works correctly on infinite lazy lists (only evaluates elements up to the point consumed).

Both LazyList.fs and LazyList.fsi are updated. The public signatures use labelled parameters consistent with the rest of the .fsi file.

Contributes to #152 (Align Collection Module functions with FSharp.Collections).

Test Status

✅ Build succeeded (0 errors, 31 warnings — all pre-existing)
dotnet test — 766 passed, 0 failed, 6 skipped (pre-existing skips)
✅ Fantomas formatting check passed

9 new tests covering:

  • exists true/false/empty cases
  • forall true/false/empty cases
  • choose keeping Some values, all-None case, laziness verification

Generated by Repo Assist ·

To install this agentic workflow, run

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

LazyList was missing three common collection functions that are present
in FSharp.Collections.List and Seq:

- exists: returns true if any element satisfies the predicate (short-circuits)
- forall: returns true if all elements satisfy the predicate (short-circuits)
- choose: applies an option-returning function; lazily yields Some values

exists and forall are strict (traverse the list up to the first match/mismatch).
choose follows the same lazy evaluation pattern as filter: evaluation is deferred
until the returned list is consumed.

Both LazyList.fs and LazyList.fsi updated; 9 new tests added, all passing.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds the missing exists, forall, and choose functions to the LazyList module to better align FSharpx.Collections with standard F# collection APIs (per #152), including public signatures and tests.

Changes:

  • Added LazyList.exists and LazyList.forall with short-circuiting traversal semantics.
  • Added LazyList.choose, producing a lazily-evaluated filtered/mapped LazyList.
  • Added unit tests for the new APIs (finite/empty cases plus a basic laziness scenario for choose).

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 2 comments.

File Description
tests/FSharpx.Collections.Tests/LazyListTests.fs Adds new tests for exists, forall, and choose
src/FSharpx.Collections/LazyList.fsi Exposes new LazyList public signatures with XML docs
src/FSharpx.Collections/LazyList.fs Implements exists, forall, and choose

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

You can also share your feedback on Copilot code review. Take the survey.


let chosen = LazyList.choose (fun x -> if x % 2 = 0 then Some x else None) ll
let first = LazyList.head chosen
Expect.equal "choose lazy first" 2 first
Comment on lines +537 to +545
test "exists returns true when element satisfies predicate" {
let ll = LazyList.ofList [ 1; 2; 3; 4; 5 ]
Expect.isTrue "exists" (LazyList.exists (fun x -> x = 3) ll)
}

test "exists returns false when no element satisfies predicate" {
let ll = LazyList.ofList [ 1; 2; 3; 4; 5 ]
Expect.isFalse "exists" (LazyList.exists (fun x -> x = 6) ll)
}
@dsyme dsyme marked this pull request as ready for review March 16, 2026 13:45
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