Skip to content

[Repo Assist] feat: add fold, foldBack, find, tryFind, pick, tryPick, filter, choose, partition, scan, indexed, unzip, pairwise, groupBy, max, min to NonEmptyList#259

Merged
gdziadkiewicz merged 8 commits into
masterfrom
repo-assist/improve-nonemptylist-funcs-174-88c4374885613a30
May 16, 2026
Merged

[Repo Assist] feat: add fold, foldBack, find, tryFind, pick, tryPick, filter, choose, partition, scan, indexed, unzip, pairwise, groupBy, max, min to NonEmptyList#259
gdziadkiewicz merged 8 commits into
masterfrom
repo-assist/improve-nonemptylist-funcs-174-88c4374885613a30

Conversation

@github-actions
Copy link
Copy Markdown
Contributor

@github-actions github-actions Bot commented Apr 30, 2026

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

Closes #174

Summary

Adds 16 missing standard List-equivalent functions to the NonEmptyList module, addressing the long-standing gap identified in #174.

Functions Added

Function Return Type Notes
fold 'State Left fold, like List.fold
foldBack 'State Right fold, like List.foldBack
find 'T Raises KeyNotFoundException if not found
tryFind 'T option Returns Some x for the first element where predicate returns true; None if none match
pick 'U Raises KeyNotFoundException if chooser never returns Some
tryPick 'U option Returns the first Some result from chooser, or None
filter 'T list Returns plain list (result can be empty)
choose 'U list Filter + map; returns plain list
partition 'T list * 'T list Both halves may be empty
indexed NonEmptyList<int * 'T> Pairs each element with its index
unzip NonEmptyList<'T1> * NonEmptyList<'T2> Splits a list of pairs
pairwise ('T * 'T) list Adjacent pairs; empty for singleton
scan NonEmptyList<'State> Always non-empty (includes initial state)
groupBy NonEmptyList<'Key * NonEmptyList<'T>> Non-empty; each group is non-empty
max 'T Safe since list is always non-empty
min 'T Safe since list is always non-empty

Design principle: functions that cannot produce an empty result return NonEmptyList<_>; functions that can produce an empty result return a plain 'T list.

Tests

18 property-based tests added to NonEmptyListTests.fs, verifying consistency with List module equivalents.

Test Status

✅ All tests pass on ubuntu-latest via dotnet test. Fantomas formatting check passes.

…can, indexed, unzip, pairwise, groupBy, max, min to NonEmptyList (addresses #174)

Add 14 missing standard List-equivalent functions to the NonEmptyList module:

- fold/foldBack: thread accumulator through the list
- find/tryFind: search for elements by predicate
- filter/choose: return plain 'T list (result can be empty)
- partition: split into two plain lists by predicate
- scan: return NonEmptyList<'State> (always non-empty)
- indexed: return NonEmptyList<int * 'T>
- unzip: split NonEmptyList<'T1 * 'T2> into two NonEmptyLists
- pairwise: return ('T * 'T) list (may be empty for singleton)
- groupBy: return NonEmptyList<'Key * NonEmptyList<'T>>
- max/min: safe since list is always non-empty

Functions that preserve non-emptiness return NonEmptyList.
Functions that may produce empty results return plain 'T list.

Add 16 property-based tests covering all new functions.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@dsyme dsyme marked this pull request as ready for review May 13, 2026 23:37
@gdziadkiewicz gdziadkiewicz requested a review from Copilot May 15, 2026 07:43
Copy link
Copy Markdown
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

This PR fills a long-standing API gap by adding missing List-equivalent operations to NonEmptyList, while preserving the design rule that only operations guaranteed to stay non-empty return NonEmptyList<_>.

Changes:

  • Added 14 List-equivalent functions to src/FSharpx.Collections/NonEmptyList.fs (e.g., fold, find, filter, scan, groupBy, max/min).
  • Added property-based tests to validate behavior matches List equivalents in tests/FSharpx.Collections.Tests/NonEmptyListTests.fs.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.

File Description
src/FSharpx.Collections/NonEmptyList.fs Adds missing List-equivalent functions to NonEmptyList with appropriate return types (non-empty vs possibly empty).
tests/FSharpx.Collections.Tests/NonEmptyListTests.fs Adds property-based tests comparing new NonEmptyList functions against List behavior.

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

Comment thread src/FSharpx.Collections/NonEmptyList.fs Outdated
Copy link
Copy Markdown
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

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

Comment thread src/FSharpx.Collections/NonEmptyList.fs
Comment thread tests/FSharpx.Collections.Tests/NonEmptyListTests.fs
Copy link
Copy Markdown
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

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

Copilot AI and others added 2 commits May 16, 2026 07:10
@gdziadkiewicz gdziadkiewicz changed the title [Repo Assist] feat: add fold, foldBack, find, tryFind, filter, choose, partition, scan, indexed, unzip, pairwise, groupBy, max, min to NonEmpt [Content truncated due to length] [Repo Assist] feat: add fold, foldBack, find, tryFind, pick, tryPick, filter, choose, partition, scan, indexed, unzip, pairwise, groupBy, max, min to NonEmptyList May 16, 2026
@gdziadkiewicz gdziadkiewicz merged commit 4d73158 into master May 16, 2026
4 checks 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.

Fill gap of functions between List and NonEmptyList

4 participants