{-# LANGUAGE BangPatterns #-}{-# OPTIONS_HADDOCK not-home #-}-- |---- = WARNING---- This module is considered __internal__.---- The Package Versioning Policy __does not apply__.---- The contents of this module may change __in any way whatsoever__-- and __without any warning__ between minor versions of this package.---- Authors importing this module are expected to track development-- closely.---- = Description---- This module provides the various sorting implementations for-- "Data.Sequence". Further notes are available in the file sorting.md-- (in this directory).moduleData.Sequence.Internal.Sorting(-- * Sort Functionssort ,sortBy ,sortOn ,unstableSort ,unstableSortBy ,unstableSortOn ,-- * Heaps-- $heapsQueue (..),QList (..),IndexedQueue (..),IQList (..),TaggedQueue (..),TQList (..),IndexedTaggedQueue (..),ITQList (..),-- * Merges-- $mergesmergeQ ,mergeIQ ,mergeTQ ,mergeITQ ,-- * popMin-- $popMinpopMinQ ,popMinIQ ,popMinTQ ,popMinITQ ,-- * Building-- $buildingbuildQ ,buildIQ ,buildTQ ,buildITQ ,-- * Special folds-- $foldsfoldToMaybeTree ,foldToMaybeWithIndexTree )whereimportData.Sequence.Internal (Elem (..),Seq (..),Node (..),Digit (..),Sized (..),FingerTree (..),replicateA ,foldDigit ,foldNode ,foldWithIndexDigit ,foldWithIndexNode )importUtils.Containers.Internal.State (State (..),execState )-- | \( O(n \log n) \). 'sort' sorts the specified 'Seq' by the natural-- ordering of its elements. The sort is stable, meaning the order of equal-- elements is preserved. If stability is not-- required, 'unstableSort' can be slightly faster.---- @since 0.3.0sort ::Orda =>Seq a ->Seq a sort :: forall a. Ord a => Seq a -> Seq a
sort =(a -> a -> Ordering) -> Seq a -> Seq a
forall a. (a -> a -> Ordering) -> Seq a -> Seq a
sortBy a -> a -> Ordering
forall a. Ord a => a -> a -> Ordering
compare-- | \( O(n \log n) \). 'sortBy' sorts the specified 'Seq' according to the-- specified comparator. The sort is stable, meaning the order of equal-- elements is preserved. If stability is not required,-- 'unstableSortBy' can be slightly faster.---- @since 0.3.0sortBy ::(a ->a ->Ordering)->Seq a ->Seq a sortBy :: forall a. (a -> a -> Ordering) -> Seq a -> Seq a
sortBy a -> a -> Ordering
cmp (Seq FingerTree (Elem a)
xs )=Seq a
-> (IndexedQueue a -> Seq a) -> Maybe (IndexedQueue a) -> Seq a
forall b a. b -> (a -> b) -> Maybe a -> b
maybe(FingerTree (Elem a) -> Seq a
forall a. FingerTree (Elem a) -> Seq a
Seq FingerTree (Elem a)
forall a. FingerTree a
EmptyT )(State (IndexedQueue a) (Seq a) -> IndexedQueue a -> Seq a
forall s a. State s a -> s -> a
execState (Int -> State (IndexedQueue a) a -> State (IndexedQueue a) (Seq a)
forall (f :: * -> *) a. Applicative f => Int -> f a -> f (Seq a)
replicateA (FingerTree (Elem a) -> Int
forall a. Sized a => a -> Int
size FingerTree (Elem a)
xs )((IndexedQueue a -> (IndexedQueue a, a)) -> State (IndexedQueue a) a
forall s a. (s -> (s, a)) -> State s a
State ((a -> a -> Ordering) -> IndexedQueue a -> (IndexedQueue a, a)
forall e.
(e -> e -> Ordering) -> IndexedQueue e -> (IndexedQueue e, e)
popMinIQ a -> a -> Ordering
cmp ))))((a -> a -> Ordering)
-> (Int -> Elem a -> IndexedQueue a)
-> Int
-> FingerTree (Elem a)
-> Maybe (IndexedQueue a)
forall b y.
(b -> b -> Ordering)
-> (Int -> Elem y -> IndexedQueue b)
-> Int
-> FingerTree (Elem y)
-> Maybe (IndexedQueue b)
buildIQ a -> a -> Ordering
cmp (\Int
s (Elem a
x )->Int -> a -> IQList a -> IndexedQueue a
forall e. Int -> e -> IQList e -> IndexedQueue e
IQ Int
s a
x IQList a
forall e. IQList e
IQNil )Int
0FingerTree (Elem a)
xs )-- | \( O(n \log n) \). 'sortOn' sorts the specified 'Seq' by comparing-- the results of a key function applied to each element. The sort is stable,-- meaning the order of equal elements is preserved. @'sortOn' f@ is-- equivalent to @'sortBy' ('compare' ``Data.Function.on`` f)@, but has the-- performance advantage of only evaluating @f@ once for each element in the-- input 'Seq'.---- An example of using 'sortOn' might be to sort a 'Seq' of strings-- according to their length:---- > sortOn length (fromList ["alligator", "monkey", "zebra"]) == fromList ["zebra", "monkey", "alligator"]---- If, instead, 'sortBy' had been used, 'length' would be evaluated on-- every comparison, giving \( O(n \log n) \) evaluations, rather than-- \( O(n) \).---- If @f@ is very cheap (for example a record selector, or 'fst'),-- @'sortBy' ('compare' ``Data.Function.on`` f)@ will be faster than-- @'sortOn' f@.---- @since 0.5.11sortOn ::Ordb =>(a ->b )->Seq a ->Seq a sortOn :: forall b a. Ord b => (a -> b) -> Seq a -> Seq a
sortOn a -> b
f (Seq FingerTree (Elem a)
xs )=Seq a
-> (IndexedTaggedQueue b a -> Seq a)
-> Maybe (IndexedTaggedQueue b a)
-> Seq a
forall b a. b -> (a -> b) -> Maybe a -> b
maybe(FingerTree (Elem a) -> Seq a
forall a. FingerTree (Elem a) -> Seq a
Seq FingerTree (Elem a)
forall a. FingerTree a
EmptyT )(State (IndexedTaggedQueue b a) (Seq a)
-> IndexedTaggedQueue b a -> Seq a
forall s a. State s a -> s -> a
execState (Int
-> State (IndexedTaggedQueue b a) a
-> State (IndexedTaggedQueue b a) (Seq a)
forall (f :: * -> *) a. Applicative f => Int -> f a -> f (Seq a)
replicateA (FingerTree (Elem a) -> Int
forall a. Sized a => a -> Int
size FingerTree (Elem a)
xs )((IndexedTaggedQueue b a -> (IndexedTaggedQueue b a, a))
-> State (IndexedTaggedQueue b a) a
forall s a. (s -> (s, a)) -> State s a
State ((b -> b -> Ordering)
-> IndexedTaggedQueue b a -> (IndexedTaggedQueue b a, a)
forall e b.
(e -> e -> Ordering)
-> IndexedTaggedQueue e b -> (IndexedTaggedQueue e b, b)
popMinITQ b -> b -> Ordering
forall a. Ord a => a -> a -> Ordering
compare))))((b -> b -> Ordering)
-> (Int -> Elem a -> IndexedTaggedQueue b a)
-> Int
-> FingerTree (Elem a)
-> Maybe (IndexedTaggedQueue b a)
forall b y c.
(b -> b -> Ordering)
-> (Int -> Elem y -> IndexedTaggedQueue b c)
-> Int
-> FingerTree (Elem y)
-> Maybe (IndexedTaggedQueue b c)
buildITQ b -> b -> Ordering
forall a. Ord a => a -> a -> Ordering
compare(\Int
s (Elem a
x )->Int -> b -> a -> ITQList b a -> IndexedTaggedQueue b a
forall e a. Int -> e -> a -> ITQList e a -> IndexedTaggedQueue e a
ITQ Int
s (a -> b
f a
x )a
x ITQList b a
forall e a. ITQList e a
ITQNil )Int
0FingerTree (Elem a)
xs )-- | \( O(n \log n) \). 'unstableSort' sorts the specified 'Seq' by-- the natural ordering of its elements, but the sort is not stable.-- This algorithm is frequently faster and uses less memory than 'sort'.-- Notes on the implementation and choice of heap are available in-- the file sorting.md (in this directory).---- @since 0.3.0unstableSort ::Orda =>Seq a ->Seq a unstableSort :: forall a. Ord a => Seq a -> Seq a
unstableSort =(a -> a -> Ordering) -> Seq a -> Seq a
forall a. (a -> a -> Ordering) -> Seq a -> Seq a
unstableSortBy a -> a -> Ordering
forall a. Ord a => a -> a -> Ordering
compare-- | \( O(n \log n) \). A generalization of 'unstableSort', 'unstableSortBy'-- takes an arbitrary comparator and sorts the specified sequence.-- The sort is not stable. This algorithm is frequently faster and-- uses less memory than 'sortBy'.---- @since 0.3.0unstableSortBy ::(a ->a ->Ordering)->Seq a ->Seq a unstableSortBy :: forall a. (a -> a -> Ordering) -> Seq a -> Seq a
unstableSortBy a -> a -> Ordering
cmp (Seq FingerTree (Elem a)
xs )=Seq a -> (Queue a -> Seq a) -> Maybe (Queue a) -> Seq a
forall b a. b -> (a -> b) -> Maybe a -> b
maybe(FingerTree (Elem a) -> Seq a
forall a. FingerTree (Elem a) -> Seq a
Seq FingerTree (Elem a)
forall a. FingerTree a
EmptyT )(State (Queue a) (Seq a) -> Queue a -> Seq a
forall s a. State s a -> s -> a
execState (Int -> State (Queue a) a -> State (Queue a) (Seq a)
forall (f :: * -> *) a. Applicative f => Int -> f a -> f (Seq a)
replicateA (FingerTree (Elem a) -> Int
forall a. Sized a => a -> Int
size FingerTree (Elem a)
xs )((Queue a -> (Queue a, a)) -> State (Queue a) a
forall s a. (s -> (s, a)) -> State s a
State ((a -> a -> Ordering) -> Queue a -> (Queue a, a)
forall e. (e -> e -> Ordering) -> Queue e -> (Queue e, e)
popMinQ a -> a -> Ordering
cmp ))))((a -> a -> Ordering)
-> (Elem a -> Queue a) -> FingerTree (Elem a) -> Maybe (Queue a)
forall b a.
(b -> b -> Ordering)
-> (a -> Queue b) -> FingerTree a -> Maybe (Queue b)
buildQ a -> a -> Ordering
cmp (\(Elem a
x )->a -> QList a -> Queue a
forall e. e -> QList e -> Queue e
Q a
x QList a
forall e. QList e
Nil )FingerTree (Elem a)
xs )-- | \( O(n \log n) \). 'unstableSortOn' sorts the specified 'Seq' by-- comparing the results of a key function applied to each element.-- @'unstableSortOn' f@ is equivalent to @'unstableSortBy' ('compare' ``Data.Function.on`` f)@,-- but has the performance advantage of only evaluating @f@ once for each-- element in the input 'Seq'.---- An example of using 'unstableSortOn' might be to sort a 'Seq' of strings-- according to their length:---- > unstableSortOn length (fromList ["alligator", "monkey", "zebra"]) == fromList ["zebra", "monkey", "alligator"]---- If, instead, 'unstableSortBy' had been used, 'length' would be evaluated on-- every comparison, giving \( O(n \log n) \) evaluations, rather than-- \( O(n) \).---- If @f@ is very cheap (for example a record selector, or 'fst'),-- @'unstableSortBy' ('compare' ``Data.Function.on`` f)@ will be faster than-- @'unstableSortOn' f@.---- @since 0.5.11unstableSortOn ::Ordb =>(a ->b )->Seq a ->Seq a unstableSortOn :: forall b a. Ord b => (a -> b) -> Seq a -> Seq a
unstableSortOn a -> b
f (Seq FingerTree (Elem a)
xs )=Seq a
-> (TaggedQueue b a -> Seq a) -> Maybe (TaggedQueue b a) -> Seq a
forall b a. b -> (a -> b) -> Maybe a -> b
maybe(FingerTree (Elem a) -> Seq a
forall a. FingerTree (Elem a) -> Seq a
Seq FingerTree (Elem a)
forall a. FingerTree a
EmptyT )(State (TaggedQueue b a) (Seq a) -> TaggedQueue b a -> Seq a
forall s a. State s a -> s -> a
execState (Int -> State (TaggedQueue b a) a -> State (TaggedQueue b a) (Seq a)
forall (f :: * -> *) a. Applicative f => Int -> f a -> f (Seq a)
replicateA (FingerTree (Elem a) -> Int
forall a. Sized a => a -> Int
size FingerTree (Elem a)
xs )((TaggedQueue b a -> (TaggedQueue b a, a))
-> State (TaggedQueue b a) a
forall s a. (s -> (s, a)) -> State s a
State ((b -> b -> Ordering) -> TaggedQueue b a -> (TaggedQueue b a, a)
forall a b.
(a -> a -> Ordering) -> TaggedQueue a b -> (TaggedQueue a b, b)
popMinTQ b -> b -> Ordering
forall a. Ord a => a -> a -> Ordering
compare))))((b -> b -> Ordering)
-> (Elem a -> TaggedQueue b a)
-> FingerTree (Elem a)
-> Maybe (TaggedQueue b a)
forall b a c.
(b -> b -> Ordering)
-> (a -> TaggedQueue b c)
-> FingerTree a
-> Maybe (TaggedQueue b c)
buildTQ b -> b -> Ordering
forall a. Ord a => a -> a -> Ordering
compare(\(Elem a
x )->b -> a -> TQList b a -> TaggedQueue b a
forall a b. a -> b -> TQList a b -> TaggedQueue a b
TQ (a -> b
f a
x )a
x TQList b a
forall a b. TQList a b
TQNil )FingerTree (Elem a)
xs )-------------------------------------------------------------------------- $heaps---- The following are definitions for various specialized pairing heaps.---- All of the heaps are defined to be non-empty, which speeds up the-- merge functions.-------------------------------------------------------------------------- | A simple pairing heap.dataQueue e =Q !e (QList e )dataQList e =Nil |QCons {-# UNPACK#-}!(Queue e )(QList e )-- | A pairing heap tagged with the original position of elements,-- to allow for stable sorting.dataIndexedQueue e =IQ {-# UNPACK#-}!Int!e (IQList e )dataIQList e =IQNil |IQCons {-# UNPACK#-}!(IndexedQueue e )(IQList e )-- | A pairing heap tagged with some key for sorting elements, for use-- in 'unstableSortOn'.dataTaggedQueue a b =TQ !a b (TQList a b )dataTQList a b =TQNil |TQCons {-# UNPACK#-}!(TaggedQueue a b )(TQList a b )-- | A pairing heap tagged with both a key and the original position-- of its elements, for use in 'sortOn'.dataIndexedTaggedQueue e a =ITQ {-# UNPACK#-}!Int!e a (ITQList e a )dataITQList e a =ITQNil |ITQCons {-# UNPACK#-}!(IndexedTaggedQueue e a )(ITQList e a )infixr8`ITQCons` ,`TQCons` ,`QCons` ,`IQCons` -------------------------------------------------------------------------- $merges---- The following are definitions for "merge" for each of the heaps-- above. Each takes a comparison function which is used to order the-- elements.-------------------------------------------------------------------------- | 'mergeQ' merges two 'Queue's.mergeQ ::(a ->a ->Ordering)->Queue a ->Queue a ->Queue a mergeQ :: forall a. (a -> a -> Ordering) -> Queue a -> Queue a -> Queue a
mergeQ a -> a -> Ordering
cmp q1 :: Queue a
q1 @(Q a
x1 QList a
ts1 )q2 :: Queue a
q2 @(Q a
x2 QList a
ts2 )|a -> a -> Ordering
cmp a
x1 a
x2 Ordering -> Ordering -> Bool
forall a. Eq a => a -> a -> Bool
==Ordering
GT=a -> QList a -> Queue a
forall e. e -> QList e -> Queue e
Q a
x2 (Queue a
q1 Queue a -> QList a -> QList a
forall e. Queue e -> QList e -> QList e
`QCons` QList a
ts2 )|Bool
otherwise=a -> QList a -> Queue a
forall e. e -> QList e -> Queue e
Q a
x1 (Queue a
q2 Queue a -> QList a -> QList a
forall e. Queue e -> QList e -> QList e
`QCons` QList a
ts1 )-- | 'mergeTQ' merges two 'TaggedQueue's, based on the tag value.mergeTQ ::(a ->a ->Ordering)->TaggedQueue a b ->TaggedQueue a b ->TaggedQueue a b mergeTQ :: forall a b.
(a -> a -> Ordering)
-> TaggedQueue a b -> TaggedQueue a b -> TaggedQueue a b
mergeTQ a -> a -> Ordering
cmp q1 :: TaggedQueue a b
q1 @(TQ a
x1 b
y1 TQList a b
ts1 )q2 :: TaggedQueue a b
q2 @(TQ a
x2 b
y2 TQList a b
ts2 )|a -> a -> Ordering
cmp a
x1 a
x2 Ordering -> Ordering -> Bool
forall a. Eq a => a -> a -> Bool
==Ordering
GT=a -> b -> TQList a b -> TaggedQueue a b
forall a b. a -> b -> TQList a b -> TaggedQueue a b
TQ a
x2 b
y2 (TaggedQueue a b
q1 TaggedQueue a b -> TQList a b -> TQList a b
forall a b. TaggedQueue a b -> TQList a b -> TQList a b
`TQCons` TQList a b
ts2 )|Bool
otherwise=a -> b -> TQList a b -> TaggedQueue a b
forall a b. a -> b -> TQList a b -> TaggedQueue a b
TQ a
x1 b
y1 (TaggedQueue a b
q2 TaggedQueue a b -> TQList a b -> TQList a b
forall a b. TaggedQueue a b -> TQList a b -> TQList a b
`TQCons` TQList a b
ts1 )-- | 'mergeIQ' merges two 'IndexedQueue's, taking into account the-- original position of the elements.mergeIQ ::(a ->a ->Ordering)->IndexedQueue a ->IndexedQueue a ->IndexedQueue a mergeIQ :: forall a.
(a -> a -> Ordering)
-> IndexedQueue a -> IndexedQueue a -> IndexedQueue a
mergeIQ a -> a -> Ordering
cmp q1 :: IndexedQueue a
q1 @(IQ Int
i1 a
x1 IQList a
ts1 )q2 :: IndexedQueue a
q2 @(IQ Int
i2 a
x2 IQList a
ts2 )=casea -> a -> Ordering
cmp a
x1 a
x2 ofOrdering
LT->Int -> a -> IQList a -> IndexedQueue a
forall e. Int -> e -> IQList e -> IndexedQueue e
IQ Int
i1 a
x1 (IndexedQueue a
q2 IndexedQueue a -> IQList a -> IQList a
forall e. IndexedQueue e -> IQList e -> IQList e
`IQCons` IQList a
ts1 )Ordering
EQ|Int
i1 Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<=Int
i2 ->Int -> a -> IQList a -> IndexedQueue a
forall e. Int -> e -> IQList e -> IndexedQueue e
IQ Int
i1 a
x1 (IndexedQueue a
q2 IndexedQueue a -> IQList a -> IQList a
forall e. IndexedQueue e -> IQList e -> IQList e
`IQCons` IQList a
ts1 )Ordering
_->Int -> a -> IQList a -> IndexedQueue a
forall e. Int -> e -> IQList e -> IndexedQueue e
IQ Int
i2 a
x2 (IndexedQueue a
q1 IndexedQueue a -> IQList a -> IQList a
forall e. IndexedQueue e -> IQList e -> IQList e
`IQCons` IQList a
ts2 )-- | 'mergeITQ' merges two 'IndexedTaggedQueue's, based on the tag-- value, taking into account the original position of the elements.mergeITQ ::(a ->a ->Ordering)->IndexedTaggedQueue a b ->IndexedTaggedQueue a b ->IndexedTaggedQueue a b mergeITQ :: forall a b.
(a -> a -> Ordering)
-> IndexedTaggedQueue a b
-> IndexedTaggedQueue a b
-> IndexedTaggedQueue a b
mergeITQ a -> a -> Ordering
cmp q1 :: IndexedTaggedQueue a b
q1 @(ITQ Int
i1 a
x1 b
y1 ITQList a b
ts1 )q2 :: IndexedTaggedQueue a b
q2 @(ITQ Int
i2 a
x2 b
y2 ITQList a b
ts2 )=casea -> a -> Ordering
cmp a
x1 a
x2 ofOrdering
LT->Int -> a -> b -> ITQList a b -> IndexedTaggedQueue a b
forall e a. Int -> e -> a -> ITQList e a -> IndexedTaggedQueue e a
ITQ Int
i1 a
x1 b
y1 (IndexedTaggedQueue a b
q2 IndexedTaggedQueue a b -> ITQList a b -> ITQList a b
forall e a. IndexedTaggedQueue e a -> ITQList e a -> ITQList e a
`ITQCons` ITQList a b
ts1 )Ordering
EQ|Int
i1 Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<=Int
i2 ->Int -> a -> b -> ITQList a b -> IndexedTaggedQueue a b
forall e a. Int -> e -> a -> ITQList e a -> IndexedTaggedQueue e a
ITQ Int
i1 a
x1 b
y1 (IndexedTaggedQueue a b
q2 IndexedTaggedQueue a b -> ITQList a b -> ITQList a b
forall e a. IndexedTaggedQueue e a -> ITQList e a -> ITQList e a
`ITQCons` ITQList a b
ts1 )Ordering
_->Int -> a -> b -> ITQList a b -> IndexedTaggedQueue a b
forall e a. Int -> e -> a -> ITQList e a -> IndexedTaggedQueue e a
ITQ Int
i2 a
x2 b
y2 (IndexedTaggedQueue a b
q1 IndexedTaggedQueue a b -> ITQList a b -> ITQList a b
forall e a. IndexedTaggedQueue e a -> ITQList e a -> ITQList e a
`ITQCons` ITQList a b
ts2 )-------------------------------------------------------------------------- $popMin---- The following are definitions for @popMin@, a function which-- constructs a stateful action which pops the smallest element from the-- queue, where "smallest" is according to the supplied comparison-- function.---- All of the functions fail on an empty queue.---- Each of these functions is structured something like this:---- @popMinQ cmp (Q x ts) = (mergeQs ts, x)@---- The reason the call to @mergeQs@ is lazy is that it will be bottom-- for the last element in the queue, preventing us from evaluating the-- fully sorted sequence.-------------------------------------------------------------------------- | Pop the smallest element from the queue, using the supplied-- comparator.popMinQ ::(e ->e ->Ordering)->Queue e ->(Queue e ,e )popMinQ :: forall e. (e -> e -> Ordering) -> Queue e -> (Queue e, e)
popMinQ e -> e -> Ordering
cmp (Q e
x QList e
xs )=(QList e -> Queue e
mergeQs QList e
xs ,e
x )wheremergeQs :: QList e -> Queue e
mergeQs (Queue e
t `QCons` QList e
Nil )=Queue e
t mergeQs (Queue e
t1 `QCons` Queue e
t2 `QCons` QList e
Nil )=Queue e
t1 Queue e -> Queue e -> Queue e
<+> Queue e
t2 mergeQs (Queue e
t1 `QCons` Queue e
t2 `QCons` QList e
ts )=(Queue e
t1 Queue e -> Queue e -> Queue e
<+> Queue e
t2 )Queue e -> Queue e -> Queue e
<+> QList e -> Queue e
mergeQs QList e
ts mergeQs QList e
Nil =[Char] -> Queue e
forall a. HasCallStack => [Char] -> a
error[Char]
"popMinQ: tried to pop from empty queue"<+> :: Queue e -> Queue e -> Queue e
(<+>) =(e -> e -> Ordering) -> Queue e -> Queue e -> Queue e
forall a. (a -> a -> Ordering) -> Queue a -> Queue a -> Queue a
mergeQ e -> e -> Ordering
cmp -- | Pop the smallest element from the queue, using the supplied-- comparator, deferring to the item's original position when the-- comparator returns 'EQ'.popMinIQ ::(e ->e ->Ordering)->IndexedQueue e ->(IndexedQueue e ,e )popMinIQ :: forall e.
(e -> e -> Ordering) -> IndexedQueue e -> (IndexedQueue e, e)
popMinIQ e -> e -> Ordering
cmp (IQ Int
_e
x IQList e
xs )=(IQList e -> IndexedQueue e
mergeQs IQList e
xs ,e
x )wheremergeQs :: IQList e -> IndexedQueue e
mergeQs (IndexedQueue e
t `IQCons` IQList e
IQNil )=IndexedQueue e
t mergeQs (IndexedQueue e
t1 `IQCons` IndexedQueue e
t2 `IQCons` IQList e
IQNil )=IndexedQueue e
t1 IndexedQueue e -> IndexedQueue e -> IndexedQueue e
<+> IndexedQueue e
t2 mergeQs (IndexedQueue e
t1 `IQCons` IndexedQueue e
t2 `IQCons` IQList e
ts )=(IndexedQueue e
t1 IndexedQueue e -> IndexedQueue e -> IndexedQueue e
<+> IndexedQueue e
t2 )IndexedQueue e -> IndexedQueue e -> IndexedQueue e
<+> IQList e -> IndexedQueue e
mergeQs IQList e
ts mergeQs IQList e
IQNil =[Char] -> IndexedQueue e
forall a. HasCallStack => [Char] -> a
error[Char]
"popMinQ: tried to pop from empty queue"<+> :: IndexedQueue e -> IndexedQueue e -> IndexedQueue e
(<+>) =(e -> e -> Ordering)
-> IndexedQueue e -> IndexedQueue e -> IndexedQueue e
forall a.
(a -> a -> Ordering)
-> IndexedQueue a -> IndexedQueue a -> IndexedQueue a
mergeIQ e -> e -> Ordering
cmp -- | Pop the smallest element from the queue, using the supplied-- comparator on the tag.popMinTQ ::(a ->a ->Ordering)->TaggedQueue a b ->(TaggedQueue a b ,b )popMinTQ :: forall a b.
(a -> a -> Ordering) -> TaggedQueue a b -> (TaggedQueue a b, b)
popMinTQ a -> a -> Ordering
cmp (TQ a
_b
x TQList a b
xs )=(TQList a b -> TaggedQueue a b
forall {b}. TQList a b -> TaggedQueue a b
mergeQs TQList a b
xs ,b
x )wheremergeQs :: TQList a b -> TaggedQueue a b
mergeQs (TaggedQueue a b
t `TQCons` TQList a b
TQNil )=TaggedQueue a b
t mergeQs (TaggedQueue a b
t1 `TQCons` TaggedQueue a b
t2 `TQCons` TQList a b
TQNil )=TaggedQueue a b
t1 TaggedQueue a b -> TaggedQueue a b -> TaggedQueue a b
forall {b}. TaggedQueue a b -> TaggedQueue a b -> TaggedQueue a b
<+> TaggedQueue a b
t2 mergeQs (TaggedQueue a b
t1 `TQCons` TaggedQueue a b
t2 `TQCons` TQList a b
ts )=(TaggedQueue a b
t1 TaggedQueue a b -> TaggedQueue a b -> TaggedQueue a b
forall {b}. TaggedQueue a b -> TaggedQueue a b -> TaggedQueue a b
<+> TaggedQueue a b
t2 )TaggedQueue a b -> TaggedQueue a b -> TaggedQueue a b
forall {b}. TaggedQueue a b -> TaggedQueue a b -> TaggedQueue a b
<+> TQList a b -> TaggedQueue a b
mergeQs TQList a b
ts mergeQs TQList a b
TQNil =[Char] -> TaggedQueue a b
forall a. HasCallStack => [Char] -> a
error[Char]
"popMinQ: tried to pop from empty queue"<+> :: TaggedQueue a b -> TaggedQueue a b -> TaggedQueue a b
(<+>) =(a -> a -> Ordering)
-> TaggedQueue a b -> TaggedQueue a b -> TaggedQueue a b
forall a b.
(a -> a -> Ordering)
-> TaggedQueue a b -> TaggedQueue a b -> TaggedQueue a b
mergeTQ a -> a -> Ordering
cmp -- | Pop the smallest element from the queue, using the supplied-- comparator on the tag, deferring to the item's original position-- when the comparator returns 'EQ'.popMinITQ ::(e ->e ->Ordering)->IndexedTaggedQueue e b ->(IndexedTaggedQueue e b ,b )popMinITQ :: forall e b.
(e -> e -> Ordering)
-> IndexedTaggedQueue e b -> (IndexedTaggedQueue e b, b)
popMinITQ e -> e -> Ordering
cmp (ITQ Int
_e
_b
x ITQList e b
xs )=(ITQList e b -> IndexedTaggedQueue e b
forall {a}. ITQList e a -> IndexedTaggedQueue e a
mergeQs ITQList e b
xs ,b
x )wheremergeQs :: ITQList e a -> IndexedTaggedQueue e a
mergeQs (IndexedTaggedQueue e a
t `ITQCons` ITQList e a
ITQNil )=IndexedTaggedQueue e a
t mergeQs (IndexedTaggedQueue e a
t1 `ITQCons` IndexedTaggedQueue e a
t2 `ITQCons` ITQList e a
ITQNil )=IndexedTaggedQueue e a
t1 IndexedTaggedQueue e a
-> IndexedTaggedQueue e a -> IndexedTaggedQueue e a
forall {b}.
IndexedTaggedQueue e b
-> IndexedTaggedQueue e b -> IndexedTaggedQueue e b
<+> IndexedTaggedQueue e a
t2 mergeQs (IndexedTaggedQueue e a
t1 `ITQCons` IndexedTaggedQueue e a
t2 `ITQCons` ITQList e a
ts )=(IndexedTaggedQueue e a
t1 IndexedTaggedQueue e a
-> IndexedTaggedQueue e a -> IndexedTaggedQueue e a
forall {b}.
IndexedTaggedQueue e b
-> IndexedTaggedQueue e b -> IndexedTaggedQueue e b
<+> IndexedTaggedQueue e a
t2 )IndexedTaggedQueue e a
-> IndexedTaggedQueue e a -> IndexedTaggedQueue e a
forall {b}.
IndexedTaggedQueue e b
-> IndexedTaggedQueue e b -> IndexedTaggedQueue e b
<+> ITQList e a -> IndexedTaggedQueue e a
mergeQs ITQList e a
ts mergeQs ITQList e a
ITQNil =[Char] -> IndexedTaggedQueue e a
forall a. HasCallStack => [Char] -> a
error[Char]
"popMinQ: tried to pop from empty queue"<+> :: IndexedTaggedQueue e b
-> IndexedTaggedQueue e b -> IndexedTaggedQueue e b
(<+>) =(e -> e -> Ordering)
-> IndexedTaggedQueue e b
-> IndexedTaggedQueue e b
-> IndexedTaggedQueue e b
forall a b.
(a -> a -> Ordering)
-> IndexedTaggedQueue a b
-> IndexedTaggedQueue a b
-> IndexedTaggedQueue a b
mergeITQ e -> e -> Ordering
cmp -------------------------------------------------------------------------- $building---- The following are definitions for functions to build queues, given a-- comparison function.------------------------------------------------------------------------buildQ ::(b ->b ->Ordering)->(a ->Queue b )->FingerTree a ->Maybe(Queue b )buildQ :: forall b a.
(b -> b -> Ordering)
-> (a -> Queue b) -> FingerTree a -> Maybe (Queue b)
buildQ b -> b -> Ordering
cmp =(Queue b -> Queue b -> Queue b)
-> (a -> Queue b) -> FingerTree a -> Maybe (Queue b)
forall b a. (b -> b -> b) -> (a -> b) -> FingerTree a -> Maybe b
foldToMaybeTree ((b -> b -> Ordering) -> Queue b -> Queue b -> Queue b
forall a. (a -> a -> Ordering) -> Queue a -> Queue a -> Queue a
mergeQ b -> b -> Ordering
cmp )buildIQ ::(b ->b ->Ordering)->(Int->Elem y ->IndexedQueue b )->Int->FingerTree (Elem y )->Maybe(IndexedQueue b )buildIQ :: forall b y.
(b -> b -> Ordering)
-> (Int -> Elem y -> IndexedQueue b)
-> Int
-> FingerTree (Elem y)
-> Maybe (IndexedQueue b)
buildIQ b -> b -> Ordering
cmp =(IndexedQueue b -> IndexedQueue b -> IndexedQueue b)
-> (Int -> Elem y -> IndexedQueue b)
-> Int
-> FingerTree (Elem y)
-> Maybe (IndexedQueue b)
forall b y.
(b -> b -> b)
-> (Int -> Elem y -> b) -> Int -> FingerTree (Elem y) -> Maybe b
foldToMaybeWithIndexTree ((b -> b -> Ordering)
-> IndexedQueue b -> IndexedQueue b -> IndexedQueue b
forall a.
(a -> a -> Ordering)
-> IndexedQueue a -> IndexedQueue a -> IndexedQueue a
mergeIQ b -> b -> Ordering
cmp )buildTQ ::(b ->b ->Ordering)->(a ->TaggedQueue b c )->FingerTree a ->Maybe(TaggedQueue b c )buildTQ :: forall b a c.
(b -> b -> Ordering)
-> (a -> TaggedQueue b c)
-> FingerTree a
-> Maybe (TaggedQueue b c)
buildTQ b -> b -> Ordering
cmp =(TaggedQueue b c -> TaggedQueue b c -> TaggedQueue b c)
-> (a -> TaggedQueue b c)
-> FingerTree a
-> Maybe (TaggedQueue b c)
forall b a. (b -> b -> b) -> (a -> b) -> FingerTree a -> Maybe b
foldToMaybeTree ((b -> b -> Ordering)
-> TaggedQueue b c -> TaggedQueue b c -> TaggedQueue b c
forall a b.
(a -> a -> Ordering)
-> TaggedQueue a b -> TaggedQueue a b -> TaggedQueue a b
mergeTQ b -> b -> Ordering
cmp )buildITQ ::(b ->b ->Ordering)->(Int->Elem y ->IndexedTaggedQueue b c )->Int->FingerTree (Elem y )->Maybe(IndexedTaggedQueue b c )buildITQ :: forall b y c.
(b -> b -> Ordering)
-> (Int -> Elem y -> IndexedTaggedQueue b c)
-> Int
-> FingerTree (Elem y)
-> Maybe (IndexedTaggedQueue b c)
buildITQ b -> b -> Ordering
cmp =(IndexedTaggedQueue b c
 -> IndexedTaggedQueue b c -> IndexedTaggedQueue b c)
-> (Int -> Elem y -> IndexedTaggedQueue b c)
-> Int
-> FingerTree (Elem y)
-> Maybe (IndexedTaggedQueue b c)
forall b y.
(b -> b -> b)
-> (Int -> Elem y -> b) -> Int -> FingerTree (Elem y) -> Maybe b
foldToMaybeWithIndexTree ((b -> b -> Ordering)
-> IndexedTaggedQueue b c
-> IndexedTaggedQueue b c
-> IndexedTaggedQueue b c
forall a b.
(a -> a -> Ordering)
-> IndexedTaggedQueue a b
-> IndexedTaggedQueue a b
-> IndexedTaggedQueue a b
mergeITQ b -> b -> Ordering
cmp )-------------------------------------------------------------------------- $folds---- A big part of what makes the heaps fast is that they're non empty,-- so the merge function can avoid an extra case match. To take-- advantage of this, though, we need specialized versions of 'foldMap'-- and 'Data.Sequence.foldMapWithIndex', which can alternate between-- calling the faster semigroup-like merge when folding over non empty-- structures (like 'Node' and 'Digit'), and the-- 'Data.Semirgroup.Option'-like mappend, when folding over structures-- which can be empty (like 'FingerTree').-------------------------------------------------------------------------- | A 'foldMap'-like function, specialized to the-- 'Data.Semigroup.Option' monoid, which takes advantage of the-- internal structure of 'Seq' to avoid wrapping in 'Maybe' at certain-- points.foldToMaybeTree ::(b ->b ->b )->(a ->b )->FingerTree a ->Maybeb foldToMaybeTree :: forall b a. (b -> b -> b) -> (a -> b) -> FingerTree a -> Maybe b
foldToMaybeTree b -> b -> b
_a -> b
_FingerTree a
EmptyT =Maybe b
forall a. Maybe a
NothingfoldToMaybeTree b -> b -> b
_a -> b
f (Single a
xs )=b -> Maybe b
forall a. a -> Maybe a
Just(a -> b
f a
xs )foldToMaybeTree b -> b -> b
(<+>) a -> b
f (Deep Int
_Digit a
pr FingerTree (Node a)
m Digit a
sf )=b -> Maybe b
forall a. a -> Maybe a
Just(b -> (b -> b) -> Maybe b -> b
forall b a. b -> (a -> b) -> Maybe a -> b
maybe(b
pr' b -> b -> b
<+> b
sf' )((b
pr' b -> b -> b
<+> b
sf' )b -> b -> b
<+> )Maybe b
m' )wherepr' :: b
pr' =(b -> b -> b) -> (a -> b) -> Digit a -> b
forall b a. (b -> b -> b) -> (a -> b) -> Digit a -> b
foldDigit b -> b -> b
(<+>) a -> b
f Digit a
pr sf' :: b
sf' =(b -> b -> b) -> (a -> b) -> Digit a -> b
forall b a. (b -> b -> b) -> (a -> b) -> Digit a -> b
foldDigit b -> b -> b
(<+>) a -> b
f Digit a
sf m' :: Maybe b
m' =(b -> b -> b) -> (Node a -> b) -> FingerTree (Node a) -> Maybe b
forall b a. (b -> b -> b) -> (a -> b) -> FingerTree a -> Maybe b
foldToMaybeTree b -> b -> b
(<+>) ((b -> b -> b) -> (a -> b) -> Node a -> b
forall b a. (b -> b -> b) -> (a -> b) -> Node a -> b
foldNode b -> b -> b
(<+>) a -> b
f )FingerTree (Node a)
m -- | A 'Data.Sequence.foldMapWithIndex'-like function, specialized to the-- 'Data.Semigroup.Option' monoid, which takes advantage of the-- internal structure of 'Seq' to avoid wrapping in 'Maybe' at certain-- points.foldToMaybeWithIndexTree ::(b ->b ->b )->(Int->Elem y ->b )->Int->FingerTree (Elem y )->Maybeb foldToMaybeWithIndexTree :: forall b y.
(b -> b -> b)
-> (Int -> Elem y -> b) -> Int -> FingerTree (Elem y) -> Maybe b
foldToMaybeWithIndexTree =(b -> b -> b)
-> (Int -> Elem y -> b) -> Int -> FingerTree (Elem y) -> Maybe b
forall a b.
Sized a =>
(b -> b -> b) -> (Int -> a -> b) -> Int -> FingerTree a -> Maybe b
foldToMaybeWithIndexTree' where{-# SPECIALISEfoldToMaybeWithIndexTree' ::(b ->b ->b )->(Int->Elem y ->b )->Int->FingerTree (Elem y )->Maybeb #-}{-# SPECIALISEfoldToMaybeWithIndexTree' ::(b ->b ->b )->(Int->Node y ->b )->Int->FingerTree (Node y )->Maybeb #-}foldToMaybeWithIndexTree' ::Sized a =>(b ->b ->b )->(Int->a ->b )->Int->FingerTree a ->Maybeb foldToMaybeWithIndexTree' :: forall a b.
Sized a =>
(b -> b -> b) -> (Int -> a -> b) -> Int -> FingerTree a -> Maybe b
foldToMaybeWithIndexTree' b -> b -> b
_Int -> a -> b
_!Int
_s FingerTree a
EmptyT =Maybe b
forall a. Maybe a
NothingfoldToMaybeWithIndexTree' b -> b -> b
_Int -> a -> b
f Int
s (Single a
xs )=b -> Maybe b
forall a. a -> Maybe a
Just(Int -> a -> b
f Int
s a
xs )foldToMaybeWithIndexTree' b -> b -> b
(<+>) Int -> a -> b
f Int
s (Deep Int
_Digit a
pr FingerTree (Node a)
m Digit a
sf )=b -> Maybe b
forall a. a -> Maybe a
Just(b -> (b -> b) -> Maybe b -> b
forall b a. b -> (a -> b) -> Maybe a -> b
maybe(b
pr' b -> b -> b
<+> b
sf' )((b
pr' b -> b -> b
<+> b
sf' )b -> b -> b
<+> )Maybe b
m' )wherepr' :: b
pr' =(b -> b -> b) -> (Int -> a -> b) -> Int -> Digit a -> b
forall a b.
Sized a =>
(b -> b -> b) -> (Int -> a -> b) -> Int -> Digit a -> b
digit b -> b -> b
(<+>) Int -> a -> b
f Int
s Digit a
pr sf' :: b
sf' =(b -> b -> b) -> (Int -> a -> b) -> Int -> Digit a -> b
forall a b.
Sized a =>
(b -> b -> b) -> (Int -> a -> b) -> Int -> Digit a -> b
digit b -> b -> b
(<+>) Int -> a -> b
f Int
sPsprm Digit a
sf m' :: Maybe b
m' =(b -> b -> b)
-> (Int -> Node a -> b) -> Int -> FingerTree (Node a) -> Maybe b
forall a b.
Sized a =>
(b -> b -> b) -> (Int -> a -> b) -> Int -> FingerTree a -> Maybe b
foldToMaybeWithIndexTree' b -> b -> b
(<+>) ((b -> b -> b) -> (Int -> a -> b) -> Int -> Node a -> b
forall a b.
Sized a =>
(b -> b -> b) -> (Int -> a -> b) -> Int -> Node a -> b
node b -> b -> b
(<+>) Int -> a -> b
f )Int
sPspr FingerTree (Node a)
m !sPspr :: Int
sPspr =Int
s Int -> Int -> Int
forall a. Num a => a -> a -> a
+Digit a -> Int
forall a. Sized a => a -> Int
size Digit a
pr !sPsprm :: Int
sPsprm =Int
sPspr Int -> Int -> Int
forall a. Num a => a -> a -> a
+FingerTree (Node a) -> Int
forall a. Sized a => a -> Int
size FingerTree (Node a)
m {-# SPECIALISEdigit ::(b ->b ->b )->(Int->Elem y ->b )->Int->Digit (Elem y )->b #-}{-# SPECIALISEdigit ::(b ->b ->b )->(Int->Node y ->b )->Int->Digit (Node y )->b #-}digit ::Sized a =>(b ->b ->b )->(Int->a ->b )->Int->Digit a ->b digit :: forall a b.
Sized a =>
(b -> b -> b) -> (Int -> a -> b) -> Int -> Digit a -> b
digit =(b -> b -> b) -> (Int -> a -> b) -> Int -> Digit a -> b
forall a b.
Sized a =>
(b -> b -> b) -> (Int -> a -> b) -> Int -> Digit a -> b
foldWithIndexDigit {-# SPECIALISEnode ::(b ->b ->b )->(Int->Elem y ->b )->Int->Node (Elem y )->b #-}{-# SPECIALISEnode ::(b ->b ->b )->(Int->Node y ->b )->Int->Node (Node y )->b #-}node ::Sized a =>(b ->b ->b )->(Int->a ->b )->Int->Node a ->b node :: forall a b.
Sized a =>
(b -> b -> b) -> (Int -> a -> b) -> Int -> Node a -> b
node =(b -> b -> b) -> (Int -> a -> b) -> Int -> Node a -> b
forall a b.
Sized a =>
(b -> b -> b) -> (Int -> a -> b) -> Int -> Node a -> b
foldWithIndexNode {-# INLINEfoldToMaybeWithIndexTree #-}

AltStyle によって変換されたページ (->オリジナル) /