Skip to content
Draft
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
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
# Revision history for pqueue

## 1.5.0

* Remove `Data.PQueue.Internals.Down.Down`. Use the usual `Data.Ord.Down`
instead.

## 1.4.3.0 -- 2022-10-30

* Add instances for [indexed-traversable](https://hackage.haskell.org/package/indexed-traversable).
Expand Down
35 changes: 18 additions & 17 deletions src/BinomialQueue/Max.hs
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,8 @@ import Data.Semigroup (Semigroup((<>)))
import qualified Data.List as List

import qualified BinomialQueue.Min as MinQ
import Data.PQueue.Internals.Down
import Data.PQueue.Internals.Down (getDown)
import Data.Ord (Down (..))

#ifdef __GLASGOW_HASKELL__
import GHC.Exts (build)
Expand All @@ -115,7 +116,7 @@ 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 (MaxQueue q) = getDown <$> MinQ.getMin q

-- | \(O(\log n)\). Deletes the maximum element. If the queue is empty, does nothing.
deleteMax :: Ord a => MaxQueue a -> MaxQueue a
Expand All @@ -142,19 +143,19 @@ q !! n = (List.!!) (toDescList q) 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 = fmap unDown . MinQ.takeWhile (p . unDown) . unMaxQueue
takeWhile p = fmap getDown . MinQ.takeWhile (p . getDown) . unMaxQueue

-- | '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 p = MaxQueue . MinQ.dropWhile (p . getDown) . unMaxQueue

-- | '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
= (fmap unDown front, MaxQueue rear)
| (front, rear) <- MinQ.span (p . getDown) queue
= (fmap getDown front, MaxQueue rear)

-- | '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 @@ -177,19 +178,19 @@ drop n (MaxQueue queue) = MaxQueue (MinQ.drop n queue)
splitAt :: Ord a => Int -> MaxQueue a -> ([a], MaxQueue a)
splitAt n (MaxQueue queue)
| (l, r) <- MinQ.splitAt n queue
= (fmap unDown l, MaxQueue r)
= (fmap getDown l, MaxQueue r)

-- | \(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 p = MaxQueue . MinQ.filter (p . getDown) . unMaxQueue

-- | \(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
| (l, r) <- MinQ.partition (p . getDown) queue
= (MaxQueue l, MaxQueue r)

-- | \(O(n)\). Creates a new priority queue containing the images of the elements of this queue.
Expand All @@ -202,13 +203,13 @@ map f = MaxQueue . MinQ.map (fmap f) . unMaxQueue
--
-- If the order of the elements is irrelevant, consider using 'toListU'.
toList :: Ord a => MaxQueue a -> [a]
toList = fmap unDown . MinQ.toAscList . unMaxQueue
toList = fmap getDown . MinQ.toAscList . unMaxQueue

toAscList :: Ord a => MaxQueue a -> [a]
toAscList = fmap unDown . MinQ.toDescList . unMaxQueue
toAscList = fmap getDown . MinQ.toDescList . unMaxQueue

toDescList :: Ord a => MaxQueue a -> [a]
toDescList = fmap unDown . MinQ.toAscList . unMaxQueue
toDescList = fmap getDown . MinQ.toAscList . unMaxQueue

-- | \(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
Expand Down Expand Up @@ -245,7 +246,7 @@ elemsU = toListU

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

-- | Get the number of elements in a 'MaxQueue'.
size :: MaxQueue a -> Int
Expand All @@ -255,7 +256,7 @@ 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 (f . getDown) . unMaxQueue

seqSpine :: MaxQueue a -> b -> b
seqSpine = MinQ.seqSpine . unMaxQueue
Expand All @@ -267,7 +268,7 @@ foldlU' :: (b -> a -> b) -> b -> MaxQueue a -> b
foldlU' f b = MinQ.foldlU' (\acc (Down a) -> f acc a) b . unMaxQueue

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

null :: MaxQueue a -> Bool
null = MinQ.null . unMaxQueue
Expand All @@ -276,13 +277,13 @@ singleton :: a -> MaxQueue a
singleton = MaxQueue . MinQ.singleton . Down

mapMaybe :: Ord b => (a -> Maybe b) -> MaxQueue a -> MaxQueue b
mapMaybe f = MaxQueue . MinQ.mapMaybe (fmap Down . f . unDown) . unMaxQueue
mapMaybe f = MaxQueue . MinQ.mapMaybe (fmap Down . f . getDown) . unMaxQueue

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

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
mapEither f (MaxQueue q) = case MinQ.mapEither (bimap Down Down . f . getDown) q of
(l, r) -> (MaxQueue l, MaxQueue r)

union :: Ord a => MaxQueue a -> MaxQueue a -> MaxQueue a
Expand Down
40 changes: 7 additions & 33 deletions src/Data/PQueue/Internals/Down.hs
Original file line number Diff line number Diff line change
@@ -1,37 +1,11 @@
{-# LANGUAGE CPP #-}
{-# LANGUAGE BangPatterns #-}

module Data.PQueue.Internals.Down where
module Data.PQueue.Internals.Down
( getDown
) where
import Data.Ord (Down (..))

import Control.DeepSeq (NFData(rnf))
import Data.Foldable (Foldable (..))

#if __GLASGOW_HASKELL__
import Data.Data (Data)
#endif

newtype Down a = Down { unDown :: a }
#if __GLASGOW_HASKELL__
deriving (Eq, Data)
#else
deriving (Eq)
#if !MIN_VERSION_base(4,14,0)
getDown :: Down a -> a
getDown (Down a) = a
#endif

instance NFData a => NFData (Down a) where
rnf (Down a) = rnf a

instance Ord a => Ord (Down a) where
Down a `compare` Down b = b `compare` a
Down a <= Down b = b <= a
Down a >= Down b = b >= a
Down a < Down b = b < a
Down a > Down b = b > a

instance Functor Down where
fmap f (Down a) = Down (f a)

instance Foldable Down where
foldr f z (Down a) = a `f` z
foldl f z (Down a) = z `f` a
foldr' f !z (Down a) = a `f` z
foldl' f !z (Down a) = z `f` a
29 changes: 15 additions & 14 deletions src/Data/PQueue/Max.hs
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,8 @@ import Data.Foldable (foldl')

import qualified Data.PQueue.Min as Min
import qualified Data.PQueue.Prio.Max.Internals as Prio
import Data.PQueue.Internals.Down (Down(..))
import Data.PQueue.Internals.Down (getDown)
import Data.Ord (Down(..))

import Prelude hiding (null, map, take, drop, takeWhile, dropWhile, splitAt, span, break, (!!), filter)

Expand Down Expand Up @@ -171,7 +172,7 @@ findMax = fromMaybe (error "Error: findMax called on empty queue") . getMax

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

-- | \(O(\log n)\). Deletes the maximum element of the queue. Does nothing on an empty queue.
deleteMax :: Ord a => MaxQueue a -> MaxQueue a
Expand Down Expand Up @@ -210,7 +211,7 @@ unions qs = MaxQ (Min.unions [q | MaxQ q <- qs])

-- | \(O(k \log n)\)/. Returns the @(k+1)@th largest element of the queue.
(!!) :: Ord a => MaxQueue a -> Int -> a
MaxQ q !! n = unDown ((Min.!!) q n)
MaxQ q !! n = getDown ((Min.!!) q n)

{-# INLINE take #-}
-- | \(O(k \log n)\)/. Returns the list of the @k@ largest elements of the queue, in descending order, or
Expand All @@ -224,25 +225,25 @@ drop k (MaxQ q) = MaxQ (Min.drop k q)

-- | \(O(k \log n)\)/. Equivalent to @(take k queue, drop k queue)@.
splitAt :: Ord a => Int -> MaxQueue a -> ([a], MaxQueue a)
splitAt k (MaxQ q) = (fmap unDown xs, MaxQ q') where
splitAt k (MaxQ q) = (fmap getDown xs, MaxQ q') where
(xs, q') = Min.splitAt k q

-- | '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 (MaxQ q) = fmap unDown (Min.takeWhile (p . unDown) q)
takeWhile p (MaxQ q) = fmap getDown (Min.takeWhile (p . getDown) q)

-- | 'dropWhile' @p queue@ returns the queue remaining after 'takeWhile' @p queue@.
dropWhile :: Ord a => (a -> Bool) -> MaxQueue a -> MaxQueue a
dropWhile p (MaxQ q) = MaxQ (Min.dropWhile (p . unDown) q)
dropWhile p (MaxQ q) = MaxQ (Min.dropWhile (p . getDown) q)

-- | '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 (MaxQ q) = (fmap unDown xs, MaxQ q') where
(xs, q') = Min.span (p . unDown) q
span p (MaxQ q) = (fmap getDown xs, MaxQ q') where
(xs, q') = Min.span (p . getDown) q

-- | '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 @@ -252,13 +253,13 @@ break p = span (not . p)

-- | \(O(n)\). Returns a queue of those elements which satisfy the predicate.
filter :: Ord a => (a -> Bool) -> MaxQueue a -> MaxQueue a
filter p (MaxQ q) = MaxQ (Min.filter (p . unDown) q)
filter p (MaxQ q) = MaxQ (Min.filter (p . getDown) q)

-- | \(O(n)\). Returns a pair of queues, where the left queue contains those elements that satisfy the predicate,
-- and the right queue contains those that do not.
partition :: Ord a => (a -> Bool) -> MaxQueue a -> (MaxQueue a, MaxQueue a)
partition p (MaxQ q) = (MaxQ q0, MaxQ q1)
where (q0, q1) = Min.partition (p . unDown) q
where (q0, q1) = Min.partition (p . getDown) q

-- | \(O(n)\). Maps a function over the elements of the queue, and collects the 'Just' values.
mapMaybe :: Ord b => (a -> Maybe b) -> MaxQueue a -> MaxQueue b
Expand All @@ -267,7 +268,7 @@ mapMaybe f (MaxQ q) = MaxQ (Min.mapMaybe (\(Down x) -> Down <$> f x) q)
-- | \(O(n)\). Maps a function over the elements of the queue, and separates the 'Left' and 'Right' values.
mapEither :: (Ord b, Ord c) => (a -> Either b c) -> MaxQueue a -> (MaxQueue b, MaxQueue c)
mapEither f (MaxQ q) = (MaxQ q0, MaxQ q1)
where (q0, q1) = Min.mapEither (either (Left . Down) (Right . Down) . f . unDown) q
where (q0, q1) = Min.mapEither (either (Left . Down) (Right . Down) . f . getDown) q

-- | \(O(n)\). Creates a new priority queue containing the images of the elements of this queue.
-- Equivalent to @'fromList' . 'Data.List.map' f . toList@.
Expand All @@ -287,7 +288,7 @@ foldrU f z (MaxQ q) = Min.foldrU (flip (foldr f)) z q
--
-- @since 1.4.2
foldMapU :: Monoid m => (a -> m) -> MaxQueue a -> m
foldMapU f (MaxQ q) = Min.foldMapU (f . unDown) q
foldMapU f (MaxQ q) = Min.foldMapU (f . getDown) q

-- | \(O(n)\). Unordered left fold on a priority queue. This is rarely
-- what you want; 'foldrU' and 'foldlU'' are more likely to perform
Expand All @@ -309,7 +310,7 @@ elemsU = toListU
{-# INLINE toListU #-}
-- | \(O(n)\). Returns a list of the elements of the priority queue, in no particular order.
toListU :: MaxQueue a -> [a]
toListU (MaxQ q) = fmap unDown (Min.toListU q)
toListU (MaxQ q) = fmap getDown (Min.toListU q)

-- | \(O(n \log n)\). Performs a right-fold on the elements of a priority queue in ascending order.
-- @'foldrAsc' f z q == 'foldlDesc' (flip f) z q@.
Expand Down Expand Up @@ -346,7 +347,7 @@ toDescList q = build (\c nil -> foldrDesc c nil q)
--
-- If the order of the elements is irrelevant, consider using 'toListU'.
toList :: Ord a => MaxQueue a -> [a]
toList (MaxQ q) = fmap unDown (Min.toList q)
toList (MaxQ q) = fmap getDown (Min.toList q)

{-# INLINE fromAscList #-}
-- | \(O(n)\). Constructs a priority queue from an ascending list. /Warning/: Does not check the precondition.
Expand Down
Loading