Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
72 changes: 30 additions & 42 deletions src/BinomialQueue/Max.hs
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,6 @@ module BinomialQueue.Max (
import Prelude hiding (null, take, drop, takeWhile, dropWhile, splitAt, span, break, (!!), filter, map)

import Data.Coerce (coerce)
import Data.Bifunctor (bimap)
import qualified Data.List as List
import Data.Maybe (fromMaybe)

Expand All @@ -103,21 +102,19 @@ findMax = fromMaybe (error "Error: findMax called on empty queue") . getMax

-- | \(O(1)\). The top (maximum) element of the queue, if there is one.
getMax :: Ord a => MaxQueue a -> Maybe a
getMax (MaxQueue q) = unDown <$> MinQ.getMin q
getMax = coerce MinQ.getMin

-- | \(O(\log n)\). Deletes the maximum element. If the queue is empty, does nothing.
deleteMax :: Ord a => MaxQueue a -> MaxQueue a
deleteMax = MaxQueue . MinQ.deleteMin . unMaxQueue
deleteMax = coerce MinQ.deleteMin

-- | \(O(\log n)\). Extracts the maximum element. Throws an error on an empty queue.
deleteFindMax :: Ord a => MaxQueue a -> (a, MaxQueue a)
deleteFindMax = fromMaybe (error "Error: deleteFindMax called on empty queue") . maxView

-- | \(O(\log n)\). Extract the top (maximum) element of the sequence, if there is one.
maxView :: Ord a => MaxQueue a -> Maybe (a, MaxQueue a)
maxView (MaxQueue q) = case MinQ.minView q of
Just (Down a, q') -> Just (a, MaxQueue q')
Nothing -> Nothing
maxView = coerce MinQ.minView

-- | \(O(k \log n)\). Index (subscript) operator, starting from 0. @queue !! k@ returns the @(k+1)@th largest
-- element in the queue. Equivalent to @toDescList queue !! k@.
Expand All @@ -130,19 +127,17 @@ q !! n = toDescList q List.!! n
-- | 'takeWhile', applied to a predicate @p@ and a queue @queue@, returns the
-- longest prefix (possibly empty) of @queue@ of elements that satisfy @p@.
takeWhile :: Ord a => (a -> Bool) -> MaxQueue a -> [a]
takeWhile p = coerce . MinQ.takeWhile (p . unDown) . unMaxQueue
takeWhile = coerce MinQ.takeWhile

-- | 'dropWhile' @p queue@ returns the queue remaining after 'takeWhile' @p queue@.
dropWhile :: Ord a => (a -> Bool) -> MaxQueue a -> MaxQueue a
dropWhile p = MaxQueue . MinQ.dropWhile (p . unDown) . unMaxQueue
dropWhile = coerce MinQ.dropWhile

-- | 'span', applied to a predicate @p@ and a queue @queue@, returns a tuple where
-- first element is longest prefix (possibly empty) of @queue@ of elements that
-- satisfy @p@ and second element is the remainder of the queue.
span :: Ord a => (a -> Bool) -> MaxQueue a -> ([a], MaxQueue a)
span p (MaxQueue queue)
| (front, rear) <- MinQ.span (p . unDown) queue
= (coerce front, MaxQueue rear)
span = coerce MinQ.span

-- | 'break', applied to a predicate @p@ and a queue @queue@, returns a tuple where
-- first element is longest prefix (possibly empty) of @queue@ of elements that
Expand All @@ -159,81 +154,75 @@ take n = List.take n . toDescList
-- | \(O(k \log n)\). 'drop' @k@, applied to a queue @queue@, returns @queue@ with the greatest @k@ elements deleted,
-- or an empty queue if @k >= 'size' queue@.
drop :: Ord a => Int -> MaxQueue a -> MaxQueue a
drop n (MaxQueue queue) = MaxQueue (MinQ.drop n queue)
drop = coerce MinQ.drop

-- | \(O(k \log n)\). Equivalent to @('take' k queue, 'drop' k queue)@.
splitAt :: Ord a => Int -> MaxQueue a -> ([a], MaxQueue a)
splitAt n (MaxQueue queue)
| (l, r) <- MinQ.splitAt n queue
= (coerce l, MaxQueue r)
splitAt = coerce MinQ.splitAt

-- | \(O(n)\). Returns the queue with all elements not satisfying @p@ removed.
filter :: Ord a => (a -> Bool) -> MaxQueue a -> MaxQueue a
filter p = MaxQueue . MinQ.filter (p . unDown) . unMaxQueue
filter = coerce MinQ.filter

-- | \(O(n)\). Returns a pair where the first queue contains all elements satisfying @p@, and the second queue
-- contains all elements not satisfying @p@.
partition :: Ord a => (a -> Bool) -> MaxQueue a -> (MaxQueue a, MaxQueue a)
partition p = go . unMaxQueue
where
go queue
| (l, r) <- MinQ.partition (p . unDown) queue
= (MaxQueue l, MaxQueue r)
partition = coerce MinQ.partition

-- | \(O(n)\). Creates a new priority queue containing the images of the elements of this queue.
-- Equivalent to @'fromList' . 'Data.List.map' f . toList@.
map :: Ord b => (a -> b) -> MaxQueue a -> MaxQueue b
map f = MaxQueue . MinQ.map (fmap f) . unMaxQueue
map = coerce MinQ.map

{-# INLINE toList #-}
-- | \(O(n \log n)\). Returns the elements of the priority queue in descending order. Equivalent to 'toDescList'.
--
-- If the order of the elements is irrelevant, consider using 'toListU'.
toList :: Ord a => MaxQueue a -> [a]
toList = coerce . MinQ.toAscList . unMaxQueue
toList = coerce MinQ.toAscList

toAscList :: Ord a => MaxQueue a -> [a]
toAscList = coerce . MinQ.toDescList . unMaxQueue
toAscList = coerce MinQ.toDescList

toDescList :: Ord a => MaxQueue a -> [a]
toDescList = coerce . MinQ.toAscList . unMaxQueue
toDescList = coerce MinQ.toAscList

-- | \(O(n \log n)\). Performs a right fold on the elements of a priority queue in descending order.
foldrDesc :: Ord a => (a -> b -> b) -> b -> MaxQueue a -> b
foldrDesc f z (MaxQueue q) = MinQ.foldrAsc (flip (foldr f)) z q
foldrDesc f z (MaxQueue q) = MinQ.foldrAsc (coerce f) z q

-- | \(O(n \log n)\). Performs a right fold on the elements of a priority queue in ascending order.
foldrAsc :: Ord a => (a -> b -> b) -> b -> MaxQueue a -> b
foldrAsc f z (MaxQueue q) = MinQ.foldrDesc (flip (foldr f)) z q
foldrAsc f z (MaxQueue q) = MinQ.foldrDesc (coerce f) z q

-- | \(O(n \log n)\). Performs a left fold on the elements of a priority queue in ascending order.
foldlAsc :: Ord a => (b -> a -> b) -> b -> MaxQueue a -> b
foldlAsc f z (MaxQueue q) = MinQ.foldlDesc (foldl f) z q
foldlAsc f z (MaxQueue q) = MinQ.foldlDesc (coerce f) z q

-- | \(O(n \log n)\). Performs a left fold on the elements of a priority queue in descending order.
foldlDesc :: Ord a => (b -> a -> b) -> b -> MaxQueue a -> b
foldlDesc f z (MaxQueue q) = MinQ.foldlAsc (foldl f) z q
foldlDesc f z (MaxQueue q) = MinQ.foldlAsc (coerce f) z q

{-# INLINE fromAscList #-}
-- | \(O(n)\). Constructs a priority queue from an ascending list. /Warning/: Does not check the precondition.
fromAscList :: [a] -> MaxQueue a
fromAscList = MaxQueue . MinQ.fromDescList . coerce
fromAscList = coerce MinQ.fromDescList

{-# INLINE fromDescList #-}
-- | \(O(n)\). Constructs a priority queue from a descending list. /Warning/: Does not check the precondition.
fromDescList :: [a] -> MaxQueue a
fromDescList = MaxQueue . MinQ.fromAscList . coerce
fromDescList = coerce MinQ.fromAscList

fromList :: Ord a => [a] -> MaxQueue a
fromList = MaxQueue . MinQ.fromList . coerce
fromList = coerce MinQ.fromList

-- | Equivalent to 'toListU'.
elemsU :: MaxQueue a -> [a]
elemsU = toListU

-- | Convert to a list in an arbitrary order.
toListU :: MaxQueue a -> [a]
toListU = coerce . MinQ.toListU . unMaxQueue
toListU = coerce MinQ.toListU

-- | Get the number of elements in a 'MaxQueue'.
size :: MaxQueue a -> Int
Expand All @@ -243,35 +232,34 @@ empty :: MaxQueue a
empty = MaxQueue MinQ.empty

foldMapU :: Monoid m => (a -> m) -> MaxQueue a -> m
foldMapU f = MinQ.foldMapU (f . unDown) . unMaxQueue
foldMapU f = MinQ.foldMapU (coerce f) . unMaxQueue

seqSpine :: MaxQueue a -> b -> b
seqSpine = MinQ.seqSpine . unMaxQueue

foldlU :: (b -> a -> b) -> b -> MaxQueue a -> b
foldlU f b = MinQ.foldlU (\acc (Down a) -> f acc a) b . unMaxQueue
foldlU f b = MinQ.foldlU (coerce f) b . unMaxQueue

foldlU' :: (b -> a -> b) -> b -> MaxQueue a -> b
foldlU' f b = MinQ.foldlU' (\acc (Down a) -> f acc a) b . unMaxQueue
foldlU' f b = MinQ.foldlU' (coerce f) b . unMaxQueue

foldrU :: (a -> b -> b) -> b -> MaxQueue a -> b
foldrU c n = MinQ.foldrU (c . unDown) n . unMaxQueue
foldrU c n = MinQ.foldrU (coerce c) n . unMaxQueue

null :: MaxQueue a -> Bool
null = MinQ.null . unMaxQueue

singleton :: a -> MaxQueue a
singleton = MaxQueue . MinQ.singleton . Down
singleton = coerce MinQ.singleton

mapMaybe :: Ord b => (a -> Maybe b) -> MaxQueue a -> MaxQueue b
mapMaybe f = MaxQueue . MinQ.mapMaybe (coerce f) . unMaxQueue
mapMaybe = coerce MinQ.mapMaybe

insert :: Ord a => a -> MaxQueue a -> MaxQueue a
insert a (MaxQueue q) = MaxQueue (MinQ.insert (Down a) q)
insert = coerce MinQ.insert

mapEither :: (Ord b, Ord c) => (a -> Either b c) -> MaxQueue a -> (MaxQueue b, MaxQueue c)
mapEither f (MaxQueue q) = case MinQ.mapEither (bimap Down Down . f . unDown) q of
(l, r) -> (MaxQueue l, MaxQueue r)
mapEither = coerce MinQ.mapEither

union :: Ord a => MaxQueue a -> MaxQueue a -> MaxQueue a
union (MaxQueue a) (MaxQueue b) = MaxQueue (MinQ.union a b)
Expand Down
Loading