1 {-# OPTIONS -cpp -fglasgow-exts -fno-bang-patterns #-}
2 -----------------------------------------------------------------------------
3 -- Module : Data.IntMap
4 -- Copyright : (c) Daan Leijen 2002
6 -- Maintainer : libraries@haskell.org
7 -- Stability : provisional
8 -- Portability : portable
10 -- An efficient implementation of maps from integer keys to values.
12 -- This module is intended to be imported @qualified@, to avoid name
13 -- clashes with "Prelude" functions. eg.
15 -- > import Data.IntMap as Map
17 -- The implementation is based on /big-endian patricia trees/. This data
18 -- structure performs especially well on binary operations like 'union'
19 -- and 'intersection'. However, my benchmarks show that it is also
20 -- (much) faster on insertions and deletions when compared to a generic
21 -- size-balanced map implementation (see "Data.Map" and "Data.FiniteMap").
23 -- * Chris Okasaki and Andy Gill, \"/Fast Mergeable Integer Maps/\",
24 -- Workshop on ML, September 1998, pages 77-86,
25 -- <http://www.cse.ogi.edu/~andy/pub/finite.htm>
27 -- * D.R. Morrison, \"/PATRICIA -- Practical Algorithm To Retrieve
28 -- Information Coded In Alphanumeric/\", Journal of the ACM, 15(4),
29 -- October 1968, pages 514-534.
31 -- Many operations have a worst-case complexity of /O(min(n,W))/.
32 -- This means that the operation can become linear in the number of
33 -- elements with a maximum of /W/ -- the number of bits in an 'Int'
35 -----------------------------------------------------------------------------
39 IntMap, Key -- instance Eq,Show
58 , insertWith, insertWithKey, insertLookupWithKey
115 , fromDistinctAscList
127 , isSubmapOf, isSubmapOfBy
128 , isProperSubmapOf, isProperSubmapOfBy
136 import Prelude hiding (lookup,map,filter,foldr,foldl,null)
139 import qualified Data.IntSet as IntSet
140 import Data.Monoid (Monoid(..))
142 import Data.Foldable (Foldable(foldMap))
146 import qualified Prelude
147 import Debug.QuickCheck
148 import List (nub,sort)
149 import qualified List
152 #if __GLASGOW_HASKELL__
154 import Data.Generics.Basics
155 import Data.Generics.Instances
158 #if __GLASGOW_HASKELL__ >= 503
160 import GHC.Exts ( Word(..), Int(..), shiftRL# )
161 #elif __GLASGOW_HASKELL__
163 import GlaExts ( Word(..), Int(..), shiftRL# )
168 infixl 9 \\{-This comment teaches CPP correct behaviour -}
170 -- A "Nat" is a natural machine word (an unsigned Int)
173 natFromInt :: Key -> Nat
174 natFromInt i = fromIntegral i
176 intFromNat :: Nat -> Key
177 intFromNat w = fromIntegral w
179 shiftRL :: Nat -> Key -> Nat
180 #if __GLASGOW_HASKELL__
181 {--------------------------------------------------------------------
182 GHC: use unboxing to get @shiftRL@ inlined.
183 --------------------------------------------------------------------}
184 shiftRL (W# x) (I# i)
187 shiftRL x i = shiftR x i
190 {--------------------------------------------------------------------
192 --------------------------------------------------------------------}
194 -- | /O(min(n,W))/. Find the value at a key.
195 -- Calls 'error' when the element can not be found.
197 (!) :: IntMap a -> Key -> a
200 -- | /O(n+m)/. See 'difference'.
201 (\\) :: IntMap a -> IntMap b -> IntMap a
202 m1 \\ m2 = difference m1 m2
204 {--------------------------------------------------------------------
206 --------------------------------------------------------------------}
207 -- | A map of integers to values @a@.
209 | Tip {-# UNPACK #-} !Key a
210 | Bin {-# UNPACK #-} !Prefix {-# UNPACK #-} !Mask !(IntMap a) !(IntMap a)
216 instance Monoid (IntMap a) where
221 instance Foldable IntMap where
222 foldMap f Nil = mempty
223 foldMap f (Tip _k v) = f v
224 foldMap f (Bin _ _ l r) = foldMap f l `mappend` foldMap f r
226 #if __GLASGOW_HASKELL__
228 {--------------------------------------------------------------------
230 --------------------------------------------------------------------}
232 -- This instance preserves data abstraction at the cost of inefficiency.
233 -- We omit reflection services for the sake of data abstraction.
235 instance Data a => Data (IntMap a) where
236 gfoldl f z im = z fromList `f` (toList im)
237 toConstr _ = error "toConstr"
238 gunfold _ _ = error "gunfold"
239 dataTypeOf _ = mkNorepType "Data.IntMap.IntMap"
240 dataCast1 f = gcast1 f
244 {--------------------------------------------------------------------
246 --------------------------------------------------------------------}
247 -- | /O(1)/. Is the map empty?
248 null :: IntMap a -> Bool
252 -- | /O(n)/. Number of elements in the map.
253 size :: IntMap a -> Int
256 Bin p m l r -> size l + size r
260 -- | /O(min(n,W))/. Is the key a member of the map?
261 member :: Key -> IntMap a -> Bool
267 -- | /O(log n)/. Is the key not a member of the map?
268 notMember :: Key -> IntMap a -> Bool
269 notMember k m = not $ member k m
271 -- | /O(min(n,W))/. Lookup the value at a key in the map.
272 lookup :: (Monad m) => Key -> IntMap a -> m a
273 lookup k t = case lookup' k t of
275 Nothing -> fail "Data.IntMap.lookup: Key not found"
277 lookup' :: Key -> IntMap a -> Maybe a
279 = let nk = natFromInt k in seq nk (lookupN nk t)
281 lookupN :: Nat -> IntMap a -> Maybe a
285 | zeroN k (natFromInt m) -> lookupN k l
286 | otherwise -> lookupN k r
288 | (k == natFromInt kx) -> Just x
289 | otherwise -> Nothing
292 find' :: Key -> IntMap a -> a
295 Nothing -> error ("IntMap.find: key " ++ show k ++ " is not an element of the map")
299 -- | /O(min(n,W))/. The expression @('findWithDefault' def k map)@
300 -- returns the value at key @k@ or returns @def@ when the key is not an
301 -- element of the map.
302 findWithDefault :: a -> Key -> IntMap a -> a
303 findWithDefault def k m
308 {--------------------------------------------------------------------
310 --------------------------------------------------------------------}
311 -- | /O(1)/. The empty map.
316 -- | /O(1)/. A map of one element.
317 singleton :: Key -> a -> IntMap a
321 {--------------------------------------------------------------------
323 --------------------------------------------------------------------}
324 -- | /O(min(n,W))/. Insert a new key\/value pair in the map.
325 -- If the key is already present in the map, the associated value is
326 -- replaced with the supplied value, i.e. 'insert' is equivalent to
327 -- @'insertWith' 'const'@.
328 insert :: Key -> a -> IntMap a -> IntMap a
332 | nomatch k p m -> join k (Tip k x) p t
333 | zero k m -> Bin p m (insert k x l) r
334 | otherwise -> Bin p m l (insert k x r)
337 | otherwise -> join k (Tip k x) ky t
340 -- right-biased insertion, used by 'union'
341 -- | /O(min(n,W))/. Insert with a combining function.
342 -- @'insertWith' f key value mp@
343 -- will insert the pair (key, value) into @mp@ if key does
344 -- not exist in the map. If the key does exist, the function will
345 -- insert @f new_value old_value@.
346 insertWith :: (a -> a -> a) -> Key -> a -> IntMap a -> IntMap a
348 = insertWithKey (\k x y -> f x y) k x t
350 -- | /O(min(n,W))/. Insert with a combining function.
351 -- @'insertWithKey' f key value mp@
352 -- will insert the pair (key, value) into @mp@ if key does
353 -- not exist in the map. If the key does exist, the function will
354 -- insert @f key new_value old_value@.
355 insertWithKey :: (Key -> a -> a -> a) -> Key -> a -> IntMap a -> IntMap a
356 insertWithKey f k x t
359 | nomatch k p m -> join k (Tip k x) p t
360 | zero k m -> Bin p m (insertWithKey f k x l) r
361 | otherwise -> Bin p m l (insertWithKey f k x r)
363 | k==ky -> Tip k (f k x y)
364 | otherwise -> join k (Tip k x) ky t
368 -- | /O(min(n,W))/. The expression (@'insertLookupWithKey' f k x map@)
369 -- is a pair where the first element is equal to (@'lookup' k map@)
370 -- and the second element equal to (@'insertWithKey' f k x map@).
371 insertLookupWithKey :: (Key -> a -> a -> a) -> Key -> a -> IntMap a -> (Maybe a, IntMap a)
372 insertLookupWithKey f k x t
375 | nomatch k p m -> (Nothing,join k (Tip k x) p t)
376 | zero k m -> let (found,l') = insertLookupWithKey f k x l in (found,Bin p m l' r)
377 | otherwise -> let (found,r') = insertLookupWithKey f k x r in (found,Bin p m l r')
379 | k==ky -> (Just y,Tip k (f k x y))
380 | otherwise -> (Nothing,join k (Tip k x) ky t)
381 Nil -> (Nothing,Tip k x)
384 {--------------------------------------------------------------------
386 [delete] is the inlined version of [deleteWith (\k x -> Nothing)]
387 --------------------------------------------------------------------}
388 -- | /O(min(n,W))/. Delete a key and its value from the map. When the key is not
389 -- a member of the map, the original map is returned.
390 delete :: Key -> IntMap a -> IntMap a
395 | zero k m -> bin p m (delete k l) r
396 | otherwise -> bin p m l (delete k r)
402 -- | /O(min(n,W))/. Adjust a value at a specific key. When the key is not
403 -- a member of the map, the original map is returned.
404 adjust :: (a -> a) -> Key -> IntMap a -> IntMap a
406 = adjustWithKey (\k x -> f x) k m
408 -- | /O(min(n,W))/. Adjust a value at a specific key. When the key is not
409 -- a member of the map, the original map is returned.
410 adjustWithKey :: (Key -> a -> a) -> Key -> IntMap a -> IntMap a
412 = updateWithKey (\k x -> Just (f k x)) k m
414 -- | /O(min(n,W))/. The expression (@'update' f k map@) updates the value @x@
415 -- at @k@ (if it is in the map). If (@f x@) is 'Nothing', the element is
416 -- deleted. If it is (@'Just' y@), the key @k@ is bound to the new value @y@.
417 update :: (a -> Maybe a) -> Key -> IntMap a -> IntMap a
419 = updateWithKey (\k x -> f x) k m
421 -- | /O(min(n,W))/. The expression (@'update' f k map@) updates the value @x@
422 -- at @k@ (if it is in the map). If (@f k x@) is 'Nothing', the element is
423 -- deleted. If it is (@'Just' y@), the key @k@ is bound to the new value @y@.
424 updateWithKey :: (Key -> a -> Maybe a) -> Key -> IntMap a -> IntMap a
429 | zero k m -> bin p m (updateWithKey f k l) r
430 | otherwise -> bin p m l (updateWithKey f k r)
432 | k==ky -> case (f k y) of
438 -- | /O(min(n,W))/. Lookup and update.
439 updateLookupWithKey :: (Key -> a -> Maybe a) -> Key -> IntMap a -> (Maybe a,IntMap a)
440 updateLookupWithKey f k t
443 | nomatch k p m -> (Nothing,t)
444 | zero k m -> let (found,l') = updateLookupWithKey f k l in (found,bin p m l' r)
445 | otherwise -> let (found,r') = updateLookupWithKey f k r in (found,bin p m l r')
447 | k==ky -> case (f k y) of
448 Just y' -> (Just y,Tip ky y')
449 Nothing -> (Just y,Nil)
450 | otherwise -> (Nothing,t)
454 {--------------------------------------------------------------------
456 --------------------------------------------------------------------}
457 -- | The union of a list of maps.
458 unions :: [IntMap a] -> IntMap a
460 = foldlStrict union empty xs
462 -- | The union of a list of maps, with a combining operation
463 unionsWith :: (a->a->a) -> [IntMap a] -> IntMap a
465 = foldlStrict (unionWith f) empty ts
467 -- | /O(n+m)/. The (left-biased) union of two maps.
468 -- It prefers the first map when duplicate keys are encountered,
469 -- i.e. (@'union' == 'unionWith' 'const'@).
470 union :: IntMap a -> IntMap a -> IntMap a
471 union t1@(Bin p1 m1 l1 r1) t2@(Bin p2 m2 l2 r2)
472 | shorter m1 m2 = union1
473 | shorter m2 m1 = union2
474 | p1 == p2 = Bin p1 m1 (union l1 l2) (union r1 r2)
475 | otherwise = join p1 t1 p2 t2
477 union1 | nomatch p2 p1 m1 = join p1 t1 p2 t2
478 | zero p2 m1 = Bin p1 m1 (union l1 t2) r1
479 | otherwise = Bin p1 m1 l1 (union r1 t2)
481 union2 | nomatch p1 p2 m2 = join p1 t1 p2 t2
482 | zero p1 m2 = Bin p2 m2 (union t1 l2) r2
483 | otherwise = Bin p2 m2 l2 (union t1 r2)
485 union (Tip k x) t = insert k x t
486 union t (Tip k x) = insertWith (\x y -> y) k x t -- right bias
490 -- | /O(n+m)/. The union with a combining function.
491 unionWith :: (a -> a -> a) -> IntMap a -> IntMap a -> IntMap a
493 = unionWithKey (\k x y -> f x y) m1 m2
495 -- | /O(n+m)/. The union with a combining function.
496 unionWithKey :: (Key -> a -> a -> a) -> IntMap a -> IntMap a -> IntMap a
497 unionWithKey f t1@(Bin p1 m1 l1 r1) t2@(Bin p2 m2 l2 r2)
498 | shorter m1 m2 = union1
499 | shorter m2 m1 = union2
500 | p1 == p2 = Bin p1 m1 (unionWithKey f l1 l2) (unionWithKey f r1 r2)
501 | otherwise = join p1 t1 p2 t2
503 union1 | nomatch p2 p1 m1 = join p1 t1 p2 t2
504 | zero p2 m1 = Bin p1 m1 (unionWithKey f l1 t2) r1
505 | otherwise = Bin p1 m1 l1 (unionWithKey f r1 t2)
507 union2 | nomatch p1 p2 m2 = join p1 t1 p2 t2
508 | zero p1 m2 = Bin p2 m2 (unionWithKey f t1 l2) r2
509 | otherwise = Bin p2 m2 l2 (unionWithKey f t1 r2)
511 unionWithKey f (Tip k x) t = insertWithKey f k x t
512 unionWithKey f t (Tip k x) = insertWithKey (\k x y -> f k y x) k x t -- right bias
513 unionWithKey f Nil t = t
514 unionWithKey f t Nil = t
516 {--------------------------------------------------------------------
518 --------------------------------------------------------------------}
519 -- | /O(n+m)/. Difference between two maps (based on keys).
520 difference :: IntMap a -> IntMap b -> IntMap a
521 difference t1@(Bin p1 m1 l1 r1) t2@(Bin p2 m2 l2 r2)
522 | shorter m1 m2 = difference1
523 | shorter m2 m1 = difference2
524 | p1 == p2 = bin p1 m1 (difference l1 l2) (difference r1 r2)
527 difference1 | nomatch p2 p1 m1 = t1
528 | zero p2 m1 = bin p1 m1 (difference l1 t2) r1
529 | otherwise = bin p1 m1 l1 (difference r1 t2)
531 difference2 | nomatch p1 p2 m2 = t1
532 | zero p1 m2 = difference t1 l2
533 | otherwise = difference t1 r2
535 difference t1@(Tip k x) t2
539 difference Nil t = Nil
540 difference t (Tip k x) = delete k t
543 -- | /O(n+m)/. Difference with a combining function.
544 differenceWith :: (a -> b -> Maybe a) -> IntMap a -> IntMap b -> IntMap a
545 differenceWith f m1 m2
546 = differenceWithKey (\k x y -> f x y) m1 m2
548 -- | /O(n+m)/. Difference with a combining function. When two equal keys are
549 -- encountered, the combining function is applied to the key and both values.
550 -- If it returns 'Nothing', the element is discarded (proper set difference).
551 -- If it returns (@'Just' y@), the element is updated with a new value @y@.
552 differenceWithKey :: (Key -> a -> b -> Maybe a) -> IntMap a -> IntMap b -> IntMap a
553 differenceWithKey f t1@(Bin p1 m1 l1 r1) t2@(Bin p2 m2 l2 r2)
554 | shorter m1 m2 = difference1
555 | shorter m2 m1 = difference2
556 | p1 == p2 = bin p1 m1 (differenceWithKey f l1 l2) (differenceWithKey f r1 r2)
559 difference1 | nomatch p2 p1 m1 = t1
560 | zero p2 m1 = bin p1 m1 (differenceWithKey f l1 t2) r1
561 | otherwise = bin p1 m1 l1 (differenceWithKey f r1 t2)
563 difference2 | nomatch p1 p2 m2 = t1
564 | zero p1 m2 = differenceWithKey f t1 l2
565 | otherwise = differenceWithKey f t1 r2
567 differenceWithKey f t1@(Tip k x) t2
568 = case lookup k t2 of
569 Just y -> case f k x y of
574 differenceWithKey f Nil t = Nil
575 differenceWithKey f t (Tip k y) = updateWithKey (\k x -> f k x y) k t
576 differenceWithKey f t Nil = t
579 {--------------------------------------------------------------------
581 --------------------------------------------------------------------}
582 -- | /O(n+m)/. The (left-biased) intersection of two maps (based on keys).
583 intersection :: IntMap a -> IntMap b -> IntMap a
584 intersection t1@(Bin p1 m1 l1 r1) t2@(Bin p2 m2 l2 r2)
585 | shorter m1 m2 = intersection1
586 | shorter m2 m1 = intersection2
587 | p1 == p2 = bin p1 m1 (intersection l1 l2) (intersection r1 r2)
590 intersection1 | nomatch p2 p1 m1 = Nil
591 | zero p2 m1 = intersection l1 t2
592 | otherwise = intersection r1 t2
594 intersection2 | nomatch p1 p2 m2 = Nil
595 | zero p1 m2 = intersection t1 l2
596 | otherwise = intersection t1 r2
598 intersection t1@(Tip k x) t2
601 intersection t (Tip k x)
605 intersection Nil t = Nil
606 intersection t Nil = Nil
608 -- | /O(n+m)/. The intersection with a combining function.
609 intersectionWith :: (a -> b -> a) -> IntMap a -> IntMap b -> IntMap a
610 intersectionWith f m1 m2
611 = intersectionWithKey (\k x y -> f x y) m1 m2
613 -- | /O(n+m)/. The intersection with a combining function.
614 intersectionWithKey :: (Key -> a -> b -> a) -> IntMap a -> IntMap b -> IntMap a
615 intersectionWithKey f t1@(Bin p1 m1 l1 r1) t2@(Bin p2 m2 l2 r2)
616 | shorter m1 m2 = intersection1
617 | shorter m2 m1 = intersection2
618 | p1 == p2 = bin p1 m1 (intersectionWithKey f l1 l2) (intersectionWithKey f r1 r2)
621 intersection1 | nomatch p2 p1 m1 = Nil
622 | zero p2 m1 = intersectionWithKey f l1 t2
623 | otherwise = intersectionWithKey f r1 t2
625 intersection2 | nomatch p1 p2 m2 = Nil
626 | zero p1 m2 = intersectionWithKey f t1 l2
627 | otherwise = intersectionWithKey f t1 r2
629 intersectionWithKey f t1@(Tip k x) t2
630 = case lookup k t2 of
631 Just y -> Tip k (f k x y)
633 intersectionWithKey f t1 (Tip k y)
634 = case lookup k t1 of
635 Just x -> Tip k (f k x y)
637 intersectionWithKey f Nil t = Nil
638 intersectionWithKey f t Nil = Nil
641 {--------------------------------------------------------------------
643 --------------------------------------------------------------------}
644 -- | /O(n+m)/. Is this a proper submap? (ie. a submap but not equal).
645 -- Defined as (@'isProperSubmapOf' = 'isProperSubmapOfBy' (==)@).
646 isProperSubmapOf :: Eq a => IntMap a -> IntMap a -> Bool
647 isProperSubmapOf m1 m2
648 = isProperSubmapOfBy (==) m1 m2
650 {- | /O(n+m)/. Is this a proper submap? (ie. a submap but not equal).
651 The expression (@'isProperSubmapOfBy' f m1 m2@) returns 'True' when
652 @m1@ and @m2@ are not equal,
653 all keys in @m1@ are in @m2@, and when @f@ returns 'True' when
654 applied to their respective values. For example, the following
655 expressions are all 'True':
657 > isProperSubmapOfBy (==) (fromList [(1,1)]) (fromList [(1,1),(2,2)])
658 > isProperSubmapOfBy (<=) (fromList [(1,1)]) (fromList [(1,1),(2,2)])
660 But the following are all 'False':
662 > isProperSubmapOfBy (==) (fromList [(1,1),(2,2)]) (fromList [(1,1),(2,2)])
663 > isProperSubmapOfBy (==) (fromList [(1,1),(2,2)]) (fromList [(1,1)])
664 > isProperSubmapOfBy (<) (fromList [(1,1)]) (fromList [(1,1),(2,2)])
666 isProperSubmapOfBy :: (a -> b -> Bool) -> IntMap a -> IntMap b -> Bool
667 isProperSubmapOfBy pred t1 t2
668 = case submapCmp pred t1 t2 of
672 submapCmp pred t1@(Bin p1 m1 l1 r1) t2@(Bin p2 m2 l2 r2)
674 | shorter m2 m1 = submapCmpLt
675 | p1 == p2 = submapCmpEq
676 | otherwise = GT -- disjoint
678 submapCmpLt | nomatch p1 p2 m2 = GT
679 | zero p1 m2 = submapCmp pred t1 l2
680 | otherwise = submapCmp pred t1 r2
681 submapCmpEq = case (submapCmp pred l1 l2, submapCmp pred r1 r2) of
687 submapCmp pred (Bin p m l r) t = GT
688 submapCmp pred (Tip kx x) (Tip ky y)
689 | (kx == ky) && pred x y = EQ
690 | otherwise = GT -- disjoint
691 submapCmp pred (Tip k x) t
693 Just y | pred x y -> LT
694 other -> GT -- disjoint
695 submapCmp pred Nil Nil = EQ
696 submapCmp pred Nil t = LT
698 -- | /O(n+m)/. Is this a submap?
699 -- Defined as (@'isSubmapOf' = 'isSubmapOfBy' (==)@).
700 isSubmapOf :: Eq a => IntMap a -> IntMap a -> Bool
702 = isSubmapOfBy (==) m1 m2
705 The expression (@'isSubmapOfBy' f m1 m2@) returns 'True' if
706 all keys in @m1@ are in @m2@, and when @f@ returns 'True' when
707 applied to their respective values. For example, the following
708 expressions are all 'True':
710 > isSubmapOfBy (==) (fromList [(1,1)]) (fromList [(1,1),(2,2)])
711 > isSubmapOfBy (<=) (fromList [(1,1)]) (fromList [(1,1),(2,2)])
712 > isSubmapOfBy (==) (fromList [(1,1),(2,2)]) (fromList [(1,1),(2,2)])
714 But the following are all 'False':
716 > isSubmapOfBy (==) (fromList [(1,2)]) (fromList [(1,1),(2,2)])
717 > isSubmapOfBy (<) (fromList [(1,1)]) (fromList [(1,1),(2,2)])
718 > isSubmapOfBy (==) (fromList [(1,1),(2,2)]) (fromList [(1,1)])
721 isSubmapOfBy :: (a -> b -> Bool) -> IntMap a -> IntMap b -> Bool
722 isSubmapOfBy pred t1@(Bin p1 m1 l1 r1) t2@(Bin p2 m2 l2 r2)
723 | shorter m1 m2 = False
724 | shorter m2 m1 = match p1 p2 m2 && (if zero p1 m2 then isSubmapOfBy pred t1 l2
725 else isSubmapOfBy pred t1 r2)
726 | otherwise = (p1==p2) && isSubmapOfBy pred l1 l2 && isSubmapOfBy pred r1 r2
727 isSubmapOfBy pred (Bin p m l r) t = False
728 isSubmapOfBy pred (Tip k x) t = case lookup k t of
731 isSubmapOfBy pred Nil t = True
733 {--------------------------------------------------------------------
735 --------------------------------------------------------------------}
736 -- | /O(n)/. Map a function over all values in the map.
737 map :: (a -> b) -> IntMap a -> IntMap b
739 = mapWithKey (\k x -> f x) m
741 -- | /O(n)/. Map a function over all values in the map.
742 mapWithKey :: (Key -> a -> b) -> IntMap a -> IntMap b
745 Bin p m l r -> Bin p m (mapWithKey f l) (mapWithKey f r)
746 Tip k x -> Tip k (f k x)
749 -- | /O(n)/. The function @'mapAccum'@ threads an accumulating
750 -- argument through the map in ascending order of keys.
751 mapAccum :: (a -> b -> (a,c)) -> a -> IntMap b -> (a,IntMap c)
753 = mapAccumWithKey (\a k x -> f a x) a m
755 -- | /O(n)/. The function @'mapAccumWithKey'@ threads an accumulating
756 -- argument through the map in ascending order of keys.
757 mapAccumWithKey :: (a -> Key -> b -> (a,c)) -> a -> IntMap b -> (a,IntMap c)
758 mapAccumWithKey f a t
761 -- | /O(n)/. The function @'mapAccumL'@ threads an accumulating
762 -- argument through the map in ascending order of keys.
763 mapAccumL :: (a -> Key -> b -> (a,c)) -> a -> IntMap b -> (a,IntMap c)
766 Bin p m l r -> let (a1,l') = mapAccumL f a l
767 (a2,r') = mapAccumL f a1 r
768 in (a2,Bin p m l' r')
769 Tip k x -> let (a',x') = f a k x in (a',Tip k x')
773 -- | /O(n)/. The function @'mapAccumR'@ threads an accumulating
774 -- argument throught the map in descending order of keys.
775 mapAccumR :: (a -> Key -> b -> (a,c)) -> a -> IntMap b -> (a,IntMap c)
778 Bin p m l r -> let (a1,r') = mapAccumR f a r
779 (a2,l') = mapAccumR f a1 l
780 in (a2,Bin p m l' r')
781 Tip k x -> let (a',x') = f a k x in (a',Tip k x')
784 {--------------------------------------------------------------------
786 --------------------------------------------------------------------}
787 -- | /O(n)/. Filter all values that satisfy some predicate.
788 filter :: (a -> Bool) -> IntMap a -> IntMap a
790 = filterWithKey (\k x -> p x) m
792 -- | /O(n)/. Filter all keys\/values that satisfy some predicate.
793 filterWithKey :: (Key -> a -> Bool) -> IntMap a -> IntMap a
797 -> bin p m (filterWithKey pred l) (filterWithKey pred r)
803 -- | /O(n)/. partition the map according to some predicate. The first
804 -- map contains all elements that satisfy the predicate, the second all
805 -- elements that fail the predicate. See also 'split'.
806 partition :: (a -> Bool) -> IntMap a -> (IntMap a,IntMap a)
808 = partitionWithKey (\k x -> p x) m
810 -- | /O(n)/. partition the map according to some predicate. The first
811 -- map contains all elements that satisfy the predicate, the second all
812 -- elements that fail the predicate. See also 'split'.
813 partitionWithKey :: (Key -> a -> Bool) -> IntMap a -> (IntMap a,IntMap a)
814 partitionWithKey pred t
817 -> let (l1,l2) = partitionWithKey pred l
818 (r1,r2) = partitionWithKey pred r
819 in (bin p m l1 r1, bin p m l2 r2)
821 | pred k x -> (t,Nil)
822 | otherwise -> (Nil,t)
826 -- | /O(log n)/. The expression (@'split' k map@) is a pair @(map1,map2)@
827 -- where all keys in @map1@ are lower than @k@ and all keys in
828 -- @map2@ larger than @k@. Any key equal to @k@ is found in neither @map1@ nor @map2@.
829 split :: Key -> IntMap a -> (IntMap a,IntMap a)
833 | m < 0 -> (if k >= 0 -- handle negative numbers.
834 then let (lt,gt) = split' k l in (union r lt, gt)
835 else let (lt,gt) = split' k r in (lt, union gt l))
836 | otherwise -> split' k t
840 | otherwise -> (Nil,Nil)
843 split' :: Key -> IntMap a -> (IntMap a,IntMap a)
847 | nomatch k p m -> if k>p then (t,Nil) else (Nil,t)
848 | zero k m -> let (lt,gt) = split k l in (lt,union gt r)
849 | otherwise -> let (lt,gt) = split k r in (union l lt,gt)
853 | otherwise -> (Nil,Nil)
856 -- | /O(log n)/. Performs a 'split' but also returns whether the pivot
857 -- key was found in the original map.
858 splitLookup :: Key -> IntMap a -> (IntMap a,Maybe a,IntMap a)
862 | m < 0 -> (if k >= 0 -- handle negative numbers.
863 then let (lt,found,gt) = splitLookup' k l in (union r lt,found, gt)
864 else let (lt,found,gt) = splitLookup' k r in (lt,found, union gt l))
865 | otherwise -> splitLookup' k t
867 | k>ky -> (t,Nothing,Nil)
868 | k<ky -> (Nil,Nothing,t)
869 | otherwise -> (Nil,Just y,Nil)
870 Nil -> (Nil,Nothing,Nil)
872 splitLookup' :: Key -> IntMap a -> (IntMap a,Maybe a,IntMap a)
876 | nomatch k p m -> if k>p then (t,Nothing,Nil) else (Nil,Nothing,t)
877 | zero k m -> let (lt,found,gt) = splitLookup k l in (lt,found,union gt r)
878 | otherwise -> let (lt,found,gt) = splitLookup k r in (union l lt,found,gt)
880 | k>ky -> (t,Nothing,Nil)
881 | k<ky -> (Nil,Nothing,t)
882 | otherwise -> (Nil,Just y,Nil)
883 Nil -> (Nil,Nothing,Nil)
885 {--------------------------------------------------------------------
887 --------------------------------------------------------------------}
888 -- | /O(n)/. Fold the values in the map, such that
889 -- @'fold' f z == 'Prelude.foldr' f z . 'elems'@.
892 -- > elems map = fold (:) [] map
894 fold :: (a -> b -> b) -> b -> IntMap a -> b
896 = foldWithKey (\k x y -> f x y) z t
898 -- | /O(n)/. Fold the keys and values in the map, such that
899 -- @'foldWithKey' f z == 'Prelude.foldr' ('uncurry' f) z . 'toAscList'@.
902 -- > keys map = foldWithKey (\k x ks -> k:ks) [] map
904 foldWithKey :: (Key -> a -> b -> b) -> b -> IntMap a -> b
908 foldr :: (Key -> a -> b -> b) -> b -> IntMap a -> b
911 Bin 0 m l r | m < 0 -> foldr' f (foldr' f z l) r -- put negative numbers before.
912 Bin _ _ _ _ -> foldr' f z t
916 foldr' :: (Key -> a -> b -> b) -> b -> IntMap a -> b
919 Bin p m l r -> foldr' f (foldr' f z r) l
925 {--------------------------------------------------------------------
927 --------------------------------------------------------------------}
929 -- Return all elements of the map in the ascending order of their keys.
930 elems :: IntMap a -> [a]
932 = foldWithKey (\k x xs -> x:xs) [] m
934 -- | /O(n)/. Return all keys of the map in ascending order.
935 keys :: IntMap a -> [Key]
937 = foldWithKey (\k x ks -> k:ks) [] m
939 -- | /O(n*min(n,W))/. The set of all keys of the map.
940 keysSet :: IntMap a -> IntSet.IntSet
941 keysSet m = IntSet.fromDistinctAscList (keys m)
944 -- | /O(n)/. Return all key\/value pairs in the map in ascending key order.
945 assocs :: IntMap a -> [(Key,a)]
950 {--------------------------------------------------------------------
952 --------------------------------------------------------------------}
953 -- | /O(n)/. Convert the map to a list of key\/value pairs.
954 toList :: IntMap a -> [(Key,a)]
956 = foldWithKey (\k x xs -> (k,x):xs) [] t
958 -- | /O(n)/. Convert the map to a list of key\/value pairs where the
959 -- keys are in ascending order.
960 toAscList :: IntMap a -> [(Key,a)]
962 = -- NOTE: the following algorithm only works for big-endian trees
963 let (pos,neg) = span (\(k,x) -> k >=0) (foldr (\k x xs -> (k,x):xs) [] t) in neg ++ pos
965 -- | /O(n*min(n,W))/. Create a map from a list of key\/value pairs.
966 fromList :: [(Key,a)] -> IntMap a
968 = foldlStrict ins empty xs
970 ins t (k,x) = insert k x t
972 -- | /O(n*min(n,W))/. Create a map from a list of key\/value pairs with a combining function. See also 'fromAscListWith'.
973 fromListWith :: (a -> a -> a) -> [(Key,a)] -> IntMap a
975 = fromListWithKey (\k x y -> f x y) xs
977 -- | /O(n*min(n,W))/. Build a map from a list of key\/value pairs with a combining function. See also fromAscListWithKey'.
978 fromListWithKey :: (Key -> a -> a -> a) -> [(Key,a)] -> IntMap a
980 = foldlStrict ins empty xs
982 ins t (k,x) = insertWithKey f k x t
984 -- | /O(n*min(n,W))/. Build a map from a list of key\/value pairs where
985 -- the keys are in ascending order.
986 fromAscList :: [(Key,a)] -> IntMap a
990 -- | /O(n*min(n,W))/. Build a map from a list of key\/value pairs where
991 -- the keys are in ascending order, with a combining function on equal keys.
992 fromAscListWith :: (a -> a -> a) -> [(Key,a)] -> IntMap a
996 -- | /O(n*min(n,W))/. Build a map from a list of key\/value pairs where
997 -- the keys are in ascending order, with a combining function on equal keys.
998 fromAscListWithKey :: (Key -> a -> a -> a) -> [(Key,a)] -> IntMap a
999 fromAscListWithKey f xs
1000 = fromListWithKey f xs
1002 -- | /O(n*min(n,W))/. Build a map from a list of key\/value pairs where
1003 -- the keys are in ascending order and all distinct.
1004 fromDistinctAscList :: [(Key,a)] -> IntMap a
1005 fromDistinctAscList xs
1009 {--------------------------------------------------------------------
1011 --------------------------------------------------------------------}
1012 instance Eq a => Eq (IntMap a) where
1013 t1 == t2 = equal t1 t2
1014 t1 /= t2 = nequal t1 t2
1016 equal :: Eq a => IntMap a -> IntMap a -> Bool
1017 equal (Bin p1 m1 l1 r1) (Bin p2 m2 l2 r2)
1018 = (m1 == m2) && (p1 == p2) && (equal l1 l2) && (equal r1 r2)
1019 equal (Tip kx x) (Tip ky y)
1020 = (kx == ky) && (x==y)
1021 equal Nil Nil = True
1024 nequal :: Eq a => IntMap a -> IntMap a -> Bool
1025 nequal (Bin p1 m1 l1 r1) (Bin p2 m2 l2 r2)
1026 = (m1 /= m2) || (p1 /= p2) || (nequal l1 l2) || (nequal r1 r2)
1027 nequal (Tip kx x) (Tip ky y)
1028 = (kx /= ky) || (x/=y)
1029 nequal Nil Nil = False
1032 {--------------------------------------------------------------------
1034 --------------------------------------------------------------------}
1036 instance Ord a => Ord (IntMap a) where
1037 compare m1 m2 = compare (toList m1) (toList m2)
1039 {--------------------------------------------------------------------
1041 --------------------------------------------------------------------}
1043 instance Functor IntMap where
1046 {--------------------------------------------------------------------
1048 --------------------------------------------------------------------}
1050 instance Show a => Show (IntMap a) where
1051 showsPrec d m = showParen (d > 10) $
1052 showString "fromList " . shows (toList m)
1054 showMap :: (Show a) => [(Key,a)] -> ShowS
1058 = showChar '{' . showElem x . showTail xs
1060 showTail [] = showChar '}'
1061 showTail (x:xs) = showChar ',' . showElem x . showTail xs
1063 showElem (k,x) = shows k . showString ":=" . shows x
1065 {--------------------------------------------------------------------
1067 --------------------------------------------------------------------}
1068 instance (Read e) => Read (IntMap e) where
1069 #ifdef __GLASGOW_HASKELL__
1070 readPrec = parens $ prec 10 $ do
1071 Ident "fromList" <- lexP
1073 return (fromList xs)
1075 readListPrec = readListPrecDefault
1077 readsPrec p = readParen (p > 10) $ \ r -> do
1078 ("fromList",s) <- lex r
1080 return (fromList xs,t)
1083 {--------------------------------------------------------------------
1085 --------------------------------------------------------------------}
1087 #include "Typeable.h"
1088 INSTANCE_TYPEABLE1(IntMap,intMapTc,"IntMap")
1090 {--------------------------------------------------------------------
1092 --------------------------------------------------------------------}
1093 -- | /O(n)/. Show the tree that implements the map. The tree is shown
1094 -- in a compressed, hanging format.
1095 showTree :: Show a => IntMap a -> String
1097 = showTreeWith True False s
1100 {- | /O(n)/. The expression (@'showTreeWith' hang wide map@) shows
1101 the tree that implements the map. If @hang@ is
1102 'True', a /hanging/ tree is shown otherwise a rotated tree is shown. If
1103 @wide@ is 'True', an extra wide version is shown.
1105 showTreeWith :: Show a => Bool -> Bool -> IntMap a -> String
1106 showTreeWith hang wide t
1107 | hang = (showsTreeHang wide [] t) ""
1108 | otherwise = (showsTree wide [] [] t) ""
1110 showsTree :: Show a => Bool -> [String] -> [String] -> IntMap a -> ShowS
1111 showsTree wide lbars rbars t
1114 -> showsTree wide (withBar rbars) (withEmpty rbars) r .
1115 showWide wide rbars .
1116 showsBars lbars . showString (showBin p m) . showString "\n" .
1117 showWide wide lbars .
1118 showsTree wide (withEmpty lbars) (withBar lbars) l
1120 -> showsBars lbars . showString " " . shows k . showString ":=" . shows x . showString "\n"
1121 Nil -> showsBars lbars . showString "|\n"
1123 showsTreeHang :: Show a => Bool -> [String] -> IntMap a -> ShowS
1124 showsTreeHang wide bars t
1127 -> showsBars bars . showString (showBin p m) . showString "\n" .
1128 showWide wide bars .
1129 showsTreeHang wide (withBar bars) l .
1130 showWide wide bars .
1131 showsTreeHang wide (withEmpty bars) r
1133 -> showsBars bars . showString " " . shows k . showString ":=" . shows x . showString "\n"
1134 Nil -> showsBars bars . showString "|\n"
1137 = "*" -- ++ show (p,m)
1140 | wide = showString (concat (reverse bars)) . showString "|\n"
1143 showsBars :: [String] -> ShowS
1147 _ -> showString (concat (reverse (tail bars))) . showString node
1150 withBar bars = "| ":bars
1151 withEmpty bars = " ":bars
1154 {--------------------------------------------------------------------
1156 --------------------------------------------------------------------}
1157 {--------------------------------------------------------------------
1159 --------------------------------------------------------------------}
1160 join :: Prefix -> IntMap a -> Prefix -> IntMap a -> IntMap a
1162 | zero p1 m = Bin p m t1 t2
1163 | otherwise = Bin p m t2 t1
1165 m = branchMask p1 p2
1168 {--------------------------------------------------------------------
1169 @bin@ assures that we never have empty trees within a tree.
1170 --------------------------------------------------------------------}
1171 bin :: Prefix -> Mask -> IntMap a -> IntMap a -> IntMap a
1174 bin p m l r = Bin p m l r
1177 {--------------------------------------------------------------------
1178 Endian independent bit twiddling
1179 --------------------------------------------------------------------}
1180 zero :: Key -> Mask -> Bool
1182 = (natFromInt i) .&. (natFromInt m) == 0
1184 nomatch,match :: Key -> Prefix -> Mask -> Bool
1191 mask :: Key -> Mask -> Prefix
1193 = maskW (natFromInt i) (natFromInt m)
1196 zeroN :: Nat -> Nat -> Bool
1197 zeroN i m = (i .&. m) == 0
1199 {--------------------------------------------------------------------
1200 Big endian operations
1201 --------------------------------------------------------------------}
1202 maskW :: Nat -> Nat -> Prefix
1204 = intFromNat (i .&. (complement (m-1) `xor` m))
1206 shorter :: Mask -> Mask -> Bool
1208 = (natFromInt m1) > (natFromInt m2)
1210 branchMask :: Prefix -> Prefix -> Mask
1212 = intFromNat (highestBitMask (natFromInt p1 `xor` natFromInt p2))
1214 {----------------------------------------------------------------------
1215 Finding the highest bit (mask) in a word [x] can be done efficiently in
1217 * convert to a floating point value and the mantissa tells us the
1218 [log2(x)] that corresponds with the highest bit position. The mantissa
1219 is retrieved either via the standard C function [frexp] or by some bit
1220 twiddling on IEEE compatible numbers (float). Note that one needs to
1221 use at least [double] precision for an accurate mantissa of 32 bit
1223 * use bit twiddling, a logarithmic sequence of bitwise or's and shifts (bit).
1224 * use processor specific assembler instruction (asm).
1226 The most portable way would be [bit], but is it efficient enough?
1227 I have measured the cycle counts of the different methods on an AMD
1228 Athlon-XP 1800 (~ Pentium III 1.8Ghz) using the RDTSC instruction:
1230 highestBitMask: method cycles
1237 highestBit: method cycles
1244 Wow, the bit twiddling is on today's RISC like machines even faster
1245 than a single CISC instruction (BSR)!
1246 ----------------------------------------------------------------------}
1248 {----------------------------------------------------------------------
1249 [highestBitMask] returns a word where only the highest bit is set.
1250 It is found by first setting all bits in lower positions than the
1251 highest bit and than taking an exclusive or with the original value.
1252 Allthough the function may look expensive, GHC compiles this into
1253 excellent C code that subsequently compiled into highly efficient
1254 machine code. The algorithm is derived from Jorg Arndt's FXT library.
1255 ----------------------------------------------------------------------}
1256 highestBitMask :: Nat -> Nat
1258 = case (x .|. shiftRL x 1) of
1259 x -> case (x .|. shiftRL x 2) of
1260 x -> case (x .|. shiftRL x 4) of
1261 x -> case (x .|. shiftRL x 8) of
1262 x -> case (x .|. shiftRL x 16) of
1263 x -> case (x .|. shiftRL x 32) of -- for 64 bit platforms
1264 x -> (x `xor` (shiftRL x 1))
1267 {--------------------------------------------------------------------
1269 --------------------------------------------------------------------}
1273 (x:xx) -> let z' = f z x in seq z' (foldlStrict f z' xx)
1276 {--------------------------------------------------------------------
1278 --------------------------------------------------------------------}
1279 testTree :: [Int] -> IntMap Int
1280 testTree xs = fromList [(x,x*x*30696 `mod` 65521) | x <- xs]
1281 test1 = testTree [1..20]
1282 test2 = testTree [30,29..10]
1283 test3 = testTree [1,4,6,89,2323,53,43,234,5,79,12,9,24,9,8,423,8,42,4,8,9,3]
1285 {--------------------------------------------------------------------
1287 --------------------------------------------------------------------}
1292 { configMaxTest = 500
1293 , configMaxFail = 5000
1294 , configSize = \n -> (div n 2 + 3)
1295 , configEvery = \n args -> let s = show n in s ++ [ '\b' | _ <- s ]
1299 {--------------------------------------------------------------------
1300 Arbitrary, reasonably balanced trees
1301 --------------------------------------------------------------------}
1302 instance Arbitrary a => Arbitrary (IntMap a) where
1303 arbitrary = do{ ks <- arbitrary
1304 ; xs <- mapM (\k -> do{ x <- arbitrary; return (k,x)}) ks
1305 ; return (fromList xs)
1309 {--------------------------------------------------------------------
1310 Single, Insert, Delete
1311 --------------------------------------------------------------------}
1312 prop_Single :: Key -> Int -> Bool
1314 = (insert k x empty == singleton k x)
1316 prop_InsertDelete :: Key -> Int -> IntMap Int -> Property
1317 prop_InsertDelete k x t
1318 = not (member k t) ==> delete k (insert k x t) == t
1320 prop_UpdateDelete :: Key -> IntMap Int -> Bool
1321 prop_UpdateDelete k t
1322 = update (const Nothing) k t == delete k t
1325 {--------------------------------------------------------------------
1327 --------------------------------------------------------------------}
1328 prop_UnionInsert :: Key -> Int -> IntMap Int -> Bool
1329 prop_UnionInsert k x t
1330 = union (singleton k x) t == insert k x t
1332 prop_UnionAssoc :: IntMap Int -> IntMap Int -> IntMap Int -> Bool
1333 prop_UnionAssoc t1 t2 t3
1334 = union t1 (union t2 t3) == union (union t1 t2) t3
1336 prop_UnionComm :: IntMap Int -> IntMap Int -> Bool
1337 prop_UnionComm t1 t2
1338 = (union t1 t2 == unionWith (\x y -> y) t2 t1)
1341 prop_Diff :: [(Key,Int)] -> [(Key,Int)] -> Bool
1343 = List.sort (keys (difference (fromListWith (+) xs) (fromListWith (+) ys)))
1344 == List.sort ((List.\\) (nub (Prelude.map fst xs)) (nub (Prelude.map fst ys)))
1346 prop_Int :: [(Key,Int)] -> [(Key,Int)] -> Bool
1348 = List.sort (keys (intersection (fromListWith (+) xs) (fromListWith (+) ys)))
1349 == List.sort (nub ((List.intersect) (Prelude.map fst xs) (Prelude.map fst ys)))
1351 {--------------------------------------------------------------------
1353 --------------------------------------------------------------------}
1355 = forAll (choose (5,100)) $ \n ->
1356 let xs = [(x,()) | x <- [0..n::Int]]
1357 in fromAscList xs == fromList xs
1359 prop_List :: [Key] -> Bool
1361 = (sort (nub xs) == [x | (x,()) <- toAscList (fromList [(x,()) | x <- xs])])