amenzwa / pfd

This project reimplements in Elm the data structures presented in the book "Purely Functional Data Structures" by Professor Okasaki (1999). Okasaki first published this material in 1996 in his PhD dissertation at CMU. The book provides Standard ML and Haskell implementations.
MIT License
38 stars 1 forks source link

Queue.LfrQueue - unexpected size after adding same item twice #3

Closed Janiczek closed 1 year ago

Janiczek commented 1 year ago

I'm not sure this is expected (are you not allowed to enqueue the same item twice?)

Minimal example:

empty |> enq 0 |> enq 0 |> size
--> 3

Trying it out in elm-repl:

> import Queue.LfrQueue exposing (..)
> empty |> enq 0 |> enq 0 |> size
3 : Int
> empty |> enq 0 |> enq 0
([0],[0,0]) : Queue number
>

The test that found this:

fuzz (Fuzz.list Fuzz.int) "empty+enq+size: behaves like stdlib queue" <|
    \items ->
        let
            lfrQueue =
                List.foldl enq empty items

            stdlibQueue =
                List.foldl (::) [] items
        in
        size lfrQueue
            |> Expect.equal (List.length stdlibQueue)
Janiczek commented 1 year ago

I'm guessing this should use front and rear once each instead of using front twice https://github.com/amenzwa/pfd/blob/main/src/Queue/LfrQueue.elm#L34

amenzwa commented 1 year ago

Martin, Okasaki's Standard ML implementation for left-right queue (which he calls BatchedQueue) on p.43 is fun snoc ((f, r), x) = checkf (f, x::r), which I mistranslated into Elm as enq x ( f, r ) = checkF ( f, x :: f ). The correct translation is enq x ( f, r ) = checkF ( f, x :: r ). I just fixed this bug, and updated the test case, too.

Thank you so much for finding this bug.