Skip to content

Commit

Permalink
doc tweaks
Browse files Browse the repository at this point in the history
  • Loading branch information
mitchellwrosen committed Jan 13, 2024
1 parent 9b7b005 commit ee4f5e6
Show file tree
Hide file tree
Showing 3 changed files with 66 additions and 17 deletions.
2 changes: 1 addition & 1 deletion queues.cabal
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ description:
+=================+======================+====================+
| @enqueue@ | \(\mathcal{O}(1)\) | \(\mathcal{O}(1)\) |
+-----------------+----------------------+--------------------+
| @dequeue@ | \(\mathcal{O}(1)^\) | \(\mathcal{O}(1)\) |
| @dequeue@ | \(\mathcal{O}(1)^*\) | \(\mathcal{O}(1)\) |
+-----------------+----------------------+--------------------+
.
* \(^*\) Amortized, under ephemeral usage only.
Expand Down
41 changes: 33 additions & 8 deletions src/Queue.hs
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ module Queue
-- ** Initialization
empty,
singleton,
fromList,

-- * Basic interface
enqueue,
Expand All @@ -51,8 +52,7 @@ module Queue
map,
traverse,

-- * List conversions
fromList,
-- * Conversions
toList,
)
where
Expand All @@ -64,6 +64,9 @@ import GHC.Exts (Any)
import Unsafe.Coerce (unsafeCoerce)
import Prelude hiding (foldMap, length, map, span, traverse)

------------------------------------------------------------------------------------------------------------------------
-- Queue type and instances

-- | A queue data structure with \(\mathcal{O}(1)\) (worst-case) operations.
data Queue a
= Q
Expand Down Expand Up @@ -128,6 +131,9 @@ instance Traversable Queue where
traverse =
Queue.traverse

------------------------------------------------------------------------------------------------------------------------
-- Patterns

-- | An empty queue.
pattern Empty :: Queue a
pattern Empty <- (dequeue -> Nothing)
Expand All @@ -138,8 +144,9 @@ pattern Front x xs <- (dequeue -> Just (x, xs))

{-# COMPLETE Empty, Front #-}

-- Queue smart constructor.
--
------------------------------------------------------------------------------------------------------------------------
-- Internal smart constructor utils

-- `queue xs ys zs` is always called when |zs| = |xs| - |ys| + 1 (i.e. just after a enqueue or dequeue)
makeQueue :: [a] -> [a] -> Schedule -> Queue a
makeQueue xs ys = \case
Expand All @@ -153,6 +160,9 @@ rotate (NonEmptyList y ys) zs = \case
[] -> y : zs
x : xs -> x : rotate ys (y : zs) xs

------------------------------------------------------------------------------------------------------------------------
-- Initialization

-- | An empty queue.
empty :: Queue a
empty =
Expand All @@ -165,6 +175,14 @@ singleton x =
where
xs = [x]

-- | \(\mathcal{O}(1)\). Construct a queue from a list. The head of the list corresponds to the front of the queue.
fromList :: [a] -> Queue a
fromList xs =
Q xs [] (schedule xs)

------------------------------------------------------------------------------------------------------------------------
-- Basic interface

-- | \(\mathcal{O}(1)\). Enqueue an element at the back of a queue, to be dequeued last.
enqueue :: a -> Queue a -> Queue a
enqueue y (Q xs ys zs) =
Expand All @@ -176,6 +194,9 @@ dequeue = \case
Q [] _ _ -> Nothing
Q (x : xs) ys zs -> Just (x, makeQueue xs ys zs)

------------------------------------------------------------------------------------------------------------------------
-- Extended interface

-- | \(\mathcal{O}(1)\). Enqueue an element at the front of a queue, to be dequeued next.
enqueueFront :: a -> Queue a -> Queue a
enqueueFront x (Q xs ys zs) =
Expand All @@ -200,12 +221,18 @@ span p =
| p x -> go (enqueue x acc) xs
| otherwise -> (acc, queue)

------------------------------------------------------------------------------------------------------------------------
-- Queries

-- | \(\mathcal{O}(1)\). Is a queue empty?
isEmpty :: Queue a -> Bool
isEmpty = \case
Q [] _ _ -> True
_ -> False

------------------------------------------------------------------------------------------------------------------------
-- Transformations

-- | \(\mathcal{O}(n)\). Apply a function to every element in a queue.
map :: (a -> b) -> Queue a -> Queue b
map f =
Expand All @@ -216,10 +243,8 @@ traverse :: (Applicative f) => (a -> f b) -> Queue a -> f (Queue b)
traverse f =
fmap fromList . Traversable.traverse f . toList

-- | \(\mathcal{O}(1)\). Construct a queue from a list. The head of the list corresponds to the front of the queue.
fromList :: [a] -> Queue a
fromList xs =
Q xs [] (schedule xs)
------------------------------------------------------------------------------------------------------------------------
-- Conversions

-- | \(\mathcal{O}(n)\). Construct a list from a queue. The head of the list corresponds to the front of the queue.
toList :: Queue a -> [a]
Expand Down
40 changes: 32 additions & 8 deletions src/Queue/Ephemeral.hs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
-- | A queue data structure with \(\mathcal{O}(1)^\) (amortized under ephemeral usage only) operations, as described in
-- | A queue data structure with \(\mathcal{O}(1)^*\) (amortized under ephemeral usage only) operations, as described in
--
-- * 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.
Expand Down Expand Up @@ -35,6 +35,7 @@ module Queue.Ephemeral
-- ** Initialization
empty,
singleton,
fromList,

-- * Basic interface
enqueue,
Expand All @@ -51,8 +52,7 @@ module Queue.Ephemeral
map,
traverse,

-- * List conversions
fromList,
-- * Conversions
toList,
)
where
Expand All @@ -61,6 +61,9 @@ import Data.Foldable qualified as Foldable
import Data.Traversable qualified as Traversable
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.
data EphemeralQueue a
= Q [a] [a]
Expand Down Expand Up @@ -90,6 +93,9 @@ instance Traversable EphemeralQueue where
traverse =
traverse

------------------------------------------------------------------------------------------------------------------------
-- Patterns

-- | An empty queue.
pattern Empty :: EphemeralQueue a
pattern Empty <- (dequeue -> Nothing)
Expand All @@ -100,6 +106,9 @@ pattern Front x xs <- (dequeue -> Just (x, xs))

{-# COMPLETE Empty, Front #-}

------------------------------------------------------------------------------------------------------------------------
-- Initialization

-- | An empty queue.
empty :: EphemeralQueue a
empty =
Expand All @@ -110,12 +119,20 @@ singleton :: a -> EphemeralQueue a
singleton x =
Q [x] []

-- | \(\mathcal{O}(1)\). Construct a queue from a list. The head of the list corresponds to the front of the queue.
fromList :: [a] -> EphemeralQueue a
fromList xs =
Q xs []

------------------------------------------------------------------------------------------------------------------------
-- Basic interface

-- | \(\mathcal{O}(1)\). Enqueue an element at the back of a queue, to be dequeued last.
enqueue :: a -> EphemeralQueue a -> EphemeralQueue a
enqueue y (Q xs ys) =
Q xs (y : ys)

-- | \(\mathcal{O}(1)^\) front, \(\mathcal{O}(1)^\) rest. Dequeue an element from the front of a queue.
-- | \(\mathcal{O}(1)^*\) front, \(\mathcal{O}(1)^*\) rest. Dequeue an element from the front of a queue.
dequeue :: EphemeralQueue a -> Maybe (a, EphemeralQueue a)
dequeue = \case
Q [] ys ->
Expand All @@ -124,6 +141,9 @@ dequeue = \case
x : xs -> Just (x, Q xs [])
Q (x : xs) ys -> Just (x, Q xs ys)

------------------------------------------------------------------------------------------------------------------------
-- Extended interface

-- | \(\mathcal{O}(1)\). Enqueue an element at the front of a queue, to be dequeued next.
enqueueFront :: a -> EphemeralQueue a -> EphemeralQueue a
enqueueFront x (Q xs ys) =
Expand All @@ -145,12 +165,18 @@ span p =
| p x -> go (enqueue x acc) xs
| otherwise -> (acc, enqueueFront x xs)

------------------------------------------------------------------------------------------------------------------------
-- Queries

-- | \(\mathcal{O}(1)\). Is a queue empty?
isEmpty :: EphemeralQueue a -> Bool
isEmpty = \case
Q [] [] -> True
_ -> False

------------------------------------------------------------------------------------------------------------------------
-- Transformations

-- | \(\mathcal{O}(n)\). Apply a function to every element in a queue.
map :: (a -> b) -> EphemeralQueue a -> EphemeralQueue b
map =
Expand All @@ -170,10 +196,8 @@ traverse f (Q xs ys) =
[] -> pure []
z : zs -> flip (:) <$> go zs <*> f z

-- | \(\mathcal{O}(1)\). Construct a queue from a list. The head of the list corresponds to the front of the queue.
fromList :: [a] -> EphemeralQueue a
fromList xs =
Q xs []
------------------------------------------------------------------------------------------------------------------------
-- Conversions

-- | \(\mathcal{O}(n)\). Construct a list from a queue. The head of the list corresponds to the front of the queue.
toList :: EphemeralQueue a -> [a]
Expand Down

0 comments on commit ee4f5e6

Please sign in to comment.