@@ -237,6 +237,7 @@ module Data.IntMap.Internal (
237237 , fromAscListWith
238238 , fromAscListWithKey
239239 , fromDistinctAscList
240+ , fromDescList
240241
241242 -- * Filter
242243 , filter
@@ -296,6 +297,9 @@ module Data.IntMap.Internal (
296297 , Stack (.. )
297298 , ascLinkTop
298299 , ascLinkAll
300+ , descInsert
301+ , descLinkTop
302+ , descLinkAll
299303 , IntMapBuilder (.. )
300304 , BStack (.. )
301305 , emptyB
@@ -3605,6 +3609,22 @@ fromDistinctAscList :: [(Key,a)] -> IntMap a
36053609fromDistinctAscList = fromAscList
36063610{-# INLINE fromDistinctAscList #-} -- Inline for list fusion
36073611
3612+ -- | \(O(n)\). Build a map from a list of key\/value pairs where
3613+ -- the keys are in descending order.
3614+ --
3615+ -- __Warning__: This function should be used only if the keys are in
3616+ -- non-increasing order. This precondition is not checked. Use 'fromList' if the
3617+ -- precondition may not hold.
3618+ --
3619+ -- > fromDescList [(5,"a"), (3,"b")] == fromList [(3,"b"), (5,"a")]
3620+ -- > fromDescList [(5,"a"), (5,"b"), (3,"b")] == fromList [(3,"b"), (5,"b")]
3621+ --
3622+ -- @since FIXME
3623+ fromDescList :: [(Key ,a )] -> IntMap a
3624+ fromDescList xs =
3625+ descLinkAll (Foldable. foldl' (\ s (ky, y) -> descInsert ky y s) MSNada xs)
3626+ {-# INLINE fromDescList #-} -- Inline for list fusion
3627+
36083628data Stack a
36093629 = Nada
36103630 | Push {- # UNPACK #-} !Int ! (IntMap a ) ! (Stack a )
@@ -3647,6 +3667,40 @@ ascLinkStack stk !rk r = case stk of
36473667 where
36483668 p = mask rk m
36493669
3670+ -- Insert an entry. The key must be <= the last inserted key. If it is equal
3671+ -- to the previous key, the previous value is replaced.
3672+ descInsert :: Int -> a -> MonoState a -> MonoState a
3673+ descInsert ! ky y s = case s of
3674+ MSNada -> MSPush ky y Nada
3675+ MSPush kx x stk
3676+ | kx == ky -> MSPush ky y stk
3677+ | otherwise -> let m = branchMask kx ky
3678+ in MSPush ky y (descLinkTop kx (Tip kx x) m stk)
3679+ {-# INLINE descInsert #-}
3680+
3681+ descLinkTop :: Int -> IntMap a -> Int -> Stack a -> Stack a
3682+ descLinkTop ! lk l ! lm stk = case stk of
3683+ Nada -> Push lm l stk
3684+ Push m r stk'
3685+ | i2w m < i2w lm -> let p = mask lk m
3686+ in descLinkTop lk (Bin p l r) lm stk'
3687+ | otherwise -> Push lm l stk
3688+
3689+ descLinkAll :: MonoState a -> IntMap a
3690+ descLinkAll s = case s of
3691+ MSNada -> Nil
3692+ MSPush kx x stk -> descLinkStack kx (Tip kx x) stk
3693+ {-# INLINABLE descLinkAll #-}
3694+
3695+ descLinkStack :: Int -> IntMap a -> Stack a -> IntMap a
3696+ descLinkStack ! lk l stk = case stk of
3697+ Nada -> l
3698+ Push m r stk'
3699+ | signBranch p -> Bin p r l
3700+ | otherwise -> descLinkStack lk (Bin p l r) stk'
3701+ where
3702+ p = mask lk m
3703+
36503704{- -------------------------------------------------------------------
36513705 IntMapBuilder
36523706--------------------------------------------------------------------}
0 commit comments