Skip to content

[Repo Assist] feat: add map, filter, iter, exists, forall, toList, toArray to Queue and Deque#241

Open
github-actions[bot] wants to merge 2 commits intomasterfrom
repo-assist/improve-queue-deque-functions-20260310-abe469ac1b3fa769
Open

[Repo Assist] feat: add map, filter, iter, exists, forall, toList, toArray to Queue and Deque#241
github-actions[bot] wants to merge 2 commits intomasterfrom
repo-assist/improve-queue-deque-functions-20260310-abe469ac1b3fa769

Conversation

@github-actions
Copy link
Contributor

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

Adds seven commonly used collection functions to the Queue and Deque modules. Partially addresses #152 (Align Collection Module functions with FSharp.Collections).

Changes

New functions (Queue and Deque)

Function Complexity Description
map f q O(n) Transform each element, returning a Queue/Deque
filter pred q O(n) Keep only elements satisfying the predicate
iter f q O(n) Apply a side-effecting function to each element (FIFO order)
exists pred q O(n) Test whether any element satisfies a predicate
forall pred q O(n) Test whether all elements satisfy a predicate
toList q O(n) Convert to list in FIFO order
toArray q O(n) Convert to array in FIFO order

All functions preserve FIFO element order. Signatures added to .fsi files. 21 new tests added.

Implementation notes

Queue.map directly maps over the internal front and rBack lists, preserving the queue structure without any rebuilding — very efficient.

Queue.filter handles the invariant that front should not be empty for a non-empty queue: if filtering removes all front elements, List.rev rBack becomes the new front.

Deque.map similarly maps directly over both internal lists. Deque.filter is simpler since Deque tolerates an empty front (it falls back to rBack).

exists and forall can check rBack in any order (order only matters for iter, toList, toArray).

Test Status

All 731 tests pass (6 pre-existing ptest skips unrelated to this PR):

Passed! - Failed: 0, Passed: 731, Skipped: 6, Total: 737

Generated by Repo Assist ·

To install this agentic workflow, run

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

… and Deque modules

Adds commonly needed collection functions to Queue and Deque that
were present in F# List but missing from these modules. Addresses
part of #152 (Align Collection Module functions with FSharp.Collections).

New functions for both Queue and Deque:
- map       : transform each element, returning the same collection type
- filter    : keep elements matching a predicate
- iter      : apply a side-effecting function to each element (FIFO order)
- exists    : test whether any element satisfies a predicate
- forall    : test whether all elements satisfy a predicate
- toList    : convert to list in FIFO order
- toArray   : convert to array in FIFO order

All seven functions are O(n) and preserve FIFO element order.
21 new tests added (QueueTest and DequeTest), all passing.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
github-actions bot added a commit that referenced this pull request Mar 13, 2026
… tests

Adds six new module-level functions to DList, mirroring the functions
added to Queue and Deque in #241, and further addressing #152.

- DList.map: transforms all elements using a function
- DList.filter: retains elements matching a predicate
- DList.iter: applies an action to each element in order
- DList.exists: short-circuit check if any element matches
- DList.forall: short-circuit check if all elements match
- DList.toArray: returns elements as an array

map and filter are implemented via foldBack so they build a DList
directly (preserving the length invariant). iter/exists/forall/toArray
delegate to the IEnumerable<'T> implementation for correct short-circuit
behaviour.

Also adds 21 new tests: 14 unit tests and 7 property-based tests that
verify results match standard List/Array equivalents.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@gdziadkiewicz gdziadkiewicz self-assigned this Mar 14, 2026
@gdziadkiewicz gdziadkiewicz requested review from Copilot and gdziadkiewicz and removed request for Copilot March 14, 2026 13:10
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 FSharp.Collections-aligned collection helpers to Queue and Deque, expanding their module APIs with common traversal/transformation/conversion functions while preserving the collections’ logical ordering.

Changes:

  • Added toList, toArray, map, filter, iter, exists, forall to Queue and Deque implementations.
  • Exposed the new functions in the corresponding .fsi signature files.
  • Added unit tests covering the new APIs (order preservation and basic semantics).

Reviewed changes

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

Show a summary per file
File Description
src/FSharpx.Collections/Queue.fs Implements the seven new Queue module functions.
src/FSharpx.Collections/Queue.fsi Adds public signatures/docs for the new Queue functions (also includes spacing/formatting changes).
src/FSharpx.Collections/Deque.fs Implements the seven new Deque module functions.
src/FSharpx.Collections/Deque.fsi Adds public signatures/docs for the new Deque functions (also includes spacing/formatting changes).
tests/FSharpx.Collections.Tests/QueueTest.fs Adds tests for new Queue APIs (FIFO order and basic behavior).
tests/FSharpx.Collections.Tests/DequeTest.fs Adds tests for new Deque APIs (order and basic behavior).

💡 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.


///O(n). Returns true if any element of the queue satisfies the given predicate.
let exists (predicate: 'T -> bool) (q: Queue<'T>) : bool =
List.exists predicate q.front || List.exists predicate q.rBack
Copy link
Collaborator

Choose a reason for hiding this comment

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

Hmmmmm


///O(n). Returns true if all elements of the queue satisfy the given predicate.
let forall (predicate: 'T -> bool) (q: Queue<'T>) : bool =
List.forall predicate q.front && List.forall predicate q.rBack
Comment on lines +270 to +274
List.exists predicate q.front || List.exists predicate q.rBack

///O(n). Returns true if all elements of the deque satisfy the given predicate.
let forall (predicate: 'T -> bool) (q: Deque<'T>) : bool =
List.forall predicate q.front && List.forall predicate q.rBack
Comment on lines +270 to +274
List.exists predicate q.front || List.exists predicate q.rBack

///O(n). Returns true if all elements of the deque satisfy the given predicate.
let forall (predicate: 'T -> bool) (q: Deque<'T>) : bool =
List.forall predicate q.front && List.forall predicate q.rBack
Comment on lines +49 to 53
val (|Cons|Nil|): Queue<'T> -> Choice<('T * Queue<'T>), unit>

///O(1). Returns a new queue with the element added to the end. (enqueue)
val inline conj : 'T -> Queue<'T> -> Queue<'T>
val inline conj: 'T -> Queue<'T> -> Queue<'T>

Comment on lines +69 to 88
val (|Cons|Nil|): Deque<'T> -> Choice<('T * Deque<'T>), unit>

val (|Conj|Nil|) : Deque<'T> -> Choice<(Deque<'T> * 'T),unit>
val (|Conj|Nil|): Deque<'T> -> Choice<(Deque<'T> * 'T), unit>

///O(1). Returns a new deque with the element added to the end.
val inline conj : 'T -> Deque<'T> -> Deque<'T>
val inline conj: 'T -> Deque<'T> -> Deque<'T>

///O(1). Returns a new deque with the element added to the beginning.
val inline cons : 'T -> Deque<'T> -> Deque<'T>
val inline cons: 'T -> Deque<'T> -> Deque<'T>

///O(1). Returns deque of no elements.
[<GeneralizableValue>]
val empty<'T> : Deque<'T>

///O(n). Applies a function to each element of the deque, threading an accumulator argument through the computation, left to right
val fold : ('State -> 'T -> 'State) -> 'State -> Deque<'T> -> 'State
val fold: ('State -> 'T -> 'State) -> 'State -> Deque<'T> -> 'State

///O(n). Applies a function to each element of the deque, threading an accumulator argument through the computation, right to left
val foldBack : ('T -> 'State -> 'State) -> Deque<'T> -> 'State -> 'State
val foldBack: ('T -> 'State -> 'State) -> Deque<'T> -> 'State -> 'State

let q = Deque.ofSeq [ 1; 2; 3; 4; 5 ]
Expect.equal "filter order" [ 1; 3; 5 ] (Deque.filter (fun x -> x % 2 <> 0) q |> Deque.toList)
}

@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.

2 participants