Skip to content

Commit

Permalink
haddock tweaks
Browse files Browse the repository at this point in the history
  • Loading branch information
mitchellwrosen committed Jan 13, 2024
1 parent d56a163 commit af2450e
Show file tree
Hide file tree
Showing 3 changed files with 23 additions and 66 deletions.
33 changes: 22 additions & 11 deletions queues.cabal
Original file line number Diff line number Diff line change
Expand Up @@ -19,20 +19,31 @@ description:
* Okasaki, Chris. "Simple and efficient purely functional queues and deques." /Journal of functional programming/ 5.4 (1995): 583-592.
* Okasaki, Chris. /Purely Functional Data Structures/. Diss. Princeton University, 1996.
.
This package provides two queue variants, whose salient API differences are summarized in the following table:
A queue has a \"back\" where new elements are enqueued, and a \"front\" where elements are dequeued in the order that
they were enqueued (last in, first out).
.
+-----------------+----------------------+--------------------+
| | @"EphemeralQueue"@ | @"Queue"@ |
+=================+======================+====================+
| @enqueue@ | \(\mathcal{O}(1)\) | \(\mathcal{O}(1)\) |
+-----------------+----------------------+--------------------+
| @dequeue@ | \(\mathcal{O}(1)^*\) | \(\mathcal{O}(1)\) |
+-----------------+----------------------+--------------------+
The queues provided in this library also support an \"enqueue at front\" operation, because the underlying
representations happen to support it, so you might technically refer to these data structures as
/output-restricted deques/.
.
* \(^*\) Amortized, under ephemeral usage only.
In this library, it is helpful to think of the \"front\" being on the /left/, because (though the direction is
arbitrary) we are consistent throughout, where it matters:
.
To see a rough performance comparison between the data structures, click into an individual module. Always benchmark
your own code for accurate numbers.
* List conversion functions associate the head of a list with the front of a queue.
* The append operator @xs <> ys@ creates a queue with @xs@ in front of @ys@.
* The `Show` instances draw the front of the queue on the left.
.
Under \"ephemeral\" (or \"single-threaded\", or \"linear\") usage, wherein one does not need to refer to an old
version of a data structure after mutating it:
.
* @EphemeralQueue@ is __2.5x faster__ than and __allocates 0.50x as much__ memory as @Queue@.
* @Queue@ is __2.6x faster__ than and __allocates 0.40x as much__ memory as @Seq@ (from @containers@).
.
(These numbers vary from benchmark to benchmark and machine to machine. Always perform your own experiments!)
.
While it is certainly common to use a queue ephemerally, it is unusual for a Haskell data structure to require
ephemeral usage to achieve its stated bounds. A refactoring or change in requirements might cause surprising changes
in performance. That is why @EphemeralQueue@ has a longer name and module name. When in doubt, use @Queue@.

extra-doc-files:
CHANGELOG.md
Expand Down
26 changes: 0 additions & 26 deletions src/Queue.hs
Original file line number Diff line number Diff line change
Expand Up @@ -2,32 +2,6 @@
--
-- * Okasaki, Chris. \"Simple and efficient purely functional queues and deques.\" /Journal of functional programming/ 5.4 (1995): 583-592.
-- * Okasaki, Chris. /Purely Functional Data Structures/. Diss. Princeton University, 1996.
--
-- A queue can be thought to have a \"back\" where new elements are enqueued, and a \"front\" where elements are
-- dequeued in the order that they were enqueued.
--
-- This queue also supports a \"enqueue at front\" operation, because the underlying representation happens to trivially
-- support it. (For a variant that also supports a \"dequeue from back\" operation, see "RealTimeDeque".
--
-- In this implementation, it is more helpful to think of the \"front\" being on the /left/, because (though the
-- decision is arbitrary) we are consistent throughout, where it matters:
--
-- * List conversion functions associate the head of a list with the front of a queue.
-- * The append operator @xs <> ys@ creates a queue with @xs@ in front of @ys@.
--
-- Performance comparison to other types:
--
-- +---+------------------------------+------------------+
-- | | @Queue@ | |
-- +===+==============================+==================+
-- | ✘ | is @2.50x@ slower than | "EphemeralQueue" |
-- +---+------------------------------+ |
-- | ✘ | allocates @2.10x@ as much as | |
-- +---+------------------------------+------------------+
-- | ✔ | is @2.50x@ faster than | @Seq@ |
-- +---+------------------------------+ |
-- | ✔ | allocates @0.40x@ as much as | |
-- +---+------------------------------+------------------+
module Queue
( -- * Queue
Queue (Empty, Front),
Expand Down
30 changes: 1 addition & 29 deletions src/Queue/Ephemeral.hs
Original file line number Diff line number Diff line change
Expand Up @@ -2,32 +2,6 @@
--
-- * Okasaki, Chris. \"Simple and efficient purely functional queues and deques.\" /Journal of functional programming/ 5.4 (1995): 583-592.
-- * Okasaki, Chris. /Purely Functional Data Structures/. Diss. Princeton University, 1996.
--
-- A queue can be thought to have a \"back\" where new elements are enqueued, and a \"front\" where elements are
-- dequeued in the order that they were enqueued.
--
-- This queue also supports a \"enqueue at front\" operation, because the underlying representation happens to trivially
-- support it. (For a variant that also supports a \"dequeue from back\" operation, see "RealTimeDeque".
--
-- In this implementation, it is more helpful to think of the \"front\" being on the /left/, because (though the
-- decision is arbitrary) we are consistent throughout, where it matters:
--
-- * List conversion functions associate the head of a list with the front of a queue.
-- * The append operator @xs <> ys@ creates a queue with @xs@ in front of @ys@.
--
-- Performance comparison to other types:
--
-- +---+------------------------------+---------+
-- | | @EphemeralQueue@ | |
-- +===+==============================+=========+
-- | ✔ | is @2.50x@ faster than | "Queue" |
-- +---+------------------------------+ |
-- | ✔ | allocates @0.50x@ as much as | |
-- +---+------------------------------+---------+
-- | ✔ | is @6.30x@ faster than | @Seq@ |
-- +---+------------------------------+ |
-- | ✔ | allocates @0.20x@ as much as | |
-- +---+------------------------------+---------+
module Queue.Ephemeral
( -- * Ephemeral queue
EphemeralQueue (Empty, Front),
Expand Down Expand Up @@ -65,7 +39,7 @@ import Prelude hiding (foldMap, length, map, span, traverse)
------------------------------------------------------------------------------------------------------------------------
-- Queue type and instances

-- | A queue data structure with \(\mathcal{O}(1)^\) (amortized under ephemeral usage only) operations.
-- | A queue data structure with \(\mathcal{O}(1)^*\) (amortized under ephemeral usage only) operations.
data EphemeralQueue a
= Q [a] [a]
deriving stock (Functor)
Expand Down Expand Up @@ -120,11 +94,9 @@ instance Traversable EphemeralQueue where
------------------------------------------------------------------------------------------------------------------------
-- Patterns

-- | An empty queue.
pattern Empty :: EphemeralQueue a
pattern Empty <- (dequeue -> Nothing)

-- | The front of a queue, and the rest of it.
pattern Front :: a -> EphemeralQueue a -> EphemeralQueue a
pattern Front x xs <- (dequeue -> Just (x, xs))

Expand Down

0 comments on commit af2450e

Please sign in to comment.