Skip to content

Commit

Permalink
Use coerce instead of fmap Down/fmap unDown (#130)
Browse files Browse the repository at this point in the history
  • Loading branch information
konsumlamm authored Sep 7, 2023
1 parent 5be8ac1 commit 781aa57
Show file tree
Hide file tree
Showing 2 changed files with 21 additions and 19 deletions.
23 changes: 12 additions & 11 deletions src/BinomialQueue/Max.hs
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ module BinomialQueue.Max (

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

import Data.Coerce (coerce)
import Data.Foldable (foldl')
import Data.Maybe (fromMaybe)
import Data.Bifunctor (bimap)
Expand Down Expand Up @@ -142,7 +143,7 @@ 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 = fmap unDown . MinQ.takeWhile (p . unDown) . unMaxQueue
takeWhile p = coerce . MinQ.takeWhile (p . unDown) . unMaxQueue

-- | 'dropWhile' @p queue@ returns the queue remaining after 'takeWhile' @p queue@.
dropWhile :: Ord a => (a -> Bool) -> MaxQueue a -> MaxQueue a
Expand All @@ -154,7 +155,7 @@ dropWhile p = MaxQueue . MinQ.dropWhile (p . unDown) . unMaxQueue
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)
= (coerce 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,7 +178,7 @@ 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)
= (coerce l, MaxQueue r)

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

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

toDescList :: Ord a => MaxQueue a -> [a]
toDescList = fmap unDown . MinQ.toAscList . unMaxQueue
toDescList = coerce . 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 All @@ -229,23 +230,23 @@ foldlDesc f z (MaxQueue q) = MinQ.foldlAsc (foldl 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 . fmap Down
fromAscList = MaxQueue . MinQ.fromDescList . coerce

{-# 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 . fmap Down
fromDescList = MaxQueue . MinQ.fromAscList . coerce

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

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

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

-- | Get the number of elements in a 'MaxQueue'.
size :: MaxQueue a -> Int
Expand Down Expand Up @@ -276,7 +277,7 @@ 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 (coerce f) . unMaxQueue

insert :: Ord a => a -> MaxQueue a -> MaxQueue a
insert a (MaxQueue q) = MaxQueue (MinQ.insert (Down a) q)
Expand Down
17 changes: 9 additions & 8 deletions src/Data/PQueue/Max.hs
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ module Data.PQueue.Max (

import Control.DeepSeq (NFData(rnf))

import Data.Coerce (coerce)
import Data.Maybe (fromMaybe)

#if MIN_VERSION_base(4,9,0)
Expand Down Expand Up @@ -224,13 +225,13 @@ 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) = (coerce 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) = coerce (Min.takeWhile (p . unDown) q)

-- | 'dropWhile' @p queue@ returns the queue remaining after 'takeWhile' @p queue@.
dropWhile :: Ord a => (a -> Bool) -> MaxQueue a -> MaxQueue a
Expand All @@ -241,7 +242,7 @@ dropWhile p (MaxQ q) = MaxQ (Min.dropWhile (p . unDown) q)
-- 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
span p (MaxQ q) = (coerce xs, MaxQ q') where
(xs, q') = Min.span (p . unDown) q

-- | 'break', applied to a predicate @p@ and a queue @queue@, returns a tuple where
Expand Down Expand Up @@ -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) = coerce (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,22 +347,22 @@ 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) = coerce (Min.toList q)

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

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

{-# INLINE fromList #-}
-- | \(O(n \log n)\). Constructs a priority queue from an unordered list.
fromList :: Ord a => [a] -> MaxQueue a
fromList = MaxQ . Min.fromList . fmap Down
fromList = MaxQ . Min.fromList . coerce

-- | \(O(n)\). Constructs a priority queue from the keys of a 'Prio.MaxPQueue'.
keysQueue :: Prio.MaxPQueue k a -> MaxQueue k
Expand Down

0 comments on commit 781aa57

Please sign in to comment.