IntervalMap 0.2.3.3 → 0.3.0.0
raw patch · 8 files changed
+1763/−1278 lines, 8 filesPVP ok
version bump matches the API change (PVP)
API changes (from Hackage documentation)
- Data.IntervalMap: (!) :: Ord k => IntervalMap k v -> Interval k -> v
- Data.IntervalMap: (\\) :: Ord k => IntervalMap k a -> IntervalMap k b -> IntervalMap k a
- Data.IntervalMap: ClosedInterval :: !a -> !a -> Interval a
- Data.IntervalMap: IntervalCO :: !a -> !a -> Interval a
- Data.IntervalMap: IntervalOC :: !a -> !a -> Interval a
- Data.IntervalMap: OpenInterval :: !a -> !a -> Interval a
- Data.IntervalMap: adjust :: Ord k => (a -> a) -> Interval k -> IntervalMap k a -> IntervalMap k a
- Data.IntervalMap: adjustWithKey :: Ord k => (Interval k -> a -> a) -> Interval k -> IntervalMap k a -> IntervalMap k a
- Data.IntervalMap: alter :: Ord k => (Maybe a -> Maybe a) -> Interval k -> IntervalMap k a -> IntervalMap k a
- Data.IntervalMap: assocs :: IntervalMap k v -> [(Interval k, v)]
- Data.IntervalMap: containing :: Ord k => IntervalMap k v -> k -> [(Interval k, v)]
- Data.IntervalMap: data Interval a
- Data.IntervalMap: data IntervalMap k v
- Data.IntervalMap: delete :: Ord k => Interval k -> IntervalMap k v -> IntervalMap k v
- Data.IntervalMap: deleteFindMax :: Ord k => IntervalMap k v -> ((Interval k, v), IntervalMap k v)
- Data.IntervalMap: deleteFindMin :: Ord k => IntervalMap k v -> ((Interval k, v), IntervalMap k v)
- Data.IntervalMap: deleteMax :: Ord k => IntervalMap k v -> IntervalMap k v
- Data.IntervalMap: deleteMin :: Ord k => IntervalMap k v -> IntervalMap k v
- Data.IntervalMap: difference :: Ord k => IntervalMap k a -> IntervalMap k b -> IntervalMap k a
- Data.IntervalMap: differenceWith :: Ord k => (a -> b -> Maybe a) -> IntervalMap k a -> IntervalMap k b -> IntervalMap k a
- Data.IntervalMap: differenceWithKey :: Ord k => (Interval k -> a -> b -> Maybe a) -> IntervalMap k a -> IntervalMap k b -> IntervalMap k a
- Data.IntervalMap: elems :: IntervalMap k v -> [v]
- Data.IntervalMap: empty :: IntervalMap k v
- Data.IntervalMap: filter :: Ord k => (a -> Bool) -> IntervalMap k a -> IntervalMap k a
- Data.IntervalMap: filterWithKey :: Ord k => (Interval k -> a -> Bool) -> IntervalMap k a -> IntervalMap k a
- Data.IntervalMap: findLast :: Eq k => IntervalMap k v -> (Interval k, v)
- Data.IntervalMap: findMax :: IntervalMap k v -> (Interval k, v)
- Data.IntervalMap: findMin :: IntervalMap k v -> (Interval k, v)
- Data.IntervalMap: findWithDefault :: Ord k => a -> Interval k -> IntervalMap k a -> a
- Data.IntervalMap: foldl :: (b -> a -> b) -> b -> IntervalMap k a -> b
- Data.IntervalMap: foldl' :: (b -> a -> b) -> b -> IntervalMap k a -> b
- Data.IntervalMap: foldlWithKey :: (a -> Interval k -> v -> a) -> a -> IntervalMap k v -> a
- Data.IntervalMap: foldlWithKey' :: (a -> Interval k -> v -> a) -> a -> IntervalMap k v -> a
- Data.IntervalMap: foldr :: (a -> b -> b) -> b -> IntervalMap k a -> b
- Data.IntervalMap: foldr' :: (a -> b -> b) -> b -> IntervalMap k a -> b
- Data.IntervalMap: foldrWithKey :: (Interval k -> v -> a -> a) -> a -> IntervalMap k v -> a
- Data.IntervalMap: foldrWithKey' :: (Interval k -> v -> a -> a) -> a -> IntervalMap k v -> a
- Data.IntervalMap: fromAscList :: Ord k => [(Interval k, v)] -> IntervalMap k v
- Data.IntervalMap: fromAscListWith :: Ord k => (a -> a -> a) -> [(Interval k, a)] -> IntervalMap k a
- Data.IntervalMap: fromAscListWithKey :: Ord k => (Interval k -> a -> a -> a) -> [(Interval k, a)] -> IntervalMap k a
- Data.IntervalMap: fromDistinctAscList :: Ord k => [(Interval k, v)] -> IntervalMap k v
- Data.IntervalMap: fromList :: Ord k => [(Interval k, v)] -> IntervalMap k v
- Data.IntervalMap: fromListWith :: Ord k => (a -> a -> a) -> [(Interval k, a)] -> IntervalMap k a
- Data.IntervalMap: fromListWithKey :: Ord k => (Interval k -> a -> a -> a) -> [(Interval k, a)] -> IntervalMap k a
- Data.IntervalMap: height :: IntervalMap k v -> Int
- Data.IntervalMap: insert :: Ord k => Interval k -> v -> IntervalMap k v -> IntervalMap k v
- Data.IntervalMap: insertLookupWithKey :: Ord k => (Interval k -> v -> v -> v) -> Interval k -> v -> IntervalMap k v -> (Maybe v, IntervalMap k v)
- Data.IntervalMap: insertWith :: Ord k => (v -> v -> v) -> Interval k -> v -> IntervalMap k v -> IntervalMap k v
- Data.IntervalMap: insertWithKey :: Ord k => (Interval k -> v -> v -> v) -> Interval k -> v -> IntervalMap k v -> IntervalMap k v
- Data.IntervalMap: instance (Eq k, Eq v) => Eq (IntervalMap k v)
- Data.IntervalMap: instance (NFData k, NFData a) => NFData (IntervalMap k a)
- Data.IntervalMap: instance (Ord k, Ord v) => Ord (IntervalMap k v)
- Data.IntervalMap: instance (Ord k, Read k, Read e) => Read (IntervalMap k e)
- Data.IntervalMap: instance (Show k, Show a) => Show (IntervalMap k a)
- Data.IntervalMap: instance Eq Color
- Data.IntervalMap: instance Foldable (IntervalMap k)
- Data.IntervalMap: instance Functor (IntervalMap k)
- Data.IntervalMap: instance Ord k => Monoid (IntervalMap k v)
- Data.IntervalMap: instance Read Color
- Data.IntervalMap: instance Show Color
- Data.IntervalMap: instance Traversable (IntervalMap k)
- Data.IntervalMap: intersecting :: Ord k => IntervalMap k v -> Interval k -> [(Interval k, v)]
- Data.IntervalMap: intersection :: Ord k => IntervalMap k a -> IntervalMap k b -> IntervalMap k a
- Data.IntervalMap: intersectionWith :: Ord k => (a -> b -> c) -> IntervalMap k a -> IntervalMap k b -> IntervalMap k c
- Data.IntervalMap: intersectionWithKey :: Ord k => (Interval k -> a -> b -> c) -> IntervalMap k a -> IntervalMap k b -> IntervalMap k c
- Data.IntervalMap: isProperSubmapOf :: (Ord k, Eq a) => IntervalMap k a -> IntervalMap k a -> Bool
- Data.IntervalMap: isProperSubmapOfBy :: Ord k => (a -> b -> Bool) -> IntervalMap k a -> IntervalMap k b -> Bool
- Data.IntervalMap: isSubmapOf :: (Ord k, Eq a) => IntervalMap k a -> IntervalMap k a -> Bool
- Data.IntervalMap: isSubmapOfBy :: Ord k => (a -> b -> Bool) -> IntervalMap k a -> IntervalMap k b -> Bool
- Data.IntervalMap: keys :: IntervalMap k v -> [Interval k]
- Data.IntervalMap: keysSet :: Ord k => IntervalMap k v -> Set (Interval k)
- Data.IntervalMap: lookup :: Ord k => Interval k -> IntervalMap k v -> Maybe v
- Data.IntervalMap: map :: (a -> b) -> IntervalMap k a -> IntervalMap k b
- Data.IntervalMap: mapAccum :: (a -> b -> (a, c)) -> a -> IntervalMap k b -> (a, IntervalMap k c)
- Data.IntervalMap: mapAccumRWithKey :: (a -> Interval k -> b -> (a, c)) -> a -> IntervalMap k b -> (a, IntervalMap k c)
- Data.IntervalMap: mapAccumWithKey :: (a -> Interval k -> b -> (a, c)) -> a -> IntervalMap k b -> (a, IntervalMap k c)
- Data.IntervalMap: mapEither :: Ord k => (a -> Either b c) -> IntervalMap k a -> (IntervalMap k b, IntervalMap k c)
- Data.IntervalMap: mapEitherWithKey :: Ord k => (Interval k -> a -> Either b c) -> IntervalMap k a -> (IntervalMap k b, IntervalMap k c)
- Data.IntervalMap: mapKeys :: Ord k2 => (Interval k1 -> Interval k2) -> IntervalMap k1 a -> IntervalMap k2 a
- Data.IntervalMap: mapKeysMonotonic :: Ord k2 => (Interval k1 -> Interval k2) -> IntervalMap k1 a -> IntervalMap k2 a
- Data.IntervalMap: mapKeysWith :: Ord k2 => (a -> a -> a) -> (Interval k1 -> Interval k2) -> IntervalMap k1 a -> IntervalMap k2 a
- Data.IntervalMap: mapMaybe :: Ord k => (a -> Maybe b) -> IntervalMap k a -> IntervalMap k b
- Data.IntervalMap: mapMaybeWithKey :: Ord k => (Interval k -> a -> Maybe b) -> IntervalMap k a -> IntervalMap k b
- Data.IntervalMap: mapWithKey :: (Interval k -> a -> b) -> IntervalMap k a -> IntervalMap k b
- Data.IntervalMap: maxHeight :: Int -> Int
- Data.IntervalMap: maxView :: Ord k => IntervalMap k a -> Maybe (a, IntervalMap k a)
- Data.IntervalMap: maxViewWithKey :: Ord k => IntervalMap k a -> Maybe ((Interval k, a), IntervalMap k a)
- Data.IntervalMap: member :: Ord k => Interval k -> IntervalMap k v -> Bool
- Data.IntervalMap: minView :: Ord k => IntervalMap k a -> Maybe (a, IntervalMap k a)
- Data.IntervalMap: minViewWithKey :: Ord k => IntervalMap k a -> Maybe ((Interval k, a), IntervalMap k a)
- Data.IntervalMap: notMember :: Ord k => Interval k -> IntervalMap k v -> Bool
- Data.IntervalMap: null :: IntervalMap k v -> Bool
- Data.IntervalMap: partition :: Ord k => (a -> Bool) -> IntervalMap k a -> (IntervalMap k a, IntervalMap k a)
- Data.IntervalMap: partitionWithKey :: Ord k => (Interval k -> a -> Bool) -> IntervalMap k a -> (IntervalMap k a, IntervalMap k a)
- Data.IntervalMap: showStats :: IntervalMap k a -> (Int, Int, Int)
- Data.IntervalMap: singleton :: Interval k -> v -> IntervalMap k v
- Data.IntervalMap: size :: IntervalMap k v -> Int
- Data.IntervalMap: split :: Ord k => Interval k -> IntervalMap k a -> (IntervalMap k a, IntervalMap k a)
- Data.IntervalMap: splitLookup :: Ord k => Interval k -> IntervalMap k a -> (IntervalMap k a, Maybe a, IntervalMap k a)
- Data.IntervalMap: toAscList :: IntervalMap k v -> [(Interval k, v)]
- Data.IntervalMap: toDescList :: IntervalMap k v -> [(Interval k, v)]
- Data.IntervalMap: toList :: IntervalMap k v -> [(Interval k, v)]
- Data.IntervalMap: union :: Ord k => IntervalMap k a -> IntervalMap k a -> IntervalMap k a
- Data.IntervalMap: unionWith :: Ord k => (a -> a -> a) -> IntervalMap k a -> IntervalMap k a -> IntervalMap k a
- Data.IntervalMap: unionWithKey :: Ord k => (Interval k -> a -> a -> a) -> IntervalMap k a -> IntervalMap k a -> IntervalMap k a
- Data.IntervalMap: unions :: Ord k => [IntervalMap k a] -> IntervalMap k a
- Data.IntervalMap: unionsWith :: Ord k => (a -> a -> a) -> [IntervalMap k a] -> IntervalMap k a
- Data.IntervalMap: update :: Ord k => (a -> Maybe a) -> Interval k -> IntervalMap k a -> IntervalMap k a
- Data.IntervalMap: updateLookupWithKey :: Ord k => (Interval k -> a -> Maybe a) -> Interval k -> IntervalMap k a -> (Maybe a, IntervalMap k a)
- Data.IntervalMap: updateMax :: Ord k => (v -> Maybe v) -> IntervalMap k v -> IntervalMap k v
- Data.IntervalMap: updateMaxWithKey :: Ord k => (Interval k -> v -> Maybe v) -> IntervalMap k v -> IntervalMap k v
- Data.IntervalMap: updateMin :: Ord k => (v -> Maybe v) -> IntervalMap k v -> IntervalMap k v
- Data.IntervalMap: updateMinWithKey :: Ord k => (Interval k -> v -> Maybe v) -> IntervalMap k v -> IntervalMap k v
- Data.IntervalMap: updateWithKey :: Ord k => (Interval k -> a -> Maybe a) -> Interval k -> IntervalMap k a -> IntervalMap k a
- Data.IntervalMap: valid :: Ord k => IntervalMap k v -> Bool
- Data.IntervalMap: within :: Ord k => IntervalMap k v -> Interval k -> [(Interval k, v)]
+ Data.IntervalMap: fold :: (a -> b -> b) -> b -> IntervalMap k a -> b
+ Data.IntervalMap: foldWithKey :: (Interval k -> a -> b -> b) -> b -> IntervalMap k a -> b
+ Data.IntervalMap.Lazy: (!) :: Ord k => IntervalMap k v -> Interval k -> v
+ Data.IntervalMap.Lazy: (\\) :: Ord k => IntervalMap k a -> IntervalMap k b -> IntervalMap k a
+ Data.IntervalMap.Lazy: ClosedInterval :: !a -> !a -> Interval a
+ Data.IntervalMap.Lazy: IntervalCO :: !a -> !a -> Interval a
+ Data.IntervalMap.Lazy: IntervalOC :: !a -> !a -> Interval a
+ Data.IntervalMap.Lazy: OpenInterval :: !a -> !a -> Interval a
+ Data.IntervalMap.Lazy: adjust :: Ord k => (a -> a) -> Interval k -> IntervalMap k a -> IntervalMap k a
+ Data.IntervalMap.Lazy: adjustWithKey :: Ord k => (Interval k -> a -> a) -> Interval k -> IntervalMap k a -> IntervalMap k a
+ Data.IntervalMap.Lazy: alter :: Ord k => (Maybe a -> Maybe a) -> Interval k -> IntervalMap k a -> IntervalMap k a
+ Data.IntervalMap.Lazy: assocs :: IntervalMap k v -> [(Interval k, v)]
+ Data.IntervalMap.Lazy: containing :: Ord k => IntervalMap k v -> k -> [(Interval k, v)]
+ Data.IntervalMap.Lazy: data Interval a
+ Data.IntervalMap.Lazy: data IntervalMap k v
+ Data.IntervalMap.Lazy: delete :: Ord k => Interval k -> IntervalMap k v -> IntervalMap k v
+ Data.IntervalMap.Lazy: deleteFindMax :: Ord k => IntervalMap k v -> ((Interval k, v), IntervalMap k v)
+ Data.IntervalMap.Lazy: deleteFindMin :: Ord k => IntervalMap k v -> ((Interval k, v), IntervalMap k v)
+ Data.IntervalMap.Lazy: deleteMax :: Ord k => IntervalMap k v -> IntervalMap k v
+ Data.IntervalMap.Lazy: deleteMin :: Ord k => IntervalMap k v -> IntervalMap k v
+ Data.IntervalMap.Lazy: difference :: Ord k => IntervalMap k a -> IntervalMap k b -> IntervalMap k a
+ Data.IntervalMap.Lazy: differenceWith :: Ord k => (a -> b -> Maybe a) -> IntervalMap k a -> IntervalMap k b -> IntervalMap k a
+ Data.IntervalMap.Lazy: differenceWithKey :: Ord k => (Interval k -> a -> b -> Maybe a) -> IntervalMap k a -> IntervalMap k b -> IntervalMap k a
+ Data.IntervalMap.Lazy: elems :: IntervalMap k v -> [v]
+ Data.IntervalMap.Lazy: empty :: IntervalMap k v
+ Data.IntervalMap.Lazy: filter :: Ord k => (a -> Bool) -> IntervalMap k a -> IntervalMap k a
+ Data.IntervalMap.Lazy: filterWithKey :: Ord k => (Interval k -> a -> Bool) -> IntervalMap k a -> IntervalMap k a
+ Data.IntervalMap.Lazy: findLast :: Eq k => IntervalMap k v -> (Interval k, v)
+ Data.IntervalMap.Lazy: findMax :: IntervalMap k v -> (Interval k, v)
+ Data.IntervalMap.Lazy: findMin :: IntervalMap k v -> (Interval k, v)
+ Data.IntervalMap.Lazy: findWithDefault :: Ord k => a -> Interval k -> IntervalMap k a -> a
+ Data.IntervalMap.Lazy: foldl :: (b -> a -> b) -> b -> IntervalMap k a -> b
+ Data.IntervalMap.Lazy: foldlWithKey :: (a -> Interval k -> v -> a) -> a -> IntervalMap k v -> a
+ Data.IntervalMap.Lazy: foldr :: (a -> b -> b) -> b -> IntervalMap k a -> b
+ Data.IntervalMap.Lazy: foldrWithKey :: (Interval k -> v -> a -> a) -> a -> IntervalMap k v -> a
+ Data.IntervalMap.Lazy: fromAscList :: Ord k => [(Interval k, v)] -> IntervalMap k v
+ Data.IntervalMap.Lazy: fromAscListWith :: Ord k => (a -> a -> a) -> [(Interval k, a)] -> IntervalMap k a
+ Data.IntervalMap.Lazy: fromAscListWithKey :: Ord k => (Interval k -> a -> a -> a) -> [(Interval k, a)] -> IntervalMap k a
+ Data.IntervalMap.Lazy: fromDistinctAscList :: Ord k => [(Interval k, v)] -> IntervalMap k v
+ Data.IntervalMap.Lazy: fromList :: Ord k => [(Interval k, v)] -> IntervalMap k v
+ Data.IntervalMap.Lazy: fromListWith :: Ord k => (a -> a -> a) -> [(Interval k, a)] -> IntervalMap k a
+ Data.IntervalMap.Lazy: fromListWithKey :: Ord k => (Interval k -> a -> a -> a) -> [(Interval k, a)] -> IntervalMap k a
+ Data.IntervalMap.Lazy: height :: IntervalMap k v -> Int
+ Data.IntervalMap.Lazy: insert :: Ord k => Interval k -> v -> IntervalMap k v -> IntervalMap k v
+ Data.IntervalMap.Lazy: insertLookupWithKey :: Ord k => (Interval k -> v -> v -> v) -> Interval k -> v -> IntervalMap k v -> (Maybe v, IntervalMap k v)
+ Data.IntervalMap.Lazy: insertWith :: Ord k => (v -> v -> v) -> Interval k -> v -> IntervalMap k v -> IntervalMap k v
+ Data.IntervalMap.Lazy: insertWithKey :: Ord k => (Interval k -> v -> v -> v) -> Interval k -> v -> IntervalMap k v -> IntervalMap k v
+ Data.IntervalMap.Lazy: intersecting :: Ord k => IntervalMap k v -> Interval k -> [(Interval k, v)]
+ Data.IntervalMap.Lazy: intersection :: Ord k => IntervalMap k a -> IntervalMap k b -> IntervalMap k a
+ Data.IntervalMap.Lazy: intersectionWith :: Ord k => (a -> b -> c) -> IntervalMap k a -> IntervalMap k b -> IntervalMap k c
+ Data.IntervalMap.Lazy: intersectionWithKey :: Ord k => (Interval k -> a -> b -> c) -> IntervalMap k a -> IntervalMap k b -> IntervalMap k c
+ Data.IntervalMap.Lazy: isProperSubmapOf :: (Ord k, Eq a) => IntervalMap k a -> IntervalMap k a -> Bool
+ Data.IntervalMap.Lazy: isProperSubmapOfBy :: Ord k => (a -> b -> Bool) -> IntervalMap k a -> IntervalMap k b -> Bool
+ Data.IntervalMap.Lazy: isSubmapOf :: (Ord k, Eq a) => IntervalMap k a -> IntervalMap k a -> Bool
+ Data.IntervalMap.Lazy: isSubmapOfBy :: Ord k => (a -> b -> Bool) -> IntervalMap k a -> IntervalMap k b -> Bool
+ Data.IntervalMap.Lazy: keys :: IntervalMap k v -> [Interval k]
+ Data.IntervalMap.Lazy: keysSet :: Ord k => IntervalMap k v -> Set (Interval k)
+ Data.IntervalMap.Lazy: lookup :: Ord k => Interval k -> IntervalMap k v -> Maybe v
+ Data.IntervalMap.Lazy: map :: (a -> b) -> IntervalMap k a -> IntervalMap k b
+ Data.IntervalMap.Lazy: mapAccum :: (a -> b -> (a, c)) -> a -> IntervalMap k b -> (a, IntervalMap k c)
+ Data.IntervalMap.Lazy: mapAccumRWithKey :: (a -> Interval k -> b -> (a, c)) -> a -> IntervalMap k b -> (a, IntervalMap k c)
+ Data.IntervalMap.Lazy: mapAccumWithKey :: (a -> Interval k -> b -> (a, c)) -> a -> IntervalMap k b -> (a, IntervalMap k c)
+ Data.IntervalMap.Lazy: mapEither :: Ord k => (a -> Either b c) -> IntervalMap k a -> (IntervalMap k b, IntervalMap k c)
+ Data.IntervalMap.Lazy: mapEitherWithKey :: Ord k => (Interval k -> a -> Either b c) -> IntervalMap k a -> (IntervalMap k b, IntervalMap k c)
+ Data.IntervalMap.Lazy: mapKeys :: Ord k2 => (Interval k1 -> Interval k2) -> IntervalMap k1 a -> IntervalMap k2 a
+ Data.IntervalMap.Lazy: mapKeysMonotonic :: Ord k2 => (Interval k1 -> Interval k2) -> IntervalMap k1 a -> IntervalMap k2 a
+ Data.IntervalMap.Lazy: mapKeysWith :: Ord k2 => (a -> a -> a) -> (Interval k1 -> Interval k2) -> IntervalMap k1 a -> IntervalMap k2 a
+ Data.IntervalMap.Lazy: mapMaybe :: Ord k => (a -> Maybe b) -> IntervalMap k a -> IntervalMap k b
+ Data.IntervalMap.Lazy: mapMaybeWithKey :: Ord k => (Interval k -> a -> Maybe b) -> IntervalMap k a -> IntervalMap k b
+ Data.IntervalMap.Lazy: mapWithKey :: (Interval k -> a -> b) -> IntervalMap k a -> IntervalMap k b
+ Data.IntervalMap.Lazy: maxHeight :: Int -> Int
+ Data.IntervalMap.Lazy: maxView :: Ord k => IntervalMap k a -> Maybe (a, IntervalMap k a)
+ Data.IntervalMap.Lazy: maxViewWithKey :: Ord k => IntervalMap k a -> Maybe ((Interval k, a), IntervalMap k a)
+ Data.IntervalMap.Lazy: member :: Ord k => Interval k -> IntervalMap k v -> Bool
+ Data.IntervalMap.Lazy: minView :: Ord k => IntervalMap k a -> Maybe (a, IntervalMap k a)
+ Data.IntervalMap.Lazy: minViewWithKey :: Ord k => IntervalMap k a -> Maybe ((Interval k, a), IntervalMap k a)
+ Data.IntervalMap.Lazy: notMember :: Ord k => Interval k -> IntervalMap k v -> Bool
+ Data.IntervalMap.Lazy: null :: IntervalMap k v -> Bool
+ Data.IntervalMap.Lazy: partition :: Ord k => (a -> Bool) -> IntervalMap k a -> (IntervalMap k a, IntervalMap k a)
+ Data.IntervalMap.Lazy: partitionWithKey :: Ord k => (Interval k -> a -> Bool) -> IntervalMap k a -> (IntervalMap k a, IntervalMap k a)
+ Data.IntervalMap.Lazy: showStats :: IntervalMap k a -> (Int, Int, Int)
+ Data.IntervalMap.Lazy: singleton :: Interval k -> v -> IntervalMap k v
+ Data.IntervalMap.Lazy: size :: IntervalMap k v -> Int
+ Data.IntervalMap.Lazy: split :: Ord k => Interval k -> IntervalMap k a -> (IntervalMap k a, IntervalMap k a)
+ Data.IntervalMap.Lazy: splitLookup :: Ord k => Interval k -> IntervalMap k a -> (IntervalMap k a, Maybe a, IntervalMap k a)
+ Data.IntervalMap.Lazy: toAscList :: IntervalMap k v -> [(Interval k, v)]
+ Data.IntervalMap.Lazy: toDescList :: IntervalMap k v -> [(Interval k, v)]
+ Data.IntervalMap.Lazy: toList :: IntervalMap k v -> [(Interval k, v)]
+ Data.IntervalMap.Lazy: union :: Ord k => IntervalMap k a -> IntervalMap k a -> IntervalMap k a
+ Data.IntervalMap.Lazy: unionWith :: Ord k => (a -> a -> a) -> IntervalMap k a -> IntervalMap k a -> IntervalMap k a
+ Data.IntervalMap.Lazy: unionWithKey :: Ord k => (Interval k -> a -> a -> a) -> IntervalMap k a -> IntervalMap k a -> IntervalMap k a
+ Data.IntervalMap.Lazy: unions :: Ord k => [IntervalMap k a] -> IntervalMap k a
+ Data.IntervalMap.Lazy: unionsWith :: Ord k => (a -> a -> a) -> [IntervalMap k a] -> IntervalMap k a
+ Data.IntervalMap.Lazy: update :: Ord k => (a -> Maybe a) -> Interval k -> IntervalMap k a -> IntervalMap k a
+ Data.IntervalMap.Lazy: updateLookupWithKey :: Ord k => (Interval k -> a -> Maybe a) -> Interval k -> IntervalMap k a -> (Maybe a, IntervalMap k a)
+ Data.IntervalMap.Lazy: updateMax :: Ord k => (v -> Maybe v) -> IntervalMap k v -> IntervalMap k v
+ Data.IntervalMap.Lazy: updateMaxWithKey :: Ord k => (Interval k -> v -> Maybe v) -> IntervalMap k v -> IntervalMap k v
+ Data.IntervalMap.Lazy: updateMin :: Ord k => (v -> Maybe v) -> IntervalMap k v -> IntervalMap k v
+ Data.IntervalMap.Lazy: updateMinWithKey :: Ord k => (Interval k -> v -> Maybe v) -> IntervalMap k v -> IntervalMap k v
+ Data.IntervalMap.Lazy: updateWithKey :: Ord k => (Interval k -> a -> Maybe a) -> Interval k -> IntervalMap k a -> IntervalMap k a
+ Data.IntervalMap.Lazy: valid :: Ord k => IntervalMap k v -> Bool
+ Data.IntervalMap.Lazy: within :: Ord k => IntervalMap k v -> Interval k -> [(Interval k, v)]
+ Data.IntervalMap.Strict: (!) :: Ord k => IntervalMap k v -> Interval k -> v
+ Data.IntervalMap.Strict: (\\) :: Ord k => IntervalMap k a -> IntervalMap k b -> IntervalMap k a
+ Data.IntervalMap.Strict: ClosedInterval :: !a -> !a -> Interval a
+ Data.IntervalMap.Strict: IntervalCO :: !a -> !a -> Interval a
+ Data.IntervalMap.Strict: IntervalOC :: !a -> !a -> Interval a
+ Data.IntervalMap.Strict: OpenInterval :: !a -> !a -> Interval a
+ Data.IntervalMap.Strict: adjust :: Ord k => (a -> a) -> Interval k -> IntervalMap k a -> IntervalMap k a
+ Data.IntervalMap.Strict: adjustWithKey :: Ord k => (Interval k -> a -> a) -> Interval k -> IntervalMap k a -> IntervalMap k a
+ Data.IntervalMap.Strict: alter :: Ord k => (Maybe a -> Maybe a) -> Interval k -> IntervalMap k a -> IntervalMap k a
+ Data.IntervalMap.Strict: assocs :: IntervalMap k v -> [(Interval k, v)]
+ Data.IntervalMap.Strict: containing :: Ord k => IntervalMap k v -> k -> [(Interval k, v)]
+ Data.IntervalMap.Strict: data Interval a
+ Data.IntervalMap.Strict: data IntervalMap k v
+ Data.IntervalMap.Strict: delete :: Ord k => Interval k -> IntervalMap k v -> IntervalMap k v
+ Data.IntervalMap.Strict: deleteFindMax :: Ord k => IntervalMap k v -> ((Interval k, v), IntervalMap k v)
+ Data.IntervalMap.Strict: deleteFindMin :: Ord k => IntervalMap k v -> ((Interval k, v), IntervalMap k v)
+ Data.IntervalMap.Strict: deleteMax :: Ord k => IntervalMap k v -> IntervalMap k v
+ Data.IntervalMap.Strict: deleteMin :: Ord k => IntervalMap k v -> IntervalMap k v
+ Data.IntervalMap.Strict: difference :: Ord k => IntervalMap k a -> IntervalMap k b -> IntervalMap k a
+ Data.IntervalMap.Strict: differenceWith :: Ord k => (a -> b -> Maybe a) -> IntervalMap k a -> IntervalMap k b -> IntervalMap k a
+ Data.IntervalMap.Strict: differenceWithKey :: Ord k => (Interval k -> a -> b -> Maybe a) -> IntervalMap k a -> IntervalMap k b -> IntervalMap k a
+ Data.IntervalMap.Strict: elems :: IntervalMap k v -> [v]
+ Data.IntervalMap.Strict: empty :: IntervalMap k v
+ Data.IntervalMap.Strict: filter :: Ord k => (a -> Bool) -> IntervalMap k a -> IntervalMap k a
+ Data.IntervalMap.Strict: filterWithKey :: Ord k => (Interval k -> a -> Bool) -> IntervalMap k a -> IntervalMap k a
+ Data.IntervalMap.Strict: findLast :: Eq k => IntervalMap k v -> (Interval k, v)
+ Data.IntervalMap.Strict: findMax :: IntervalMap k v -> (Interval k, v)
+ Data.IntervalMap.Strict: findMin :: IntervalMap k v -> (Interval k, v)
+ Data.IntervalMap.Strict: findWithDefault :: Ord k => a -> Interval k -> IntervalMap k a -> a
+ Data.IntervalMap.Strict: foldl :: (b -> a -> b) -> b -> IntervalMap k a -> b
+ Data.IntervalMap.Strict: foldlWithKey :: (a -> Interval k -> v -> a) -> a -> IntervalMap k v -> a
+ Data.IntervalMap.Strict: foldr :: (a -> b -> b) -> b -> IntervalMap k a -> b
+ Data.IntervalMap.Strict: foldrWithKey :: (Interval k -> v -> a -> a) -> a -> IntervalMap k v -> a
+ Data.IntervalMap.Strict: fromAscList :: Ord k => [(Interval k, v)] -> IntervalMap k v
+ Data.IntervalMap.Strict: fromAscListWith :: Ord k => (a -> a -> a) -> [(Interval k, a)] -> IntervalMap k a
+ Data.IntervalMap.Strict: fromAscListWithKey :: Ord k => (Interval k -> a -> a -> a) -> [(Interval k, a)] -> IntervalMap k a
+ Data.IntervalMap.Strict: fromDistinctAscList :: Ord k => [(Interval k, v)] -> IntervalMap k v
+ Data.IntervalMap.Strict: fromList :: Ord k => [(Interval k, v)] -> IntervalMap k v
+ Data.IntervalMap.Strict: fromListWith :: Ord k => (a -> a -> a) -> [(Interval k, a)] -> IntervalMap k a
+ Data.IntervalMap.Strict: fromListWithKey :: Ord k => (Interval k -> a -> a -> a) -> [(Interval k, a)] -> IntervalMap k a
+ Data.IntervalMap.Strict: height :: IntervalMap k v -> Int
+ Data.IntervalMap.Strict: insert :: Ord k => Interval k -> v -> IntervalMap k v -> IntervalMap k v
+ Data.IntervalMap.Strict: insertLookupWithKey :: Ord k => (Interval k -> v -> v -> v) -> Interval k -> v -> IntervalMap k v -> (Maybe v, IntervalMap k v)
+ Data.IntervalMap.Strict: insertWith :: Ord k => (v -> v -> v) -> Interval k -> v -> IntervalMap k v -> IntervalMap k v
+ Data.IntervalMap.Strict: insertWithKey :: Ord k => (Interval k -> v -> v -> v) -> Interval k -> v -> IntervalMap k v -> IntervalMap k v
+ Data.IntervalMap.Strict: intersecting :: Ord k => IntervalMap k v -> Interval k -> [(Interval k, v)]
+ Data.IntervalMap.Strict: intersection :: Ord k => IntervalMap k a -> IntervalMap k b -> IntervalMap k a
+ Data.IntervalMap.Strict: intersectionWith :: Ord k => (a -> b -> c) -> IntervalMap k a -> IntervalMap k b -> IntervalMap k c
+ Data.IntervalMap.Strict: intersectionWithKey :: Ord k => (Interval k -> a -> b -> c) -> IntervalMap k a -> IntervalMap k b -> IntervalMap k c
+ Data.IntervalMap.Strict: isProperSubmapOf :: (Ord k, Eq a) => IntervalMap k a -> IntervalMap k a -> Bool
+ Data.IntervalMap.Strict: isProperSubmapOfBy :: Ord k => (a -> b -> Bool) -> IntervalMap k a -> IntervalMap k b -> Bool
+ Data.IntervalMap.Strict: isSubmapOf :: (Ord k, Eq a) => IntervalMap k a -> IntervalMap k a -> Bool
+ Data.IntervalMap.Strict: isSubmapOfBy :: Ord k => (a -> b -> Bool) -> IntervalMap k a -> IntervalMap k b -> Bool
+ Data.IntervalMap.Strict: keys :: IntervalMap k v -> [Interval k]
+ Data.IntervalMap.Strict: keysSet :: Ord k => IntervalMap k v -> Set (Interval k)
+ Data.IntervalMap.Strict: lookup :: Ord k => Interval k -> IntervalMap k v -> Maybe v
+ Data.IntervalMap.Strict: map :: (a -> b) -> IntervalMap k a -> IntervalMap k b
+ Data.IntervalMap.Strict: mapAccum :: (a -> b -> (a, c)) -> a -> IntervalMap k b -> (a, IntervalMap k c)
+ Data.IntervalMap.Strict: mapAccumRWithKey :: (a -> Interval k -> b -> (a, c)) -> a -> IntervalMap k b -> (a, IntervalMap k c)
+ Data.IntervalMap.Strict: mapAccumWithKey :: (a -> Interval k -> b -> (a, c)) -> a -> IntervalMap k b -> (a, IntervalMap k c)
+ Data.IntervalMap.Strict: mapEither :: Ord k => (a -> Either b c) -> IntervalMap k a -> (IntervalMap k b, IntervalMap k c)
+ Data.IntervalMap.Strict: mapEitherWithKey :: Ord k => (Interval k -> a -> Either b c) -> IntervalMap k a -> (IntervalMap k b, IntervalMap k c)
+ Data.IntervalMap.Strict: mapKeys :: Ord k2 => (Interval k1 -> Interval k2) -> IntervalMap k1 a -> IntervalMap k2 a
+ Data.IntervalMap.Strict: mapKeysMonotonic :: Ord k2 => (Interval k1 -> Interval k2) -> IntervalMap k1 a -> IntervalMap k2 a
+ Data.IntervalMap.Strict: mapKeysWith :: Ord k2 => (a -> a -> a) -> (Interval k1 -> Interval k2) -> IntervalMap k1 a -> IntervalMap k2 a
+ Data.IntervalMap.Strict: mapMaybe :: Ord k => (a -> Maybe b) -> IntervalMap k a -> IntervalMap k b
+ Data.IntervalMap.Strict: mapMaybeWithKey :: Ord k => (Interval k -> a -> Maybe b) -> IntervalMap k a -> IntervalMap k b
+ Data.IntervalMap.Strict: mapWithKey :: (Interval k -> a -> b) -> IntervalMap k a -> IntervalMap k b
+ Data.IntervalMap.Strict: maxHeight :: Int -> Int
+ Data.IntervalMap.Strict: maxView :: Ord k => IntervalMap k a -> Maybe (a, IntervalMap k a)
+ Data.IntervalMap.Strict: maxViewWithKey :: Ord k => IntervalMap k a -> Maybe ((Interval k, a), IntervalMap k a)
+ Data.IntervalMap.Strict: member :: Ord k => Interval k -> IntervalMap k v -> Bool
+ Data.IntervalMap.Strict: minView :: Ord k => IntervalMap k a -> Maybe (a, IntervalMap k a)
+ Data.IntervalMap.Strict: minViewWithKey :: Ord k => IntervalMap k a -> Maybe ((Interval k, a), IntervalMap k a)
+ Data.IntervalMap.Strict: notMember :: Ord k => Interval k -> IntervalMap k v -> Bool
+ Data.IntervalMap.Strict: null :: IntervalMap k v -> Bool
+ Data.IntervalMap.Strict: partition :: Ord k => (a -> Bool) -> IntervalMap k a -> (IntervalMap k a, IntervalMap k a)
+ Data.IntervalMap.Strict: partitionWithKey :: Ord k => (Interval k -> a -> Bool) -> IntervalMap k a -> (IntervalMap k a, IntervalMap k a)
+ Data.IntervalMap.Strict: showStats :: IntervalMap k a -> (Int, Int, Int)
+ Data.IntervalMap.Strict: singleton :: Interval k -> v -> IntervalMap k v
+ Data.IntervalMap.Strict: size :: IntervalMap k v -> Int
+ Data.IntervalMap.Strict: split :: Ord k => Interval k -> IntervalMap k a -> (IntervalMap k a, IntervalMap k a)
+ Data.IntervalMap.Strict: splitLookup :: Ord k => Interval k -> IntervalMap k a -> (IntervalMap k a, Maybe a, IntervalMap k a)
+ Data.IntervalMap.Strict: toAscList :: IntervalMap k v -> [(Interval k, v)]
+ Data.IntervalMap.Strict: toDescList :: IntervalMap k v -> [(Interval k, v)]
+ Data.IntervalMap.Strict: toList :: IntervalMap k v -> [(Interval k, v)]
+ Data.IntervalMap.Strict: union :: Ord k => IntervalMap k a -> IntervalMap k a -> IntervalMap k a
+ Data.IntervalMap.Strict: unionWith :: Ord k => (a -> a -> a) -> IntervalMap k a -> IntervalMap k a -> IntervalMap k a
+ Data.IntervalMap.Strict: unionWithKey :: Ord k => (Interval k -> a -> a -> a) -> IntervalMap k a -> IntervalMap k a -> IntervalMap k a
+ Data.IntervalMap.Strict: unions :: Ord k => [IntervalMap k a] -> IntervalMap k a
+ Data.IntervalMap.Strict: unionsWith :: Ord k => (a -> a -> a) -> [IntervalMap k a] -> IntervalMap k a
+ Data.IntervalMap.Strict: update :: Ord k => (a -> Maybe a) -> Interval k -> IntervalMap k a -> IntervalMap k a
+ Data.IntervalMap.Strict: updateLookupWithKey :: Ord k => (Interval k -> a -> Maybe a) -> Interval k -> IntervalMap k a -> (Maybe a, IntervalMap k a)
+ Data.IntervalMap.Strict: updateMax :: Ord k => (v -> Maybe v) -> IntervalMap k v -> IntervalMap k v
+ Data.IntervalMap.Strict: updateMaxWithKey :: Ord k => (Interval k -> v -> Maybe v) -> IntervalMap k v -> IntervalMap k v
+ Data.IntervalMap.Strict: updateMin :: Ord k => (v -> Maybe v) -> IntervalMap k v -> IntervalMap k v
+ Data.IntervalMap.Strict: updateMinWithKey :: Ord k => (Interval k -> v -> Maybe v) -> IntervalMap k v -> IntervalMap k v
+ Data.IntervalMap.Strict: updateWithKey :: Ord k => (Interval k -> a -> Maybe a) -> Interval k -> IntervalMap k a -> IntervalMap k a
+ Data.IntervalMap.Strict: valid :: Ord k => IntervalMap k v -> Bool
+ Data.IntervalMap.Strict: within :: Ord k => IntervalMap k v -> Interval k -> [(Interval k, v)]
- Data.IntervalMap: insertLookupWithKey' :: Ord k => (Interval k -> v -> v -> v) -> Interval k -> v -> IntervalMap k v -> (Maybe v, IntervalMap k v)
+ Data.IntervalMap: insertLookupWithKey' :: Ord k => (Interval k -> a -> a -> a) -> Interval k -> a -> IntervalMap k a -> (Maybe a, IntervalMap k a)
- Data.IntervalMap: insertWith' :: Ord k => (v -> v -> v) -> Interval k -> v -> IntervalMap k v -> IntervalMap k v
+ Data.IntervalMap: insertWith' :: Ord k => (a -> a -> a) -> Interval k -> a -> IntervalMap k a -> IntervalMap k a
- Data.IntervalMap: insertWithKey' :: Ord k => (Interval k -> v -> v -> v) -> Interval k -> v -> IntervalMap k v -> IntervalMap k v
+ Data.IntervalMap: insertWithKey' :: Ord k => (Interval k -> a -> a -> a) -> Interval k -> a -> IntervalMap k a -> IntervalMap k a
Files
- Data/IntervalMap.hs +73/−1270
- Data/IntervalMap/Base.hs +1267/−0
- Data/IntervalMap/Interval.hs +1/−1
- Data/IntervalMap/Lazy.hs +155/−0
- Data/IntervalMap/Strict.hs +252/−0
- IntervalMap.cabal +7/−5
- README +1/−1
- bench/BenchAll.hs +7/−1
Data/IntervalMap.hs view
@@ -1,1270 +1,73 @@--- |--- Module : Data.IntervalMap--- Copyright : (c) Christoph Breitkopf 2011--- License : BSD-style--- Maintainer : chbreitkopf@googlemail.com--- Stability : experimental--- Portability : portable------ An implementation of maps from intervals to values. The key intervals may--- overlap, and the implementation contains efficient search functions--- for all keys containing a point or overlapping an interval.--- Closed, open, and half-open intervals can be contained in the same map.------ An IntervalMap cannot contain duplicate keys - if you need to map a key--- to muiltiple values, use a collection as the value type, for--- example: @IntervalMap /k/ [/v/]@.------ It is an error to insert an empty interval into a map. This precondition is not--- checked by the various construction functions.------ Since many function names (but not the type name) clash with--- /Prelude/ names, this module is usually imported @qualified@, e.g.------ > import Data.IntervalMap (IvMap)--- > import qualified Data.IntervalMap as IvMap------ It offers most of the same functions as 'Data.Map', but uses 'Interval' /k/ instead of--- just /k/ as the key type. Some of the functions need stricter type constraints to--- maintain the additional information for efficient interval searching,--- for example 'fromDistinctAscList' needs an 'Ord' /k/ constraint.--- Also, some functions differ in asymptotic performance (for example 'size') or have not--- been tuned for efficiency as much as their equivalents in 'Data.Map' (in--- particular the various set functions).------ In addition, there are functions specific to maps of intervals, for example to search--- for all keys containing a given point or contained in a given interval.------ To stay compatible with standard Haskell, this implementation uses a fixed data--- type for intervals, and not a multi-parameter type class. Thus, it's currently--- not possible to define e.g. a 2-tuple as an instance of interval and use that--- map key. Instead, you must convert your keys to 'Interval'.------ The implementation is a red-black tree augmented with the maximum upper bound--- of all keys.------ Parts of this implementation are based on code from the 'Data.Map' implementation,--- (c) Daan Leijen 2002, (c) Andriy Palamarchuk 2008.--- The red-black tree deletion is based on code from llrbtree by Kazu Yamamoto.--- Of course, any errors are mine.----module Data.IntervalMap (- -- * re-export- Interval(..)- -- * Map type- , IntervalMap -- instance Eq,Show,Read-- -- * Operators- , (!), (\\)-- -- * Query- , null- , size- , member- , notMember- , lookup- , findWithDefault-- -- ** Interval query- , containing- , intersecting- , within- - -- * Construction- , empty- , singleton-- -- ** Insertion- , insert- , insertWith- , insertWith'- , insertWithKey- , insertWithKey'- , insertLookupWithKey- , insertLookupWithKey'- - -- ** Delete\/Update- , delete- , adjust- , adjustWithKey- , update- , updateWithKey- , updateLookupWithKey- , alter-- -- * Combine-- -- ** Union- , union - , unionWith - , unionWithKey- , unions- , unionsWith-- -- ** Difference- , difference- , differenceWith- , differenceWithKey- - -- ** Intersection- , intersection - , intersectionWith- , intersectionWithKey-- -- * Traversal- -- ** Map- , map- , mapWithKey- , mapAccum- , mapAccumWithKey- , mapAccumRWithKey- , mapKeys- , mapKeysWith- , mapKeysMonotonic-- -- ** Fold- , foldr, foldl- , foldrWithKey, foldlWithKey- , foldl', foldr'- , foldrWithKey', foldlWithKey'-- -- * Conversion- , elems- , keys- , keysSet- , assocs- - -- ** Lists- , toList- , fromList- , fromListWith- , fromListWithKey-- -- ** Ordered lists- , toAscList- , toDescList- , fromAscList- , fromAscListWith- , fromAscListWithKey- , fromDistinctAscList-- -- * Filter - , filter- , filterWithKey- , partition- , partitionWithKey-- , mapMaybe- , mapMaybeWithKey- , mapEither- , mapEitherWithKey-- , split - , splitLookup -- -- * Submap- , isSubmapOf, isSubmapOfBy- , isProperSubmapOf, isProperSubmapOfBy-- {-- -- * Indexed - , lookupIndex- , findIndex- , elemAt- , updateAt- , deleteAt- -}-- -- * Min\/Max- , findMin- , findMax- , findLast- , deleteMin- , deleteMax- , deleteFindMin- , deleteFindMax- , updateMin- , updateMax- , updateMinWithKey- , updateMaxWithKey- , minView- , maxView- , minViewWithKey- , maxViewWithKey-- -- * Debugging- , valid-- -- * Testing- , height, maxHeight, showStats-- ) where--import Prelude hiding (null, lookup, map, filter, foldr, foldl)-import Data.Bits (shiftR, (.&.))-import Data.Monoid (Monoid(..))-import Control.Applicative (Applicative(..), (<$>))-import Data.Traversable (Traversable(traverse))-import qualified Data.Foldable as Foldable-import qualified Data.List as L-import qualified Data.Set as Set-import Control.DeepSeq (NFData(rnf))--import Data.IntervalMap.Interval--{--------------------------------------------------------------------- Operators---------------------------------------------------------------------}-infixl 9 !,\\ ------ | /O(log n)/. Lookup value for given key. Calls 'error' if the key is not in the map.-(!) :: (Ord k) => IntervalMap k v -> Interval k -> v-tree ! key = case lookup key tree of- Just v -> v- Nothing -> error "IntervalMap.!: key not found"---- | Same as 'difference'.-(\\) :: Ord k => IntervalMap k a -> IntervalMap k b -> IntervalMap k a-m1 \\ m2 = difference m1 m2---data Color = R | B deriving (Eq, Read, Show)---- | A map from intervals with endpoints of type @k@ to values of type @v@.-data IntervalMap k v = Nil- | Node !Color- !(Interval k) -- key- !(Interval k) -- interval with maximum upper in tree- v -- value- !(IntervalMap k v) -- left subtree- !(IntervalMap k v) -- right subtree--instance (Eq k, Eq v) => Eq (IntervalMap k v) where- a == b = toAscList a == toAscList b--instance (Ord k, Ord v) => Ord (IntervalMap k v) where- compare a b = compare (toAscList a) (toAscList b)--instance Functor (IntervalMap k) where- fmap f m = map f m--instance (Ord k) => Monoid (IntervalMap k v) where- mempty = empty- mappend = union- mconcat = unions--instance Traversable (IntervalMap k) where- traverse _ Nil = pure Nil- traverse f (Node c k m v l r)- = flip (Node c k m) <$> traverse f l <*> f v <*> traverse f r--instance Foldable.Foldable (IntervalMap k) where- fold Nil = mempty- fold (Node _ _ _ v l r) = Foldable.fold l `mappend` v `mappend` Foldable.fold r- foldr = foldr- foldl = foldl- foldMap _ Nil = mempty- foldMap f (Node _ _ _ v l r) = Foldable.foldMap f l `mappend` f v `mappend` Foldable.foldMap f r--instance (NFData k, NFData a) => NFData (IntervalMap k a) where- rnf Nil = ()- rnf (Node _ kx _ x l r) = rnf kx `seq` rnf x `seq` rnf l `seq` rnf r--instance (Ord k, Read k, Read e) => Read (IntervalMap k e) where- readsPrec p = readParen (p > 10) $ \ r -> do- ("fromList",s) <- lex r- (xs,t) <- reads s- return (fromList xs,t)--instance (Show k, Show a) => Show (IntervalMap k a) where- showsPrec d m = showParen (d > 10) $- showString "fromList " . shows (toList m)---isRed :: IntervalMap k v -> Bool-isRed (Node R _ _ _ _ _) = True-isRed _ = False--turnBlack :: IntervalMap k v -> IntervalMap k v-turnBlack (Node R k m vs l r) = Node B k m vs l r-turnBlack t = t--turnRed :: IntervalMap k v -> IntervalMap k v-turnRed Nil = error "turnRed: Leaf"-turnRed (Node B k m v l r) = Node R k m v l r-turnRed t = t---- construct node, recomputing the upper key bound.-mNode :: (Ord k) => Color -> Interval k -> v -> IntervalMap k v -> IntervalMap k v -> IntervalMap k v-mNode c k v l r = Node c k (maxUpper k l r) v l r--maxUpper :: Ord k => Interval k -> IntervalMap k v -> IntervalMap k v -> Interval k-maxUpper k Nil Nil = k `seq` k-maxUpper k Nil (Node _ _ m _ _ _) = maxByUpper k m-maxUpper k (Node _ _ m _ _ _) Nil = maxByUpper k m-maxUpper k (Node _ _ l _ _ _) (Node _ _ r _ _ _) = maxByUpper k (maxByUpper l r)---- interval with the greatest upper bound. The lower bound is ignored!-maxByUpper :: Ord a => Interval a -> Interval a -> Interval a-maxByUpper a@(IntervalCO _ u) b = if u > upperBound b then a else b-maxByUpper a@(ClosedInterval _ u) b = if u >= upperBound b then a else b-maxByUpper a@(OpenInterval _ u) b = if u > upperBound b then a else b-maxByUpper a@(IntervalOC _ u) b = if u >= upperBound b then a else b----- ------------------------------------------------------------- | /O(1)/. The empty map.-empty :: IntervalMap k v-empty = Nil---- | /O(1)/. A map with one entry.-singleton :: Interval k -> v -> IntervalMap k v-singleton k v = Node B k k v Nil Nil----- | /O(1)/. Is the map empty?-null :: IntervalMap k v -> Bool-null Nil = True-null _ = False---- | /O(n)/. Number of keys in the map.------ Caution: unlike 'Data.Map.size', which takes constant time, this is linear in the--- number of keys!-size :: IntervalMap k v -> Int-size t = h 0 t- where- h n m = n `seq` case m of- Nil -> n- Node _ _ _ _ l r -> h (h n l + 1) r---- | The height of the tree. For testing/debugging only.-height :: IntervalMap k v -> Int-height Nil = 0-height (Node _ _ _ _ l r) = 1 + max (height l) (height r)---- | The maximum height of a red-black tree with the given number of nodes.--- For testing/debugging only.-maxHeight :: Int -> Int-maxHeight nodes = 2 * log2 (nodes + 1)---- | Tree statistics (size, height, maxHeight size).--- For testing/debugging only.-showStats :: IntervalMap k a -> (Int, Int, Int)-showStats m = (n, height m, maxHeight n)- where n = size m---- | /O(log n)/. Does the map contain the given key? See also 'notMember'.-member :: (Ord k) => Interval k -> IntervalMap k v -> Bool-member key tree = case lookup key tree of- Nothing -> False- Just _ -> True---- | /O(log n)/. Does the map not contain the given key? See also 'member'.-notMember :: (Ord k) => Interval k -> IntervalMap k v -> Bool-notMember key tree = not (member key tree)----- | /O(log n)/. Look up the given key in the map, returning the value @('Just' value)@,--- or 'Nothing' if the key is not in the map.-lookup :: (Ord k) => Interval k -> IntervalMap k v -> Maybe v-lookup k Nil = k `seq` Nothing-lookup k (Node _ key _ v l r) = case compare k key of- LT -> lookup k l- GT -> lookup k r- EQ -> Just v----- | /O(log n)/. The expression @('findWithDefault' def k map)@ returns--- the value at key @k@ or returns default value @def@--- when the key is not in the map.------ > findWithDefault 'x' 1 (fromList [(5,'a'), (3,'b')]) == 'x'--- > findWithDefault 'x' 5 (fromList [(5,'a'), (3,'b')]) == 'a'--findWithDefault :: Ord k => a -> Interval k -> IntervalMap k a -> a-findWithDefault def k m = case lookup k m of- Nothing -> def- Just x -> x---- | Return all key/value pairs where the key intervals contain the given point.--- The elements are returned in ascending key order.------ /O(n)/, since potentially all keys could contain the point.--- /O(log n)/ average case. This is also the worst case for maps containing no overlapping keys.-containing :: (Ord k) => IntervalMap k v -> k -> [(Interval k, v)]-t `containing` pt = go [] pt t- where- go xs p Nil = p `seq` xs- go xs p (Node _ k m v l r)- | p `above` m = xs -- above all intervals in the tree: no result- | p `below` k = go xs p l -- to the left of the lower bound: can't be in right subtree- | p `inside` k = go ((k,v) : go xs p r) p l- | otherwise = go (go xs p r) p l---- | Return all key/value pairs where the key intervals overlap (intersect) the given interval.--- The elements are returned in ascending key order.------ /O(n)/, since potentially all keys could intersect the interval.--- /O(log n)/ average case, if few keys intersect the interval.-intersecting :: (Ord k) => IntervalMap k v -> Interval k -> [(Interval k, v)]-t `intersecting` iv = go [] iv t- where- go xs i Nil = i `seq` xs- go xs i (Node _ k m v l r)- | i `after` m = xs- | i `before` k = go xs i l- | i `overlaps` k = go ((k,v) : go xs i r) i l- | otherwise = go (go xs i r) i l---- | Return all key/value pairs where the key intervals are completely inside the given interval.--- The elements are returned in ascending key order.------ /O(n)/, since potentially all keys could be inside the interval.--- /O(log n)/ average case, if few keys are inside the interval.-within :: (Ord k) => IntervalMap k v -> Interval k -> [(Interval k, v)]-t `within` iv = go [] iv t- where- go xs i Nil = i `seq` xs- go xs i (Node _ k m v l r)- | i `after` m = xs- | i `before` k = go xs i l- | i `subsumes` k = go ((k,v) : go xs i r) i l- | otherwise = go (go xs i r) i l----- | /O(log n)/. Insert a new key/value pair. If the map already contains the key, its value is--- changed to the new value.-insert :: (Ord k) => Interval k -> v -> IntervalMap k v -> IntervalMap k v-insert = insertWithKey' (\_ v _ -> v)---- | /O(log n)/. Insert with a function, combining new value and old value.--- @'insertWith' f key value mp@ --- will insert the pair (key, value) into @mp@ if key does--- not exist in the map. If the key does exist, the function will--- insert the pair @(key, f new_value old_value)@.-insertWith :: (Ord k) => (v -> v -> v) -> Interval k -> v -> IntervalMap k v -> IntervalMap k v-insertWith f = insertWithKey (\_ new old -> f new old)---- | Same as 'insertWith', but the combining function is applied strictly.--- This is often the most desirable behavior.-insertWith' :: (Ord k) => (v -> v -> v) -> Interval k -> v -> IntervalMap k v -> IntervalMap k v-insertWith' f = insertWithKey' (\_ new old -> f new old)---- | /O(log n)/. Insert with a function, combining key, new value and old value.--- @'insertWithKey' f key value mp@ --- will insert the pair (key, value) into @mp@ if key does--- not exist in the map. If the key does exist, the function will--- insert the pair @(key, f key new_value old_value)@.--- Note that the key passed to f is the same key passed to 'insertWithKey'.-insertWithKey :: (Ord k) => (Interval k -> v -> v -> v) -> Interval k -> v -> IntervalMap k v -> IntervalMap k v-insertWithKey f key value mp = key `seq` turnBlack (ins mp)- where- singletonR k v = Node R k k v Nil Nil- ins Nil = singletonR key value- ins (Node color k m v l r) =- case compare key k of- LT -> balanceL color k v (ins l) r- GT -> balanceR color k v l (ins r)- EQ -> Node color k m (f k value v) l r---- | Same as 'insertWithKey', but the combining function is applied strictly.-insertWithKey' :: (Ord k) => (Interval k -> v -> v -> v) -> Interval k -> v -> IntervalMap k v -> IntervalMap k v-insertWithKey' f key value mp = key `seq` turnBlack (ins mp)- where- singletonR k v = Node R k k v Nil Nil- ins Nil = value `seq` singletonR key value- ins (Node color k m v l r) =- case compare key k of- LT -> balanceL color k v (ins l) r- GT -> balanceR color k v l (ins r)- EQ -> let v' = f k value v in v' `seq` Node color k m v' l r----- | /O(log n)/. Combine insert with old values retrieval.-insertLookupWithKey :: (Ord k) => (Interval k -> v -> v -> v) -> Interval k -> v -> IntervalMap k v -> (Maybe v, IntervalMap k v)-insertLookupWithKey f key value mp = key `seq` (oldval, turnBlack mp')- where- (oldval, mp') = ins mp- singletonR k v = Node R k k v Nil Nil- ins Nil = (Nothing, singletonR key value)- ins (Node color k m v l r) =- case compare key k of- LT -> case ins l of- (x@(Just _), t') -> (x, Node color k m v t' r)- (Nothing, t') -> (Nothing, balanceL color k v t' r)- GT -> case ins r of- (x@(Just _), t') -> (x, Node color k m v l t')- (Nothing, t') -> (Nothing, balanceR color k v l t')- EQ -> (Just v, Node color k m (f k value v) l r)---- | /O(log n)/. A strict version of 'insertLookupWithKey'.-insertLookupWithKey' :: (Ord k) => (Interval k -> v -> v -> v) -> Interval k -> v -> IntervalMap k v -> (Maybe v, IntervalMap k v)-insertLookupWithKey' f key value mp = key `seq` (oldval, turnBlack mp')- where- (oldval, mp') = ins mp- singletonR k v = Node R k k v Nil Nil- ins Nil = value `seq` (Nothing, singletonR key value)- ins (Node color k m v l r) =- case compare key k of- LT -> case ins l of- (x@(Just _), t') -> (x, Node color k m v t' r)- (Nothing, t') -> (Nothing, balanceL color k v t' r)- GT -> case ins r of- (x@(Just _), t') -> (x, Node color k m v l t')- (Nothing, t') -> (Nothing, balanceR color k v l t')- EQ -> let v' = f k value v in v' `seq` (Just v, Node color k m v' l r)---balanceL :: Ord k => Color -> Interval k -> v -> IntervalMap k v -> IntervalMap k v -> IntervalMap k v-balanceL B zk zv (Node R yk _ yv (Node R xk _ xv a b) c) d =- mNode R yk yv (mNode B xk xv a b) (mNode B zk zv c d)-balanceL B zk zv (Node R xk _ xv a (Node R yk _ yv b c)) d =- mNode R yk yv (mNode B xk xv a b) (mNode B zk zv c d)-balanceL c xk xv l r = mNode c xk xv l r--balanceR :: Ord k => Color -> Interval k -> v -> IntervalMap k v -> IntervalMap k v -> IntervalMap k v-balanceR B xk xv a (Node R yk _ yv b (Node R zk _ zv c d)) =- mNode R yk yv (mNode B xk xv a b) (mNode B zk zv c d)-balanceR B xk xv a (Node R zk _ zv (Node R yk _ yv b c) d) =- mNode R yk yv (mNode B xk xv a b) (mNode B zk zv c d)-balanceR c xk xv l r = mNode c xk xv l r----- min/max---- | /O(log n)/. Returns the smallest key and its associated value.--- Calls 'error' if the map is empty.-findMin :: IntervalMap k v -> (Interval k, v)-findMin (Node _ k _ v Nil _) = (k,v)-findMin (Node _ _ _ _ l _) = findMin l-findMin Nil = error "IntervalMap.findMin: empty map"---- | /O(log n)/. Returns the largest key and its associated value.--- Calls 'error' if the map is empty.-findMax :: IntervalMap k v -> (Interval k, v)-findMax (Node _ k _ v _ Nil) = (k,v)-findMax (Node _ _ _ _ _ r) = findMax r-findMax Nil = error "IntervalMap.findMin: empty map"---- | Returns the interval with the largest endpoint.--- If there is more than one interval with that endpoint,--- return the rightmost.------ /O(n)/, since all keys could have the same endpoint.--- /O(log n)/ average case.-findLast :: Eq k => IntervalMap k v -> (Interval k, v)-findLast Nil = error "IntervalMap.findLast: empty map"-findLast t@(Node _ _ mx _ _ _) = lastMax- where- (lastMax : _) = go t- go Nil = []- go (Node _ k m v l r) | sameU m mx = if sameU k m then go r ++ ((k,v) : go l)- else go r ++ go l- | otherwise = []- sameU a b = upperBound a == upperBound b && rightClosed a == rightClosed b----- Type to indicate whether the number of black nodes changed or stayed the same.-data DeleteResult k v = U !(IntervalMap k v) -- Unchanged- | S !(IntervalMap k v) -- Shrunk--unwrap :: DeleteResult k v -> IntervalMap k v-unwrap (U m) = m-unwrap (S m) = m---- DeleteResult with value-data DeleteResult' k v a = U' !(IntervalMap k v) a- | S' !(IntervalMap k v) a--unwrap' :: DeleteResult' k v a -> IntervalMap k v-unwrap' (U' m _) = m-unwrap' (S' m _) = m---- annotate DeleteResult with value-annotate :: DeleteResult k v -> a -> DeleteResult' k v a-annotate (U m) x = U' m x-annotate (S m) x = S' m x----- | /O(log n)/. Remove the smallest key from the map. Return the empty map if the map is empty.-deleteMin :: (Ord k) => IntervalMap k v -> IntervalMap k v-deleteMin Nil = Nil-deleteMin m = turnBlack (unwrap' (deleteMin' m))--deleteMin' :: Ord k => IntervalMap k v -> DeleteResult' k v (Interval k, v)-deleteMin' Nil = error "deleteMin': Nil"-deleteMin' (Node B k _ v Nil Nil) = S' Nil (k,v)-deleteMin' (Node B k _ v Nil r@(Node R _ _ _ _ _)) = U' (turnBlack r) (k,v)-deleteMin' (Node R k _ v Nil r) = U' r (k,v)-deleteMin' (Node c k _ v l r) =- case deleteMin' l of- (U' l' kv) -> U' (mNode c k v l' r) kv- (S' l' kv) -> annotate (unbalancedR c k v l' r) kv--deleteMax' :: Ord k => IntervalMap k v -> DeleteResult' k v (Interval k, v)-deleteMax' Nil = error "deleteMax': Nil"-deleteMax' (Node B k _ v Nil Nil) = S' Nil (k,v)-deleteMax' (Node B k _ v l@(Node R _ _ _ _ _) Nil) = U' (turnBlack l) (k,v)-deleteMax' (Node R k _ v l Nil) = U' l (k,v)-deleteMax' (Node c k _ v l r) =- case deleteMax' r of- (U' r' kv) -> U' (mNode c k v l r') kv- (S' r' kv) -> annotate (unbalancedL c k v l r') kv---- The left tree lacks one Black node-unbalancedR :: Ord k => Color -> Interval k -> v -> IntervalMap k v -> IntervalMap k v -> DeleteResult k v--- Decreasing one Black node in the right-unbalancedR B k v l r@(Node B _ _ _ _ _) = S (balanceR B k v l (turnRed r))-unbalancedR R k v l r@(Node B _ _ _ _ _) = U (balanceR B k v l (turnRed r))--- Taking one Red node from the right and adding it to the right as Black-unbalancedR B k v l (Node R rk _ rv rl@(Node B _ _ _ _ _) rr)- = U (mNode B rk rv (balanceR B k v l (turnRed rl)) rr)-unbalancedR _ _ _ _ _ = error "unbalancedR"--unbalancedL :: Ord k => Color -> Interval k -> v -> IntervalMap k v -> IntervalMap k v -> DeleteResult k v-unbalancedL R k v l@(Node B _ _ _ _ _) r = U (balanceL B k v (turnRed l) r)-unbalancedL B k v l@(Node B _ _ _ _ _) r = S (balanceL B k v (turnRed l) r)-unbalancedL B k v (Node R lk _ lv ll lr@(Node B _ _ _ _ _)) r- = U (mNode B lk lv ll (balanceL B k v (turnRed lr) r))-unbalancedL _ _ _ _ _ = error "unbalancedL"------ | /O(log n)/. Remove the largest key from the map. Return the empty map if the map is empty.-deleteMax :: (Ord k) => IntervalMap k v -> IntervalMap k v-deleteMax Nil = Nil-deleteMax m = turnBlack (unwrap' (deleteMax' m))---- | /O(log n)/. Delete and return the smallest key.-deleteFindMin :: (Ord k) => IntervalMap k v -> ((Interval k,v), IntervalMap k v)-deleteFindMin mp = case deleteMin' mp of- (U' r v) -> (v, turnBlack r)- (S' r v) -> (v, turnBlack r)---- | /O(log n)/. Delete and return the largest key.-deleteFindMax :: (Ord k) => IntervalMap k v -> ((Interval k,v), IntervalMap k v)-deleteFindMax mp = case deleteMax' mp of- (U' r v) -> (v, turnBlack r)- (S' r v) -> (v, turnBlack r)---- | /O(log n)/. Update or delete value at minimum key.-updateMin :: Ord k => (v -> Maybe v) -> IntervalMap k v -> IntervalMap k v-updateMin f m = updateMinWithKey (\_ v -> f v) m---- | /O(log n)/. Update or delete value at maximum key.-updateMax :: Ord k => (v -> Maybe v) -> IntervalMap k v -> IntervalMap k v-updateMax f m = updateMaxWithKey (\_ v -> f v) m---- | /O(log n)/. Update or delete value at minimum key.-updateMinWithKey :: Ord k => (Interval k -> v -> Maybe v) -> IntervalMap k v -> IntervalMap k v-updateMinWithKey _ Nil = Nil-updateMinWithKey f m = let (k,v) = findMin m in- case f k v of- Just v' -> setMinValue v' m- Nothing -> deleteMin m---- | /O(log n)/. Update or delete value at maximum key.-updateMaxWithKey :: Ord k => (Interval k -> v -> Maybe v) -> IntervalMap k v -> IntervalMap k v-updateMaxWithKey _ Nil = Nil-updateMaxWithKey f m = let (k,v) = findMax m in- case f k v of- Just v' -> setMaxValue v' m- Nothing -> deleteMax m---- | /O(log n)/. Retrieves the minimal (key,value) pair of the map, and--- the map stripped of that element, or 'Nothing' if passed an empty map.------ > minViewWithKey (fromList [(5,"a"), (3,"b")]) == Just ((3,"b"), singleton 5 "a")--- > minViewWithKey empty == Nothing--minViewWithKey :: Ord k => IntervalMap k a -> Maybe ((Interval k, a), IntervalMap k a)-minViewWithKey Nil = Nothing-minViewWithKey x = Just (deleteFindMin x)---- | /O(log n)/. Retrieves the maximal (key,value) pair of the map, and--- the map stripped of that element, or 'Nothing' if passed an empty map.-maxViewWithKey :: Ord k => IntervalMap k a -> Maybe ((Interval k, a), IntervalMap k a)-maxViewWithKey Nil = Nothing-maxViewWithKey x = Just (deleteFindMax x)---- | /O(log n)/. Retrieves the value associated with minimal key of the--- map, and the map stripped of that element, or 'Nothing' if passed an--- empty map.-minView :: Ord k => IntervalMap k a -> Maybe (a, IntervalMap k a)-minView Nil = Nothing-minView x = case deleteFindMin x of ((_,a), x') -> Just (a, x')---- | /O(log n)/. Retrieves the value associated with maximal key of the--- map, and the map stripped of that element, or 'Nothing' if passed an--- empty map.-maxView :: Ord k => IntervalMap k a -> Maybe (a, IntervalMap k a)-maxView Nil = Nothing-maxView x = case deleteFindMax x of ((_,a), x') -> Just (a, x')---setMinValue :: v -> IntervalMap k v -> IntervalMap k v-setMinValue _ Nil = Nil-setMinValue v' (Node c k m _ Nil r) = Node c k m v' Nil r-setMinValue v' (Node c k m v l r) = Node c k m v (setMinValue v' l) r--setMaxValue :: v -> IntervalMap k v -> IntervalMap k v-setMaxValue _ Nil = Nil-setMaxValue v' (Node c k m _ l Nil) = Node c k m v' l Nil-setMaxValue v' (Node c k m v l r) = Node c k m v l (setMaxValue v' r)------ folding---- | /O(n)/. Fold the values in the map using the given right-associative--- binary operator, such that @'foldr' f z == 'Prelude.foldr' f z . 'elems'@.-foldr :: (a -> b -> b) -> b -> IntervalMap k a -> b-foldr _ z Nil = z-foldr f z (Node _ _ _ x l r) = foldr f (f x (foldr f z r)) l---- | /O(n)/. A strict version of 'foldr'. Each application of the operator is--- evaluated before using the result in the next application. This--- function is strict in the starting value.-foldr' :: (a -> b -> b) -> b -> IntervalMap k a -> b-foldr' f z m = z `seq` case m of- Nil -> z- Node _ _ _ x l r -> foldr' f (f x (foldr' f z r)) l---- | /O(n)/. Fold the values in the map using the given left-associative--- binary operator, such that @'foldl' f z == 'Prelude.foldl' f z . 'elems'@.-foldl :: (b -> a -> b) -> b -> IntervalMap k a -> b-foldl _ z Nil = z-foldl f z (Node _ _ _ x l r) = foldl f (f (foldl f z l) x) r---- | /O(n)/. A strict version of 'foldl'. Each application of the operator is--- evaluated before using the result in the next application. This--- function is strict in the starting value.-foldl' :: (b -> a -> b) -> b -> IntervalMap k a -> b-foldl' f z m = z `seq` case m of- Nil -> z- Node _ _ _ x l r -> foldl' f (f (foldl' f z l) x) r---- | /O(n)/. Fold the keys and values in the map using the given right-associative--- binary operator, such that--- @'foldrWithKey' f z == 'Prelude.foldr' ('uncurry' f) z . 'toAscList'@.-foldrWithKey :: (Interval k -> v -> a -> a) -> a -> IntervalMap k v -> a-foldrWithKey _ z Nil = z-foldrWithKey f z (Node _ k _ x l r) = foldrWithKey f (f k x (foldrWithKey f z r)) l---- | /O(n)/. A strict version of 'foldrWithKey'. Each application of the operator is--- evaluated before using the result in the next application. This--- function is strict in the starting value.-foldrWithKey' :: (Interval k -> v -> a -> a) -> a -> IntervalMap k v -> a-foldrWithKey' f z m = z `seq` case m of- Nil -> z- Node _ k _ x l r -> foldrWithKey' f (f k x (foldrWithKey' f z r)) l---- | /O(n)/. Fold the keys and values in the map using the given left-associative--- binary operator, such that--- @'foldlWithKey' f z == 'Prelude.foldl' (\\z' (kx, x) -> f z' kx x) z . 'toAscList'@.-foldlWithKey :: (a -> Interval k -> v -> a) -> a -> IntervalMap k v -> a-foldlWithKey _ z Nil = z-foldlWithKey f z (Node _ k _ x l r) = foldlWithKey f (f (foldlWithKey f z l) k x) r---- | /O(n)/. A strict version of 'foldlWithKey'. Each application of the operator is--- evaluated before using the result in the next application. This--- function is strict in the starting value.-foldlWithKey' :: (a -> Interval k -> v -> a) -> a -> IntervalMap k v -> a-foldlWithKey' f z m = z `seq` case m of- Nil -> z- Node _ k _ x l r -> foldlWithKey' f (f (foldlWithKey' f z l) k x) r---- delete---- | /O(log n)/. Delete a key from the map. If the map does not contain the key,--- it is returned unchanged.-delete :: (Ord k) => Interval k -> IntervalMap k v -> IntervalMap k v-delete key mp = turnBlack (unwrap (delete' key mp))--delete' :: Ord k => Interval k -> IntervalMap k v -> DeleteResult k v-delete' x Nil = x `seq` U Nil-delete' x (Node c k _ v l r) =- case compare x k of- LT -> case delete' x l of- (U l') -> U (mNode c k v l' r)- (S l') -> unbalancedR c k v l' r- GT -> case delete' x r of- (U r') -> U (mNode c k v l r')- (S r') -> unbalancedL c k v l r'- EQ -> case r of- Nil -> if c == B then blackify l else U l- _ -> case deleteMin' r of- (U' r' (rk,rv)) -> U (mNode c rk rv l r')- (S' r' (rk,rv)) -> unbalancedL c rk rv l r'--blackify :: IntervalMap k v -> DeleteResult k v-blackify (Node R k m v l r) = U (Node B k m v l r)-blackify s = S s---- | /O(log n)/. Update a value at a specific key with the result of the provided function.--- When the key is not--- a member of the map, the original map is returned.-adjust :: Ord k => (a -> a) -> Interval k -> IntervalMap k a -> IntervalMap k a-adjust f k m = adjustWithKey (\_ v -> f v) k m---- | /O(log n)/. Adjust a value at a specific key. When the key is not--- a member of the map, the original map is returned.-adjustWithKey :: Ord k => (Interval k -> a -> a) -> Interval k -> IntervalMap k a -> IntervalMap k a-adjustWithKey _ _ Nil = Nil-adjustWithKey f x (Node c k m v l r) =- case compare x k of- LT -> Node c k m v (adjustWithKey f x l) r- GT -> Node c k m v l (adjustWithKey f x r)- EQ -> Node c k m (f k v) l r---- | /O(log n)/. The expression (@'update' f k map@) updates the value @x@--- at @k@ (if it is in the map). If (@f x@) is 'Nothing', the element is--- deleted. If it is (@'Just' y@), the key @k@ is bound to the new value @y@.-update :: Ord k => (a -> Maybe a) -> Interval k -> IntervalMap k a -> IntervalMap k a-update f k m = updateWithKey (\_ v -> f v) k m---- | /O(log n)/. The expression (@'updateWithKey' f k map@) updates the--- value @x@ at @k@ (if it is in the map). If (@f k x@) is 'Nothing',--- the element is deleted. If it is (@'Just' y@), the key @k@ is bound--- to the new value @y@.-updateWithKey :: Ord k => (Interval k -> a -> Maybe a) -> Interval k -> IntervalMap k a -> IntervalMap k a-updateWithKey f k m = snd (updateLookupWithKey f k m)---- | /O(log n)/. Lookup and update. See also 'updateWithKey'.--- The function returns changed value, if it is updated.--- Returns the original key value if the map entry is deleted.-updateLookupWithKey :: Ord k => (Interval k -> a -> Maybe a) -> Interval k -> IntervalMap k a -> (Maybe a, IntervalMap k a)-updateLookupWithKey f x m = case lookup x m of- Nothing -> (Nothing, m)- r@(Just v) -> case f x v of- Nothing -> (r, delete x m)- r'@(Just v') -> (r', adjust (const v') x m)---- | /O(log n)/. The expression (@'alter' f k map@) alters the value @x@ at @k@, or absence thereof.--- 'alter' can be used to insert, delete, or update a value in a 'Map'.--- In short : @'lookup' k ('alter' f k m) = f ('lookup' k m)@.-alter :: Ord k => (Maybe a -> Maybe a) -> Interval k -> IntervalMap k a -> IntervalMap k a-alter f x m = case lookup x m of- Nothing -> case f Nothing of- Nothing -> m- Just v -> insert x v m- y -> case f y of- Nothing -> delete x m- Just v' -> adjust (const v') x m----- | /O(n+m)/. The expression (@'union' t1 t2@) takes the left-biased union of @t1@ and @t2@. --- It prefers @t1@ when duplicate keys are encountered,--- i.e. (@'union' == 'unionWith' 'const'@).-union :: Ord k => IntervalMap k a -> IntervalMap k a -> IntervalMap k a-union m1 m2 = unionWith const m1 m2---- | /O(n+m)/. Union with a combining function.-unionWith :: Ord k => (a -> a -> a) -> IntervalMap k a -> IntervalMap k a -> IntervalMap k a-unionWith f m1 m2 = unionWithKey (\_ v1 v2 -> f v1 v2) m1 m2---- | /O(n+m)/. Union with a combining function.-unionWithKey :: Ord k => (Interval k -> a -> a -> a) -> IntervalMap k a -> IntervalMap k a -> IntervalMap k a-unionWithKey f m1 m2 = fromDistinctAscList (ascListUnion f (toAscList m1) (toAscList m2))---- | The union of a list of maps:--- (@'unions' == 'Prelude.foldl' 'union' 'empty'@).-unions :: Ord k => [IntervalMap k a] -> IntervalMap k a-unions = L.foldl union empty---- | The union of a list of maps, with a combining operation:--- (@'unionsWith' f == 'Prelude.foldl' ('unionWith' f) 'empty'@).-unionsWith :: Ord k => (a -> a -> a) -> [IntervalMap k a] -> IntervalMap k a-unionsWith f = L.foldl (unionWith f) empty---- | /O(n+m)/. Difference of two maps. --- Return elements of the first map not existing in the second map.-difference :: Ord k => IntervalMap k a -> IntervalMap k b -> IntervalMap k a-difference m1 m2 = differenceWithKey (\_ _ _ -> Nothing) m1 m2---- | /O(n+m)/. Difference with a combining function. --- When two equal keys are--- encountered, the combining function is applied to the values of these keys.--- If it returns 'Nothing', the element is discarded (proper set difference). If--- it returns (@'Just' y@), the element is updated with a new value @y@. -differenceWith :: Ord k => (a -> b -> Maybe a) -> IntervalMap k a -> IntervalMap k b -> IntervalMap k a-differenceWith f m1 m2 = differenceWithKey (\_ v1 v2 -> f v1 v2) m1 m2---- | /O(n+m)/. Difference with a combining function. When two equal keys are--- encountered, the combining function is applied to the key and both values.--- If it returns 'Nothing', the element is discarded (proper set difference). If--- it returns (@'Just' y@), the element is updated with a new value @y@. -differenceWithKey :: Ord k => (Interval k -> a -> b -> Maybe a) -> IntervalMap k a -> IntervalMap k b -> IntervalMap k a-differenceWithKey f m1 m2 = fromDistinctAscList (ascListDifference f (toAscList m1) (toAscList m2))---- | /O(n+m)/. Intersection of two maps.--- Return data in the first map for the keys existing in both maps.--- (@'intersection' m1 m2 == 'intersectionWith' 'const' m1 m2@).-intersection :: Ord k => IntervalMap k a -> IntervalMap k b -> IntervalMap k a-intersection m1 m2 = intersectionWithKey (\_ v _ -> v) m1 m2---- | /O(n+m)/. Intersection with a combining function.-intersectionWith :: Ord k => (a -> b -> c) -> IntervalMap k a -> IntervalMap k b -> IntervalMap k c-intersectionWith f m1 m2 = intersectionWithKey (\_ v1 v2 -> f v1 v2) m1 m2---- | /O(n+m)/. Intersection with a combining function.-intersectionWithKey :: Ord k => (Interval k -> a -> b -> c) -> IntervalMap k a -> IntervalMap k b -> IntervalMap k c-intersectionWithKey f m1 m2 = fromDistinctAscList (ascListIntersection f (toAscList m1) (toAscList m2))--ascListUnion :: Ord k => (k -> a -> a -> a) -> [(k,a)] -> [(k,a)] -> [(k,a)]-ascListUnion _ [] [] = []-ascListUnion _ [] ys = ys-ascListUnion _ xs [] = xs-ascListUnion f xs@(x@(xk,xv):xs') ys@(y@(yk,yv):ys') =- case compare xk yk of- LT -> x : ascListUnion f xs' ys- GT -> y : ascListUnion f xs ys'- EQ -> (xk, f xk xv yv) : ascListUnion f xs' ys'--ascListDifference :: Ord k => (k -> a -> b -> Maybe a) -> [(k,a)] -> [(k,b)] -> [(k,a)]-ascListDifference _ [] _ = []-ascListDifference _ xs [] = xs-ascListDifference f xs@(x@(xk,xv):xs') ys@((yk,yv):ys') =- case compare xk yk of- LT -> x : ascListDifference f xs' ys- GT -> ascListDifference f xs ys'- EQ -> case f xk xv yv of- Nothing -> ascListDifference f xs' ys'- Just v' -> (xk,v') : ascListDifference f xs' ys'--ascListIntersection :: Ord k => (k -> a -> b -> c) -> [(k,a)] -> [(k,b)] -> [(k,c)]-ascListIntersection _ [] _ = []-ascListIntersection _ _ [] = []-ascListIntersection f xs@((xk,xv):xs') ys@((yk,yv):ys') =- case compare xk yk of- LT -> ascListIntersection f xs' ys- GT -> ascListIntersection f xs ys'- EQ -> (xk, f xk xv yv) : ascListIntersection f xs' ys'----- --- Conversion ------- | /O(n)/. The list of all key\/value pairs contained in the map, in ascending order of keys.-toAscList :: IntervalMap k v -> [(Interval k,v)]-toAscList m = foldrWithKey (\k v r -> (k,v) : r) [] m---- | /O(n)/. The list of all key\/value pairs contained in the map, in no particular order.-toList :: IntervalMap k v -> [(Interval k,v)]-toList m = toAscList m---- | /O(n)/. The list of all key\/value pairs contained in the map, in descending order of keys.-toDescList :: IntervalMap k v -> [(Interval k, v)]-toDescList m = foldlWithKey (\r k v -> (k,v) : r) [] m---- | /O(n log n)/. Build a map from a list of key\/value pairs. See also 'fromAscList'.--- If the list contains more than one value for the same key, the last value--- for the key is retained.-fromList :: Ord k => [(Interval k,v)] -> IntervalMap k v-fromList xs = L.foldl' (\m (k,v) -> insert k v m) empty xs---- | /O(n log n)/. Build a map from a list of key\/value pairs with a combining function. See also 'fromAscListWith'.-fromListWith :: Ord k => (a -> a -> a) -> [(Interval k,a)] -> IntervalMap k a -fromListWith f xs = fromListWithKey (\_ x y -> f x y) xs---- | /O(n log n)/. Build a map from a list of key\/value pairs with a combining function. See also 'fromAscListWith'.-fromListWithKey :: Ord k => (Interval k -> a -> a -> a) -> [(Interval k,a)] -> IntervalMap k a -fromListWithKey f xs = L.foldl' ins empty xs- where- ins t (k,x) = insertWithKey f k x t---- | /O(n)/. Build a map from an ascending list in linear time.--- /The precondition (input list is ascending) is not checked./-fromAscList :: Ord k => [(Interval k,v)] -> IntervalMap k v-fromAscList xs = fromAscListWith (\_ b -> b) xs---- | /O(n)/. Build a map from an ascending list in linear time with a combining function for equal keys.--- /The precondition (input list is ascending) is not checked./-fromAscListWith :: Ord k => (a -> a -> a) -> [(Interval k,a)] -> IntervalMap k a -fromAscListWith f xs = fromAscListWithKey (\_ a b -> f a b) xs---- | /O(n)/. Build a map from an ascending list in linear time with a combining function for equal keys.--- /The precondition (input list is ascending) is not checked./-fromAscListWithKey :: Ord k => (Interval k -> a -> a -> a) -> [(Interval k,a)] -> IntervalMap k a -fromAscListWithKey f xs = fromDistinctAscList (combineEq f xs)--combineEq :: Eq k => (k -> a -> a -> a) -> [(k,a)] -> [(k,a)]-combineEq _ [] = []-combineEq _ xs@[_] = xs-combineEq f (x@(xk,xv) : xs@((yk,yv) : xs'))- | xk == yk = combineEq f ((xk, f xk xv yv) : xs')- | otherwise = x : combineEq f xs---- | /O(n)/. Build a map from an ascending list of elements with distinct keys in linear time.--- /The precondition is not checked./-fromDistinctAscList :: (Ord k) => [(Interval k,v)] -> IntervalMap k v--- exactly 2^n-1 items have height n. They can be all black--- from 2^n - 2^n-2 items have height n+1. The lowest "row" should be red.-fromDistinctAscList lyst = case h (length lyst) lyst of- (result, []) -> result- _ -> error "fromDistinctAscList: list not fully consumed"- where- h n xs | n == 0 = (Nil, xs)- | isPerfect n = buildB n xs- | otherwise = buildR n (log2 n) xs-- buildB n xs | xs `seq` n <= 0 = error "fromDictinctAscList: buildB 0"- | n == 1 = case xs of ((k,v):xs') -> (Node B k k v Nil Nil, xs')- | otherwise =- case n `quot` 2 of { n' ->- case buildB n' xs of { (l, (k,v):xs') ->- case buildB n' xs' of { (r, xs'') ->- (mNode B k v l r, xs'') }}}-- buildR n d xs | d `seq` xs `seq` n == 0 = (Nil, xs)- | n == 1 = case xs of ((k,v):xs') -> (Node (if d==0 then R else B) k k v Nil Nil, xs')- | otherwise =- case n `quot` 2 of { n' ->- case buildR n' (d-1) xs of { (l, (k,v):xs') ->- case buildR (n - (n' + 1)) (d-1) xs' of { (r, xs'') ->- (mNode B k v l r, xs'') }}}---- is n a perfect binary tree size (2^m-1)?-isPerfect :: Int -> Bool-isPerfect n = (n .&. (n + 1)) == 0--log2 :: Int -> Int-log2 m = h (-1) m- where- h r n | r `seq` n <= 0 = r- | otherwise = h (r + 1) (n `shiftR` 1)----- | /O(n)/. List of all values in the map, in ascending order of their keys.-elems :: IntervalMap k v -> [v]-elems m = [v | (_,v) <- toAscList m]---- | /O(n)/. List of all keys in the map, in ascending order.-keys :: IntervalMap k v -> [Interval k]-keys m = [k | (k,_) <- toAscList m]---- | /O(n)/. Set of the keys.-keysSet :: (Ord k) => IntervalMap k v -> Set.Set (Interval k)-keysSet m = Set.fromDistinctAscList (keys m)---- | Same as 'toAscList'.-assocs :: IntervalMap k v -> [(Interval k, v)]-assocs m = toAscList m---- --- Mapping ------- | /O(n)/. Map a function over all values in the map.-map :: (a -> b) -> IntervalMap k a -> IntervalMap k b-map f = mapWithKey (\_ x -> f x)---- | /O(n)/. Map a function over all values in the map.-mapWithKey :: (Interval k -> a -> b) -> IntervalMap k a -> IntervalMap k b-mapWithKey f = go- where- go Nil = Nil- go (Node c k m v l r) = Node c k m (f k v) (go l) (go r)---- | /O(n)/. The function 'mapAccum' threads an accumulating--- argument through the map in ascending order of keys.------ > let f a b = (a ++ b, b ++ "X")--- > mapAccum f "Everything: " (fromList [(5,"a"), (3,"b")]) == ("Everything: ba", fromList [(3, "bX"), (5, "aX")])-mapAccum :: (a -> b -> (a,c)) -> a -> IntervalMap k b -> (a, IntervalMap k c)-mapAccum f a m = mapAccumWithKey (\a' _ x' -> f a' x') a m---- | /O(n)/. The function 'mapAccumWithKey' threads an accumulating--- argument through the map in ascending order of keys.------ > let f a k b = (a ++ " " ++ (show k) ++ "-" ++ b, b ++ "X")--- > mapAccumWithKey f "Everything:" (fromList [(5,"a"), (3,"b")]) == ("Everything: 3-b 5-a", fromList [(3, "bX"), (5, "aX")])-mapAccumWithKey :: (a -> Interval k -> b -> (a,c)) -> a -> IntervalMap k b -> (a, IntervalMap k c)-mapAccumWithKey f a t = mapAccumL f a t---- | /O(n)/. The function 'mapAccumL' threads an accumulating--- argument throught the map in ascending order of keys.-mapAccumL :: (a -> Interval k -> b -> (a,c)) -> a -> IntervalMap k b -> (a, IntervalMap k c)-mapAccumL f = go- where- go a Nil = (a,Nil)- go a (Node c kx m x l r) =- let (a1,l') = go a l- (a2,x') = f a1 kx x- (a3,r') = go a2 r- in (a3, Node c kx m x' l' r')---- | /O(n)/. The function 'mapAccumR' threads an accumulating--- argument through the map in descending order of keys.-mapAccumRWithKey :: (a -> Interval k -> b -> (a,c)) -> a -> IntervalMap k b -> (a, IntervalMap k c)-mapAccumRWithKey f = go- where- go a Nil = (a, Nil)- go a (Node c kx m x l r) =- let (a1,r') = go a r- (a2,x') = f a1 kx x- (a3,l') = go a2 l- in (a3, Node c kx m x' l' r')----- | /O(n log n)/. @'mapKeys' f s@ is the map obtained by applying @f@ to each key of @s@.--- --- The size of the result may be smaller if @f@ maps two or more distinct--- keys to the same new key. In this case the value at the smallest of--- these keys is retained.-mapKeys :: Ord k2 => (Interval k1 -> Interval k2) -> IntervalMap k1 a -> IntervalMap k2 a-mapKeys f m = fromList [ (f k, v) | (k, v) <- toDescList m ]---- | /O(n log n)/. @'mapKeysWith' c f s@ is the map obtained by applying @f@ to each key of @s@.--- --- The size of the result may be smaller if @f@ maps two or more distinct--- keys to the same new key. In this case the associated values will be--- combined using @c@.-mapKeysWith :: Ord k2 => (a -> a -> a) -> (Interval k1 -> Interval k2) -> IntervalMap k1 a -> IntervalMap k2 a-mapKeysWith c f m = fromListWith c [ (f k, v) | (k, v) <- toAscList m ]---- | /O(n log n)/. @'mapKeysMonotonic' f s == 'mapKeys' f s@, but works only when @f@--- is strictly monotonic.--- That is, for any values @x@ and @y@, if @x@ < @y@ then @f x@ < @f y@.--- /The precondition is not checked./-mapKeysMonotonic :: Ord k2 => (Interval k1 -> Interval k2) -> IntervalMap k1 a -> IntervalMap k2 a-mapKeysMonotonic _ Nil = Nil-mapKeysMonotonic f (Node c k _ x l r) =- mNode c (f k) x (mapKeysMonotonic f l) (mapKeysMonotonic f r)---- | /O(n)/. Filter values satisfying a predicate.-filter :: Ord k => (a -> Bool) -> IntervalMap k a -> IntervalMap k a-filter p m = filterWithKey (\_ v -> p v) m---- | /O(n)/. Filter keys\/values satisfying a predicate.-filterWithKey :: Ord k => (Interval k -> a -> Bool) -> IntervalMap k a -> IntervalMap k a-filterWithKey p m = mapMaybeWithKey (\k v -> if p k v then Just v else Nothing) m---- | /O(n)/. Partition the map according to a predicate. The first--- map contains all elements that satisfy the predicate, the second all--- elements that fail the predicate. See also 'split'.-partition :: Ord k => (a -> Bool) -> IntervalMap k a -> (IntervalMap k a, IntervalMap k a)-partition p m = partitionWithKey (\_ v -> p v) m---- | /O(n)/. Partition the map according to a predicate. The first--- map contains all elements that satisfy the predicate, the second all--- elements that fail the predicate. See also 'split'.-partitionWithKey :: Ord k => (Interval k -> a -> Bool) -> IntervalMap k a -> (IntervalMap k a, IntervalMap k a)-partitionWithKey p m = mapEitherWithKey p' m- where- p' k v | p k v = Left v- | otherwise = Right v---- | /O(n)/. Map values and collect the 'Just' results.-mapMaybe :: Ord k => (a -> Maybe b) -> IntervalMap k a -> IntervalMap k b-mapMaybe f m = mapMaybeWithKey (\_ v -> f v) m---- | /O(n)/. Map keys\/values and collect the 'Just' results.-mapMaybeWithKey :: Ord k => (Interval k -> a -> Maybe b) -> IntervalMap k a -> IntervalMap k b-mapMaybeWithKey f m = fromDistinctAscList (mapf [] m)- where- mapf z Nil = z- mapf z (Node _ k _ v l r) = mapf (f' k v z r) l- f' k v z r = case f k v of- Nothing -> mapf z r- Just v' -> (k,v') : mapf z r---- | /O(n)/. Map values and separate the 'Left' and 'Right' results.-mapEither :: Ord k => (a -> Either b c) -> IntervalMap k a -> (IntervalMap k b, IntervalMap k c)-mapEither f m = mapEitherWithKey (\_ v -> f v) m---- | /O(n)/. Map keys\/values and separate the 'Left' and 'Right' results.-mapEitherWithKey :: Ord k => (Interval k -> a -> Either b c) -> IntervalMap k a -> (IntervalMap k b, IntervalMap k c)-mapEitherWithKey f m = (fromDistinctAscList l, fromDistinctAscList r)- where- (l, r) = part [] [] (toDescList m)- part ls rs [] = (ls, rs)- part ls rs ((k,v):xs) = case f k v of- Left v' -> part ((k,v'):ls) rs xs- Right v' -> part ls ((k,v'):rs) xs---- | /O(n)/. The expression (@'split' k map@) is a pair @(map1,map2)@ where--- the keys in @map1@ are smaller than @k@ and the keys in @map2@ larger than @k@.--- Any key equal to @k@ is found in neither @map1@ nor @map2@.-split :: Ord k => Interval k -> IntervalMap k a -> (IntervalMap k a, IntervalMap k a)-split x m = (l, r)- where (l, _, r) = splitLookup x m- --- | /O(n)/. The expression (@'splitLookup' k map@) splits a map just--- like 'split' but also returns @'lookup' k map@. -splitLookup :: Ord k => Interval k -> IntervalMap k a -> (IntervalMap k a, Maybe a, IntervalMap k a)-splitLookup x m = (fromDistinctAscList less, lookup x m, fromDistinctAscList greater)- where- less = [e | e@(k,_) <- toAscList m, k < x]- greater = [e | e@(k,_) <- toAscList m, k > x]---- submaps---- | /O(n+m)/. This function is defined as (@'isSubmapOf' = 'isSubmapOfBy' (==)@).-isSubmapOf :: (Ord k, Eq a) => IntervalMap k a -> IntervalMap k a -> Bool-isSubmapOf m1 m2 = isSubmapOfBy (==) m1 m2--{- | /O(n+m)/.- The expression (@'isSubmapOfBy' f t1 t2@) returns 'True' if- all keys in @t1@ are in tree @t2@, and @f@ returns 'True' when- applied to their respective values.--}-isSubmapOfBy :: Ord k => (a -> b -> Bool) -> IntervalMap k a -> IntervalMap k b -> Bool-isSubmapOfBy f m1 m2 = go (toAscList m1) (toAscList m2)- where- go [] _ = True- go (_:_) [] = False- go s1@((k1,v1):r1) ((k2,v2):r2) =- case compare k1 k2 of- GT -> go s1 r2- EQ -> f v1 v2 && go r1 r2- LT -> False---- | /O(n+m)/. Is this a proper submap? (ie. a submap but not equal). --- Defined as (@'isProperSubmapOf' = 'isProperSubmapOfBy' (==)@).-isProperSubmapOf :: (Ord k, Eq a) => IntervalMap k a -> IntervalMap k a -> Bool-isProperSubmapOf m1 m2 = isProperSubmapOfBy (==) m1 m2--{- | /O(n+m)/. Is this a proper submap? (ie. a submap but not equal).- The expression (@'isProperSubmapOfBy' f m1 m2@) returns 'True' when- @m1@ and @m2@ are not equal,- all keys in @m1@ are in @m2@, and when @f@ returns 'True' when- applied to their respective values.--}-isProperSubmapOfBy :: Ord k => (a -> b -> Bool) -> IntervalMap k a -> IntervalMap k b -> Bool-isProperSubmapOfBy f t1 t2 = size t1 < size t2 && isSubmapOfBy f t1 t2----- debugging---- | Check red-black-tree and interval search augmentation invariants.--- For testing/debugging only.-valid :: Ord k => IntervalMap k v -> Bool-valid mp = test mp && height mp <= maxHeight (size mp) && validColor mp- where- test Nil = True- test n@(Node _ _ _ _ l r) = validOrder n && validMax n && test l && test r- validMax (Node _ k m _ lo hi) = m == maxUpper k lo hi- validMax Nil = True-- validOrder (Node _ _ _ _ Nil Nil) = True- validOrder (Node _ k1 _ _ Nil (Node _ k2 _ _ _ _)) = k1 < k2- validOrder (Node _ k2 _ _ (Node _ k1 _ _ _ _) Nil) = k1 < k2- validOrder (Node _ k2 _ _ (Node _ k1 _ _ _ _) (Node _ k3 _ _ _ _)) = k1 < k2 && k2 < k3- validOrder Nil = True-- -- validColor parentColor blackCount tree- validColor n = blackDepth n >= 0-- -- return -1 if subtrees have diffrent black depths or two consecutive red nodes are encountered- blackDepth :: IntervalMap k v -> Int- blackDepth Nil = 0- blackDepth (Node c _ _ _ l r) = case blackDepth l of- ld -> if ld < 0 then ld- else- case blackDepth r of- rd -> if rd < 0 then rd- else if rd /= ld then -1- else if c == R && (isRed l || isRed r) then -1- else if c == B then rd + 1- else rd-+{- |+Module : Data.IntervalMap+Copyright : (c) Christoph Breitkopf 2011+License : BSD-style+Maintainer : chbreitkopf@gmail.com+Stability : experimental+Portability : portable++An implementation of maps from intervals to values. The key intervals may+overlap, and the implementation contains efficient search functions+for all keys containing a point or overlapping an interval.+Closed, open, and half-open intervals can be contained in the same map.++This module re-exports the value lazy "Data.IntervalMap.Lazy" API, plus+several value strict functions from "Data.IntervalMap.Strict".+-}+module Data.IntervalMap+ ( module Data.IntervalMap.Lazy+ , insertWith'+ , insertWithKey'+ , insertLookupWithKey'+ , fold+ , foldWithKey+ ) where++import Data.IntervalMap.Lazy+import qualified Data.IntervalMap.Lazy as L+import qualified Data.IntervalMap.Strict as S++-- | /Deprecated./ As of version 0.3, replaced by 'S.insertWith'.+--+-- /O(log n)/. Same as 'insertWith', but the combining function is+-- applied strictly. This is often the most desirable behavior.+--+-- For example, to update a counter:+--+-- > insertWith' (+) k 1 m+--+insertWith' :: Ord k => (a -> a -> a) -> Interval k -> a -> IntervalMap k a -> IntervalMap k a+insertWith' = S.insertWith+{-# INLINABLE insertWith' #-}++-- | /Deprecated./ As of version 0.3, replaced by 'S.insertWithKey'.+--+-- /O(log n)/. Same as 'insertWithKey', but the combining function is+-- applied strictly.+insertWithKey' :: Ord k => (Interval k -> a -> a -> a) -> Interval k -> a -> IntervalMap k a -> IntervalMap k a+insertWithKey' = S.insertWithKey+{-# INLINABLE insertWithKey' #-}++-- | /Deprecated./ As of version 0.3, replaced by+-- 'S.insertLookupWithKey'.+--+-- /O(log n)/. A strict version of 'insertLookupWithKey'.+insertLookupWithKey' :: Ord k => (Interval k -> a -> a -> a) -> Interval k -> a -> IntervalMap k a+ -> (Maybe a, IntervalMap k a)+insertLookupWithKey' = S.insertLookupWithKey++-- | /Deprecated./ As of version 0.5, replaced by 'L.foldr'.+--+-- /O(n)/. Fold the values in the map using the given right-associative+-- binary operator. This function is an equivalent of 'foldr' and is present+-- for compatibility only.+fold :: (a -> b -> b) -> b -> IntervalMap k a -> b+fold = L.foldr++-- | /Deprecated./ As of version 0.3, replaced by 'L.foldrWithKey'.+--+-- /O(n)/. Fold the keys and values in the map using the given right-associative+-- binary operator. This function is an equivalent of 'foldrWithKey' and is present+-- for compatibility only.+foldWithKey :: (Interval k -> a -> b -> b) -> b -> IntervalMap k a -> b+foldWithKey = foldrWithKey
+ Data/IntervalMap/Base.hs view
@@ -0,0 +1,1267 @@+-- |+-- Module : Data.IntervalMap.Base+-- Copyright : (c) Christoph Breitkopf 2011+-- License : BSD-style+-- Maintainer : chbreitkopf@gmail.com+-- Stability : experimental+-- Portability : portable+--+-- An implementation of maps from intervals to values. The key intervals may+-- overlap, and the implementation contains efficient search functions+-- for all keys containing a point or overlapping an interval.+-- Closed, open, and half-open intervals can be contained in the same map.+--+-- An IntervalMap cannot contain duplicate keys - if you need to map a key+-- to muiltiple values, use a collection as the value type, for+-- example: @IntervalMap /k/ [/v/]@.+--+-- It is an error to insert an empty interval into a map. This precondition is not+-- checked by the various construction functions.+--+-- Since many function names (but not the type name) clash with+-- /Prelude/ names, this module is usually imported @qualified@, e.g.+--+-- > import Data.IntervalMap (IvMap)+-- > import qualified Data.IntervalMap as IvMap+--+-- It offers most of the same functions as 'Data.Map', but uses 'Interval' /k/ instead of+-- just /k/ as the key type. Some of the functions need stricter type constraints to+-- maintain the additional information for efficient interval searching,+-- for example 'fromDistinctAscList' needs an 'Ord' /k/ constraint.+-- Also, some functions differ in asymptotic performance (for example 'size') or have not+-- been tuned for efficiency as much as their equivalents in 'Data.Map' (in+-- particular the various set functions).+--+-- In addition, there are functions specific to maps of intervals, for example to search+-- for all keys containing a given point or contained in a given interval.+--+-- To stay compatible with standard Haskell, this implementation uses a fixed data+-- type for intervals, and not a multi-parameter type class. Thus, it's currently+-- not possible to define e.g. a 2-tuple as an instance of interval and use that+-- map key. Instead, you must convert your keys to 'Interval'.+--+-- The implementation is a red-black tree augmented with the maximum upper bound+-- of all keys.+--+-- Parts of this implementation are based on code from the 'Data.Map' implementation,+-- (c) Daan Leijen 2002, (c) Andriy Palamarchuk 2008.+-- The red-black tree deletion is based on code from llrbtree by Kazu Yamamoto.+-- Of course, any errors are mine.+--+module Data.IntervalMap.Base (+ -- * re-export+ Interval(..)+ -- * Map type+ , IntervalMap(..) -- instance Eq,Show,Read++ -- * Operators+ , (!), (\\)++ -- * Query+ , null+ , size+ , member+ , notMember+ , lookup+ , findWithDefault++ -- ** Interval query+ , containing+ , intersecting+ , within+ + -- * Construction+ , empty+ , singleton++ -- ** Insertion+ , insert+ , insertWith+ , insertWith'+ , insertWithKey+ , insertWithKey'+ , insertLookupWithKey+ , insertLookupWithKey'+ + -- ** Delete\/Update+ , delete+ , adjust+ , adjustWithKey+ , update+ , updateWithKey+ , updateLookupWithKey+ , alter++ -- * Combine++ -- ** Union+ , union+ , unionWith+ , unionWithKey+ , unions+ , unionsWith++ -- ** Difference+ , difference+ , differenceWith+ , differenceWithKey+ + -- ** Intersection+ , intersection+ , intersectionWith+ , intersectionWithKey++ -- * Traversal+ -- ** Map+ , map+ , mapWithKey+ , mapAccum+ , mapAccumWithKey+ , mapAccumRWithKey+ , mapKeys+ , mapKeysWith+ , mapKeysMonotonic++ -- ** Fold+ , foldr, foldl+ , foldrWithKey, foldlWithKey+ , foldl', foldr'+ , foldrWithKey', foldlWithKey'++ -- * Conversion+ , elems+ , keys+ , keysSet+ , assocs++ -- ** Lists+ , toList+ , fromList+ , fromListWith+ , fromListWithKey++ -- ** Ordered lists+ , toAscList+ , toDescList+ , fromAscList+ , fromAscListWith+ , fromAscListWithKey+ , fromDistinctAscList++ -- * Filter+ , filter+ , filterWithKey+ , partition+ , partitionWithKey++ , mapMaybe+ , mapMaybeWithKey+ , mapEither+ , mapEitherWithKey++ , split+ , splitLookup++ -- * Submap+ , isSubmapOf, isSubmapOfBy+ , isProperSubmapOf, isProperSubmapOfBy++ -- * Min\/Max+ , findMin+ , findMax+ , findLast+ , deleteMin+ , deleteMax+ , deleteFindMin+ , deleteFindMax+ , updateMin+ , updateMax+ , updateMinWithKey+ , updateMaxWithKey+ , minView+ , maxView+ , minViewWithKey+ , maxViewWithKey++ -- * Internal, not re-exported by Data.IntervalMap.{Lazy,Strict}+ , Color(..)+ , balanceL, balanceR+ , turnBlack++ -- * Debugging+ , valid++ -- * Testing+ , height, maxHeight, showStats++ ) where++import Prelude hiding (null, lookup, map, filter, foldr, foldl)+import Data.Bits (shiftR, (.&.))+import Data.Monoid (Monoid(..))+import Control.Applicative (Applicative(..), (<$>))+import Data.Traversable (Traversable(traverse))+import qualified Data.Foldable as Foldable+import qualified Data.List as L+import qualified Data.Set as Set+import Control.DeepSeq (NFData(rnf))++import Data.IntervalMap.Interval++{--------------------------------------------------------------------+ Operators+--------------------------------------------------------------------}+infixl 9 !,\\ --++-- | /O(log n)/. Lookup value for given key. Calls 'error' if the key is not in the map.+(!) :: (Ord k) => IntervalMap k v -> Interval k -> v+tree ! key = case lookup key tree of+ Just v -> v+ Nothing -> error "IntervalMap.!: key not found"++-- | Same as 'difference'.+(\\) :: Ord k => IntervalMap k a -> IntervalMap k b -> IntervalMap k a+m1 \\ m2 = difference m1 m2+++data Color = R | B deriving (Eq, Read, Show)++-- | A map from intervals with endpoints of type @k@ to values of type @v@.+data IntervalMap k v = Nil+ | Node !Color+ !(Interval k) -- key+ !(Interval k) -- interval with maximum upper in tree+ v -- value+ !(IntervalMap k v) -- left subtree+ !(IntervalMap k v) -- right subtree++instance (Eq k, Eq v) => Eq (IntervalMap k v) where+ a == b = toAscList a == toAscList b++instance (Ord k, Ord v) => Ord (IntervalMap k v) where+ compare a b = compare (toAscList a) (toAscList b)++instance Functor (IntervalMap k) where+ fmap f m = map f m++instance (Ord k) => Monoid (IntervalMap k v) where+ mempty = empty+ mappend = union+ mconcat = unions++instance Traversable (IntervalMap k) where+ traverse _ Nil = pure Nil+ traverse f (Node c k m v l r)+ = flip (Node c k m) <$> traverse f l <*> f v <*> traverse f r++instance Foldable.Foldable (IntervalMap k) where+ fold Nil = mempty+ fold (Node _ _ _ v l r) = Foldable.fold l `mappend` v `mappend` Foldable.fold r+ foldr = foldr+ foldl = foldl+ foldMap _ Nil = mempty+ foldMap f (Node _ _ _ v l r) = Foldable.foldMap f l `mappend` f v `mappend` Foldable.foldMap f r++instance (NFData k, NFData a) => NFData (IntervalMap k a) where+ rnf Nil = ()+ rnf (Node _ kx _ x l r) = rnf kx `seq` rnf x `seq` rnf l `seq` rnf r++instance (Ord k, Read k, Read e) => Read (IntervalMap k e) where+ readsPrec p = readParen (p > 10) $ \ r -> do+ ("fromList",s) <- lex r+ (xs,t) <- reads s+ return (fromList xs,t)++instance (Show k, Show a) => Show (IntervalMap k a) where+ showsPrec d m = showParen (d > 10) $+ showString "fromList " . shows (toList m)+++isRed :: IntervalMap k v -> Bool+isRed (Node R _ _ _ _ _) = True+isRed _ = False++turnBlack :: IntervalMap k v -> IntervalMap k v+turnBlack (Node R k m vs l r) = Node B k m vs l r+turnBlack t = t++turnRed :: IntervalMap k v -> IntervalMap k v+turnRed Nil = error "turnRed: Leaf"+turnRed (Node B k m v l r) = Node R k m v l r+turnRed t = t++-- construct node, recomputing the upper key bound.+mNode :: (Ord k) => Color -> Interval k -> v -> IntervalMap k v -> IntervalMap k v -> IntervalMap k v+mNode c k v l r = Node c k (maxUpper k l r) v l r++maxUpper :: Ord k => Interval k -> IntervalMap k v -> IntervalMap k v -> Interval k+maxUpper k Nil Nil = k `seq` k+maxUpper k Nil (Node _ _ m _ _ _) = maxByUpper k m+maxUpper k (Node _ _ m _ _ _) Nil = maxByUpper k m+maxUpper k (Node _ _ l _ _ _) (Node _ _ r _ _ _) = maxByUpper k (maxByUpper l r)++-- interval with the greatest upper bound. The lower bound is ignored!+maxByUpper :: Ord a => Interval a -> Interval a -> Interval a+maxByUpper a@(IntervalCO _ u) b = if u > upperBound b then a else b+maxByUpper a@(ClosedInterval _ u) b = if u >= upperBound b then a else b+maxByUpper a@(OpenInterval _ u) b = if u > upperBound b then a else b+maxByUpper a@(IntervalOC _ u) b = if u >= upperBound b then a else b+++-- ---------------------------------------------------------++-- | /O(1)/. The empty map.+empty :: IntervalMap k v+empty = Nil++-- | /O(1)/. A map with one entry.+singleton :: Interval k -> v -> IntervalMap k v+singleton k v = Node B k k v Nil Nil+++-- | /O(1)/. Is the map empty?+null :: IntervalMap k v -> Bool+null Nil = True+null _ = False++-- | /O(n)/. Number of keys in the map.+--+-- Caution: unlike 'Data.Map.size', which takes constant time, this is linear in the+-- number of keys!+size :: IntervalMap k v -> Int+size t = h 0 t+ where+ h n m = n `seq` case m of+ Nil -> n+ Node _ _ _ _ l r -> h (h n l + 1) r++-- | The height of the tree. For testing/debugging only.+height :: IntervalMap k v -> Int+height Nil = 0+height (Node _ _ _ _ l r) = 1 + max (height l) (height r)++-- | The maximum height of a red-black tree with the given number of nodes.+-- For testing/debugging only.+maxHeight :: Int -> Int+maxHeight nodes = 2 * log2 (nodes + 1)++-- | Tree statistics (size, height, maxHeight size).+-- For testing/debugging only.+showStats :: IntervalMap k a -> (Int, Int, Int)+showStats m = (n, height m, maxHeight n)+ where n = size m++-- | /O(log n)/. Does the map contain the given key? See also 'notMember'.+member :: (Ord k) => Interval k -> IntervalMap k v -> Bool+member key tree = case lookup key tree of+ Nothing -> False+ Just _ -> True++-- | /O(log n)/. Does the map not contain the given key? See also 'member'.+notMember :: (Ord k) => Interval k -> IntervalMap k v -> Bool+notMember key tree = not (member key tree)+++-- | /O(log n)/. Look up the given key in the map, returning the value @('Just' value)@,+-- or 'Nothing' if the key is not in the map.+lookup :: (Ord k) => Interval k -> IntervalMap k v -> Maybe v+lookup k Nil = k `seq` Nothing+lookup k (Node _ key _ v l r) = case compare k key of+ LT -> lookup k l+ GT -> lookup k r+ EQ -> Just v+++-- | /O(log n)/. The expression @('findWithDefault' def k map)@ returns+-- the value at key @k@ or returns default value @def@+-- when the key is not in the map.+--+-- > findWithDefault 'x' 1 (fromList [(5,'a'), (3,'b')]) == 'x'+-- > findWithDefault 'x' 5 (fromList [(5,'a'), (3,'b')]) == 'a'++findWithDefault :: Ord k => a -> Interval k -> IntervalMap k a -> a+findWithDefault def k m = case lookup k m of+ Nothing -> def+ Just x -> x++-- | Return all key/value pairs where the key intervals contain the given point.+-- The elements are returned in ascending key order.+--+-- /O(n)/, since potentially all keys could contain the point.+-- /O(log n)/ average case. This is also the worst case for maps containing no overlapping keys.+containing :: (Ord k) => IntervalMap k v -> k -> [(Interval k, v)]+t `containing` pt = go [] pt t+ where+ go xs p Nil = p `seq` xs+ go xs p (Node _ k m v l r)+ | p `above` m = xs -- above all intervals in the tree: no result+ | p `below` k = go xs p l -- to the left of the lower bound: can't be in right subtree+ | p `inside` k = go ((k,v) : go xs p r) p l+ | otherwise = go (go xs p r) p l++-- | Return all key/value pairs where the key intervals overlap (intersect) the given interval.+-- The elements are returned in ascending key order.+--+-- /O(n)/, since potentially all keys could intersect the interval.+-- /O(log n)/ average case, if few keys intersect the interval.+intersecting :: (Ord k) => IntervalMap k v -> Interval k -> [(Interval k, v)]+t `intersecting` iv = go [] iv t+ where+ go xs i Nil = i `seq` xs+ go xs i (Node _ k m v l r)+ | i `after` m = xs+ | i `before` k = go xs i l+ | i `overlaps` k = go ((k,v) : go xs i r) i l+ | otherwise = go (go xs i r) i l++-- | Return all key/value pairs where the key intervals are completely inside the given interval.+-- The elements are returned in ascending key order.+--+-- /O(n)/, since potentially all keys could be inside the interval.+-- /O(log n)/ average case, if few keys are inside the interval.+within :: (Ord k) => IntervalMap k v -> Interval k -> [(Interval k, v)]+t `within` iv = go [] iv t+ where+ go xs i Nil = i `seq` xs+ go xs i (Node _ k m v l r)+ | i `after` m = xs+ | i `before` k = go xs i l+ | i `subsumes` k = go ((k,v) : go xs i r) i l+ | otherwise = go (go xs i r) i l+++-- | /O(log n)/. Insert a new key/value pair. If the map already contains the key, its value is+-- changed to the new value.+insert :: (Ord k) => Interval k -> v -> IntervalMap k v -> IntervalMap k v+insert = insertWithKey' (\_ v _ -> v)++-- | /O(log n)/. Insert with a function, combining new value and old value.+-- @'insertWith' f key value mp@ +-- will insert the pair (key, value) into @mp@ if key does+-- not exist in the map. If the key does exist, the function will+-- insert the pair @(key, f new_value old_value)@.+insertWith :: (Ord k) => (v -> v -> v) -> Interval k -> v -> IntervalMap k v -> IntervalMap k v+insertWith f = insertWithKey (\_ new old -> f new old)++-- | Same as 'insertWith', but the combining function is applied strictly.+-- This is often the most desirable behavior.+insertWith' :: (Ord k) => (v -> v -> v) -> Interval k -> v -> IntervalMap k v -> IntervalMap k v+insertWith' f = insertWithKey' (\_ new old -> f new old)++-- | /O(log n)/. Insert with a function, combining key, new value and old value.+-- @'insertWithKey' f key value mp@ +-- will insert the pair (key, value) into @mp@ if key does+-- not exist in the map. If the key does exist, the function will+-- insert the pair @(key, f key new_value old_value)@.+-- Note that the key passed to f is the same key passed to 'insertWithKey'.+insertWithKey :: (Ord k) => (Interval k -> v -> v -> v) -> Interval k -> v -> IntervalMap k v -> IntervalMap k v+insertWithKey f key value mp = key `seq` turnBlack (ins mp)+ where+ singletonR k v = Node R k k v Nil Nil+ ins Nil = singletonR key value+ ins (Node color k m v l r) =+ case compare key k of+ LT -> balanceL color k v (ins l) r+ GT -> balanceR color k v l (ins r)+ EQ -> Node color k m (f k value v) l r++-- | Same as 'insertWithKey', but the combining function is applied strictly.+insertWithKey' :: (Ord k) => (Interval k -> v -> v -> v) -> Interval k -> v -> IntervalMap k v -> IntervalMap k v+insertWithKey' f key value mp = key `seq` turnBlack (ins mp)+ where+ singletonR k v = Node R k k v Nil Nil+ ins Nil = value `seq` singletonR key value+ ins (Node color k m v l r) =+ case compare key k of+ LT -> balanceL color k v (ins l) r+ GT -> balanceR color k v l (ins r)+ EQ -> let v' = f k value v in v' `seq` Node color k m v' l r+++-- | /O(log n)/. Combine insert with old values retrieval.+insertLookupWithKey :: (Ord k) => (Interval k -> v -> v -> v) -> Interval k -> v -> IntervalMap k v -> (Maybe v, IntervalMap k v)+insertLookupWithKey f key value mp = key `seq` (oldval, turnBlack mp')+ where+ (oldval, mp') = ins mp+ singletonR k v = Node R k k v Nil Nil+ ins Nil = (Nothing, singletonR key value)+ ins (Node color k m v l r) =+ case compare key k of+ LT -> case ins l of+ (x@(Just _), t') -> (x, Node color k m v t' r)+ (Nothing, t') -> (Nothing, balanceL color k v t' r)+ GT -> case ins r of+ (x@(Just _), t') -> (x, Node color k m v l t')+ (Nothing, t') -> (Nothing, balanceR color k v l t')+ EQ -> (Just v, Node color k m (f k value v) l r)++-- | /O(log n)/. A strict version of 'insertLookupWithKey'.+insertLookupWithKey' :: (Ord k) => (Interval k -> v -> v -> v) -> Interval k -> v -> IntervalMap k v -> (Maybe v, IntervalMap k v)+insertLookupWithKey' f key value mp = key `seq` (oldval, turnBlack mp')+ where+ (oldval, mp') = ins mp+ singletonR k v = Node R k k v Nil Nil+ ins Nil = value `seq` (Nothing, singletonR key value)+ ins (Node color k m v l r) =+ case compare key k of+ LT -> case ins l of+ (x@(Just _), t') -> (x, Node color k m v t' r)+ (Nothing, t') -> (Nothing, balanceL color k v t' r)+ GT -> case ins r of+ (x@(Just _), t') -> (x, Node color k m v l t')+ (Nothing, t') -> (Nothing, balanceR color k v l t')+ EQ -> let v' = f k value v in v' `seq` (Just v, Node color k m v' l r)+++balanceL :: Ord k => Color -> Interval k -> v -> IntervalMap k v -> IntervalMap k v -> IntervalMap k v+balanceL B zk zv (Node R yk _ yv (Node R xk _ xv a b) c) d =+ mNode R yk yv (mNode B xk xv a b) (mNode B zk zv c d)+balanceL B zk zv (Node R xk _ xv a (Node R yk _ yv b c)) d =+ mNode R yk yv (mNode B xk xv a b) (mNode B zk zv c d)+balanceL c xk xv l r = mNode c xk xv l r++balanceR :: Ord k => Color -> Interval k -> v -> IntervalMap k v -> IntervalMap k v -> IntervalMap k v+balanceR B xk xv a (Node R yk _ yv b (Node R zk _ zv c d)) =+ mNode R yk yv (mNode B xk xv a b) (mNode B zk zv c d)+balanceR B xk xv a (Node R zk _ zv (Node R yk _ yv b c) d) =+ mNode R yk yv (mNode B xk xv a b) (mNode B zk zv c d)+balanceR c xk xv l r = mNode c xk xv l r+++-- min/max++-- | /O(log n)/. Returns the smallest key and its associated value.+-- Calls 'error' if the map is empty.+findMin :: IntervalMap k v -> (Interval k, v)+findMin (Node _ k _ v Nil _) = (k,v)+findMin (Node _ _ _ _ l _) = findMin l+findMin Nil = error "IntervalMap.findMin: empty map"++-- | /O(log n)/. Returns the largest key and its associated value.+-- Calls 'error' if the map is empty.+findMax :: IntervalMap k v -> (Interval k, v)+findMax (Node _ k _ v _ Nil) = (k,v)+findMax (Node _ _ _ _ _ r) = findMax r+findMax Nil = error "IntervalMap.findMin: empty map"++-- | Returns the interval with the largest endpoint.+-- If there is more than one interval with that endpoint,+-- return the rightmost.+--+-- /O(n)/, since all keys could have the same endpoint.+-- /O(log n)/ average case.+findLast :: Eq k => IntervalMap k v -> (Interval k, v)+findLast Nil = error "IntervalMap.findLast: empty map"+findLast t@(Node _ _ mx _ _ _) = lastMax+ where+ (lastMax : _) = go t+ go Nil = []+ go (Node _ k m v l r) | sameU m mx = if sameU k m then go r ++ ((k,v) : go l)+ else go r ++ go l+ | otherwise = []+ sameU a b = upperBound a == upperBound b && rightClosed a == rightClosed b+++-- Type to indicate whether the number of black nodes changed or stayed the same.+data DeleteResult k v = U !(IntervalMap k v) -- Unchanged+ | S !(IntervalMap k v) -- Shrunk++unwrap :: DeleteResult k v -> IntervalMap k v+unwrap (U m) = m+unwrap (S m) = m++-- DeleteResult with value+data DeleteResult' k v a = U' !(IntervalMap k v) a+ | S' !(IntervalMap k v) a++unwrap' :: DeleteResult' k v a -> IntervalMap k v+unwrap' (U' m _) = m+unwrap' (S' m _) = m++-- annotate DeleteResult with value+annotate :: DeleteResult k v -> a -> DeleteResult' k v a+annotate (U m) x = U' m x+annotate (S m) x = S' m x+++-- | /O(log n)/. Remove the smallest key from the map. Return the empty map if the map is empty.+deleteMin :: (Ord k) => IntervalMap k v -> IntervalMap k v+deleteMin Nil = Nil+deleteMin m = turnBlack (unwrap' (deleteMin' m))++deleteMin' :: Ord k => IntervalMap k v -> DeleteResult' k v (Interval k, v)+deleteMin' Nil = error "deleteMin': Nil"+deleteMin' (Node B k _ v Nil Nil) = S' Nil (k,v)+deleteMin' (Node B k _ v Nil r@(Node R _ _ _ _ _)) = U' (turnBlack r) (k,v)+deleteMin' (Node R k _ v Nil r) = U' r (k,v)+deleteMin' (Node c k _ v l r) =+ case deleteMin' l of+ (U' l' kv) -> U' (mNode c k v l' r) kv+ (S' l' kv) -> annotate (unbalancedR c k v l' r) kv++deleteMax' :: Ord k => IntervalMap k v -> DeleteResult' k v (Interval k, v)+deleteMax' Nil = error "deleteMax': Nil"+deleteMax' (Node B k _ v Nil Nil) = S' Nil (k,v)+deleteMax' (Node B k _ v l@(Node R _ _ _ _ _) Nil) = U' (turnBlack l) (k,v)+deleteMax' (Node R k _ v l Nil) = U' l (k,v)+deleteMax' (Node c k _ v l r) =+ case deleteMax' r of+ (U' r' kv) -> U' (mNode c k v l r') kv+ (S' r' kv) -> annotate (unbalancedL c k v l r') kv++-- The left tree lacks one Black node+unbalancedR :: Ord k => Color -> Interval k -> v -> IntervalMap k v -> IntervalMap k v -> DeleteResult k v+-- Decreasing one Black node in the right+unbalancedR B k v l r@(Node B _ _ _ _ _) = S (balanceR B k v l (turnRed r))+unbalancedR R k v l r@(Node B _ _ _ _ _) = U (balanceR B k v l (turnRed r))+-- Taking one Red node from the right and adding it to the right as Black+unbalancedR B k v l (Node R rk _ rv rl@(Node B _ _ _ _ _) rr)+ = U (mNode B rk rv (balanceR B k v l (turnRed rl)) rr)+unbalancedR _ _ _ _ _ = error "unbalancedR"++unbalancedL :: Ord k => Color -> Interval k -> v -> IntervalMap k v -> IntervalMap k v -> DeleteResult k v+unbalancedL R k v l@(Node B _ _ _ _ _) r = U (balanceL B k v (turnRed l) r)+unbalancedL B k v l@(Node B _ _ _ _ _) r = S (balanceL B k v (turnRed l) r)+unbalancedL B k v (Node R lk _ lv ll lr@(Node B _ _ _ _ _)) r+ = U (mNode B lk lv ll (balanceL B k v (turnRed lr) r))+unbalancedL _ _ _ _ _ = error "unbalancedL"++++-- | /O(log n)/. Remove the largest key from the map. Return the empty map if the map is empty.+deleteMax :: (Ord k) => IntervalMap k v -> IntervalMap k v+deleteMax Nil = Nil+deleteMax m = turnBlack (unwrap' (deleteMax' m))++-- | /O(log n)/. Delete and return the smallest key.+deleteFindMin :: (Ord k) => IntervalMap k v -> ((Interval k,v), IntervalMap k v)+deleteFindMin mp = case deleteMin' mp of+ (U' r v) -> (v, turnBlack r)+ (S' r v) -> (v, turnBlack r)++-- | /O(log n)/. Delete and return the largest key.+deleteFindMax :: (Ord k) => IntervalMap k v -> ((Interval k,v), IntervalMap k v)+deleteFindMax mp = case deleteMax' mp of+ (U' r v) -> (v, turnBlack r)+ (S' r v) -> (v, turnBlack r)++-- | /O(log n)/. Update or delete value at minimum key.+updateMin :: Ord k => (v -> Maybe v) -> IntervalMap k v -> IntervalMap k v+updateMin f m = updateMinWithKey (\_ v -> f v) m++-- | /O(log n)/. Update or delete value at maximum key.+updateMax :: Ord k => (v -> Maybe v) -> IntervalMap k v -> IntervalMap k v+updateMax f m = updateMaxWithKey (\_ v -> f v) m++-- | /O(log n)/. Update or delete value at minimum key.+updateMinWithKey :: Ord k => (Interval k -> v -> Maybe v) -> IntervalMap k v -> IntervalMap k v+updateMinWithKey _ Nil = Nil+updateMinWithKey f m = let (k,v) = findMin m in+ case f k v of+ Just v' -> setMinValue v' m+ Nothing -> deleteMin m++-- | /O(log n)/. Update or delete value at maximum key.+updateMaxWithKey :: Ord k => (Interval k -> v -> Maybe v) -> IntervalMap k v -> IntervalMap k v+updateMaxWithKey _ Nil = Nil+updateMaxWithKey f m = let (k,v) = findMax m in+ case f k v of+ Just v' -> setMaxValue v' m+ Nothing -> deleteMax m++-- | /O(log n)/. Retrieves the minimal (key,value) pair of the map, and+-- the map stripped of that element, or 'Nothing' if passed an empty map.+--+-- > minViewWithKey (fromList [(5,"a"), (3,"b")]) == Just ((3,"b"), singleton 5 "a")+-- > minViewWithKey empty == Nothing++minViewWithKey :: Ord k => IntervalMap k a -> Maybe ((Interval k, a), IntervalMap k a)+minViewWithKey Nil = Nothing+minViewWithKey x = Just (deleteFindMin x)++-- | /O(log n)/. Retrieves the maximal (key,value) pair of the map, and+-- the map stripped of that element, or 'Nothing' if passed an empty map.+maxViewWithKey :: Ord k => IntervalMap k a -> Maybe ((Interval k, a), IntervalMap k a)+maxViewWithKey Nil = Nothing+maxViewWithKey x = Just (deleteFindMax x)++-- | /O(log n)/. Retrieves the value associated with minimal key of the+-- map, and the map stripped of that element, or 'Nothing' if passed an+-- empty map.+minView :: Ord k => IntervalMap k a -> Maybe (a, IntervalMap k a)+minView Nil = Nothing+minView x = case deleteFindMin x of ((_,a), x') -> Just (a, x')++-- | /O(log n)/. Retrieves the value associated with maximal key of the+-- map, and the map stripped of that element, or 'Nothing' if passed an+-- empty map.+maxView :: Ord k => IntervalMap k a -> Maybe (a, IntervalMap k a)+maxView Nil = Nothing+maxView x = case deleteFindMax x of ((_,a), x') -> Just (a, x')+++setMinValue :: v -> IntervalMap k v -> IntervalMap k v+setMinValue _ Nil = Nil+setMinValue v' (Node c k m _ Nil r) = Node c k m v' Nil r+setMinValue v' (Node c k m v l r) = Node c k m v (setMinValue v' l) r++setMaxValue :: v -> IntervalMap k v -> IntervalMap k v+setMaxValue _ Nil = Nil+setMaxValue v' (Node c k m _ l Nil) = Node c k m v' l Nil+setMaxValue v' (Node c k m v l r) = Node c k m v l (setMaxValue v' r)++++-- folding++-- | /O(n)/. Fold the values in the map using the given right-associative+-- binary operator, such that @'foldr' f z == 'Prelude.foldr' f z . 'elems'@.+foldr :: (a -> b -> b) -> b -> IntervalMap k a -> b+foldr _ z Nil = z+foldr f z (Node _ _ _ x l r) = foldr f (f x (foldr f z r)) l++-- | /O(n)/. A strict version of 'foldr'. Each application of the operator is+-- evaluated before using the result in the next application. This+-- function is strict in the starting value.+foldr' :: (a -> b -> b) -> b -> IntervalMap k a -> b+foldr' f z m = z `seq` case m of+ Nil -> z+ Node _ _ _ x l r -> foldr' f (f x (foldr' f z r)) l++-- | /O(n)/. Fold the values in the map using the given left-associative+-- binary operator, such that @'foldl' f z == 'Prelude.foldl' f z . 'elems'@.+foldl :: (b -> a -> b) -> b -> IntervalMap k a -> b+foldl _ z Nil = z+foldl f z (Node _ _ _ x l r) = foldl f (f (foldl f z l) x) r++-- | /O(n)/. A strict version of 'foldl'. Each application of the operator is+-- evaluated before using the result in the next application. This+-- function is strict in the starting value.+foldl' :: (b -> a -> b) -> b -> IntervalMap k a -> b+foldl' f z m = z `seq` case m of+ Nil -> z+ Node _ _ _ x l r -> foldl' f (f (foldl' f z l) x) r++-- | /O(n)/. Fold the keys and values in the map using the given right-associative+-- binary operator, such that+-- @'foldrWithKey' f z == 'Prelude.foldr' ('uncurry' f) z . 'toAscList'@.+foldrWithKey :: (Interval k -> v -> a -> a) -> a -> IntervalMap k v -> a+foldrWithKey _ z Nil = z+foldrWithKey f z (Node _ k _ x l r) = foldrWithKey f (f k x (foldrWithKey f z r)) l++-- | /O(n)/. A strict version of 'foldrWithKey'. Each application of the operator is+-- evaluated before using the result in the next application. This+-- function is strict in the starting value.+foldrWithKey' :: (Interval k -> v -> a -> a) -> a -> IntervalMap k v -> a+foldrWithKey' f z m = z `seq` case m of+ Nil -> z+ Node _ k _ x l r -> foldrWithKey' f (f k x (foldrWithKey' f z r)) l++-- | /O(n)/. Fold the keys and values in the map using the given left-associative+-- binary operator, such that+-- @'foldlWithKey' f z == 'Prelude.foldl' (\\z' (kx, x) -> f z' kx x) z . 'toAscList'@.+foldlWithKey :: (a -> Interval k -> v -> a) -> a -> IntervalMap k v -> a+foldlWithKey _ z Nil = z+foldlWithKey f z (Node _ k _ x l r) = foldlWithKey f (f (foldlWithKey f z l) k x) r++-- | /O(n)/. A strict version of 'foldlWithKey'. Each application of the operator is+-- evaluated before using the result in the next application. This+-- function is strict in the starting value.+foldlWithKey' :: (a -> Interval k -> v -> a) -> a -> IntervalMap k v -> a+foldlWithKey' f z m = z `seq` case m of+ Nil -> z+ Node _ k _ x l r -> foldlWithKey' f (f (foldlWithKey' f z l) k x) r++-- delete++-- | /O(log n)/. Delete a key from the map. If the map does not contain the key,+-- it is returned unchanged.+delete :: (Ord k) => Interval k -> IntervalMap k v -> IntervalMap k v+delete key mp = turnBlack (unwrap (delete' key mp))++delete' :: Ord k => Interval k -> IntervalMap k v -> DeleteResult k v+delete' x Nil = x `seq` U Nil+delete' x (Node c k _ v l r) =+ case compare x k of+ LT -> case delete' x l of+ (U l') -> U (mNode c k v l' r)+ (S l') -> unbalancedR c k v l' r+ GT -> case delete' x r of+ (U r') -> U (mNode c k v l r')+ (S r') -> unbalancedL c k v l r'+ EQ -> case r of+ Nil -> if c == B then blackify l else U l+ _ -> case deleteMin' r of+ (U' r' (rk,rv)) -> U (mNode c rk rv l r')+ (S' r' (rk,rv)) -> unbalancedL c rk rv l r'++blackify :: IntervalMap k v -> DeleteResult k v+blackify (Node R k m v l r) = U (Node B k m v l r)+blackify s = S s++-- | /O(log n)/. Update a value at a specific key with the result of the provided function.+-- When the key is not+-- a member of the map, the original map is returned.+adjust :: Ord k => (a -> a) -> Interval k -> IntervalMap k a -> IntervalMap k a+adjust f k m = adjustWithKey (\_ v -> f v) k m++-- | /O(log n)/. Adjust a value at a specific key. When the key is not+-- a member of the map, the original map is returned.+adjustWithKey :: Ord k => (Interval k -> a -> a) -> Interval k -> IntervalMap k a -> IntervalMap k a+adjustWithKey _ _ Nil = Nil+adjustWithKey f x (Node c k m v l r) =+ case compare x k of+ LT -> Node c k m v (adjustWithKey f x l) r+ GT -> Node c k m v l (adjustWithKey f x r)+ EQ -> Node c k m (f k v) l r++-- | /O(log n)/. The expression (@'update' f k map@) updates the value @x@+-- at @k@ (if it is in the map). If (@f x@) is 'Nothing', the element is+-- deleted. If it is (@'Just' y@), the key @k@ is bound to the new value @y@.+update :: Ord k => (a -> Maybe a) -> Interval k -> IntervalMap k a -> IntervalMap k a+update f k m = updateWithKey (\_ v -> f v) k m++-- | /O(log n)/. The expression (@'updateWithKey' f k map@) updates the+-- value @x@ at @k@ (if it is in the map). If (@f k x@) is 'Nothing',+-- the element is deleted. If it is (@'Just' y@), the key @k@ is bound+-- to the new value @y@.+updateWithKey :: Ord k => (Interval k -> a -> Maybe a) -> Interval k -> IntervalMap k a -> IntervalMap k a+updateWithKey f k m = snd (updateLookupWithKey f k m)++-- | /O(log n)/. Lookup and update. See also 'updateWithKey'.+-- The function returns changed value, if it is updated.+-- Returns the original key value if the map entry is deleted.+updateLookupWithKey :: Ord k => (Interval k -> a -> Maybe a) -> Interval k -> IntervalMap k a -> (Maybe a, IntervalMap k a)+updateLookupWithKey f x m = case lookup x m of+ Nothing -> (Nothing, m)+ r@(Just v) -> case f x v of+ Nothing -> (r, delete x m)+ r'@(Just v') -> (r', adjust (const v') x m)++-- | /O(log n)/. The expression (@'alter' f k map@) alters the value @x@ at @k@, or absence thereof.+-- 'alter' can be used to insert, delete, or update a value in a 'Map'.+-- In short : @'lookup' k ('alter' f k m) = f ('lookup' k m)@.+alter :: Ord k => (Maybe a -> Maybe a) -> Interval k -> IntervalMap k a -> IntervalMap k a+alter f x m = case lookup x m of+ Nothing -> case f Nothing of+ Nothing -> m+ Just v -> insert x v m+ y -> case f y of+ Nothing -> delete x m+ Just v' -> adjust (const v') x m+++-- | /O(n+m)/. The expression (@'union' t1 t2@) takes the left-biased union of @t1@ and @t2@. +-- It prefers @t1@ when duplicate keys are encountered,+-- i.e. (@'union' == 'unionWith' 'const'@).+union :: Ord k => IntervalMap k a -> IntervalMap k a -> IntervalMap k a+union m1 m2 = unionWithKey (\_ v _ -> v) m1 m2++-- | /O(n+m)/. Union with a combining function.+unionWith :: Ord k => (a -> a -> a) -> IntervalMap k a -> IntervalMap k a -> IntervalMap k a+unionWith f m1 m2 = unionWithKey (\_ v1 v2 -> f v1 v2) m1 m2++-- | /O(n+m)/. Union with a combining function.+unionWithKey :: Ord k => (Interval k -> a -> a -> a) -> IntervalMap k a -> IntervalMap k a -> IntervalMap k a+unionWithKey f m1 m2 = fromDistinctAscList (ascListUnion f (toAscList m1) (toAscList m2))++-- | The union of a list of maps:+-- (@'unions' == 'Prelude.foldl' 'union' 'empty'@).+unions :: Ord k => [IntervalMap k a] -> IntervalMap k a+unions = L.foldl union empty++-- | The union of a list of maps, with a combining operation:+-- (@'unionsWith' f == 'Prelude.foldl' ('unionWith' f) 'empty'@).+unionsWith :: Ord k => (a -> a -> a) -> [IntervalMap k a] -> IntervalMap k a+unionsWith f = L.foldl (unionWith f) empty++-- | /O(n+m)/. Difference of two maps. +-- Return elements of the first map not existing in the second map.+difference :: Ord k => IntervalMap k a -> IntervalMap k b -> IntervalMap k a+difference m1 m2 = differenceWithKey (\_ _ _ -> Nothing) m1 m2++-- | /O(n+m)/. Difference with a combining function. +-- When two equal keys are+-- encountered, the combining function is applied to the values of these keys.+-- If it returns 'Nothing', the element is discarded (proper set difference). If+-- it returns (@'Just' y@), the element is updated with a new value @y@. +differenceWith :: Ord k => (a -> b -> Maybe a) -> IntervalMap k a -> IntervalMap k b -> IntervalMap k a+differenceWith f m1 m2 = differenceWithKey (\_ v1 v2 -> f v1 v2) m1 m2++-- | /O(n+m)/. Difference with a combining function. When two equal keys are+-- encountered, the combining function is applied to the key and both values.+-- If it returns 'Nothing', the element is discarded (proper set difference). If+-- it returns (@'Just' y@), the element is updated with a new value @y@. +differenceWithKey :: Ord k => (Interval k -> a -> b -> Maybe a) -> IntervalMap k a -> IntervalMap k b -> IntervalMap k a+differenceWithKey f m1 m2 = fromDistinctAscList (ascListDifference f (toAscList m1) (toAscList m2))++-- | /O(n+m)/. Intersection of two maps.+-- Return data in the first map for the keys existing in both maps.+-- (@'intersection' m1 m2 == 'intersectionWith' 'const' m1 m2@).+intersection :: Ord k => IntervalMap k a -> IntervalMap k b -> IntervalMap k a+intersection m1 m2 = intersectionWithKey (\_ v _ -> v) m1 m2++-- | /O(n+m)/. Intersection with a combining function.+intersectionWith :: Ord k => (a -> b -> c) -> IntervalMap k a -> IntervalMap k b -> IntervalMap k c+intersectionWith f m1 m2 = intersectionWithKey (\_ v1 v2 -> f v1 v2) m1 m2++-- | /O(n+m)/. Intersection with a combining function.+intersectionWithKey :: Ord k => (Interval k -> a -> b -> c) -> IntervalMap k a -> IntervalMap k b -> IntervalMap k c+intersectionWithKey f m1 m2 = fromDistinctAscList (ascListIntersection f (toAscList m1) (toAscList m2))++ascListUnion :: Ord k => (k -> a -> a -> a) -> [(k,a)] -> [(k,a)] -> [(k,a)]+ascListUnion _ [] [] = []+ascListUnion _ [] ys = ys+ascListUnion _ xs [] = xs+ascListUnion f xs@(x@(xk,xv):xs') ys@(y@(yk,yv):ys') =+ case compare xk yk of+ LT -> x : ascListUnion f xs' ys+ GT -> y : ascListUnion f xs ys'+ EQ -> (xk, f xk xv yv) : ascListUnion f xs' ys'++ascListDifference :: Ord k => (k -> a -> b -> Maybe a) -> [(k,a)] -> [(k,b)] -> [(k,a)]+ascListDifference _ [] _ = []+ascListDifference _ xs [] = xs+ascListDifference f xs@(x@(xk,xv):xs') ys@((yk,yv):ys') =+ case compare xk yk of+ LT -> x : ascListDifference f xs' ys+ GT -> ascListDifference f xs ys'+ EQ -> case f xk xv yv of+ Nothing -> ascListDifference f xs' ys'+ Just v' -> (xk,v') : ascListDifference f xs' ys'++ascListIntersection :: Ord k => (k -> a -> b -> c) -> [(k,a)] -> [(k,b)] -> [(k,c)]+ascListIntersection _ [] _ = []+ascListIntersection _ _ [] = []+ascListIntersection f xs@((xk,xv):xs') ys@((yk,yv):ys') =+ case compare xk yk of+ LT -> ascListIntersection f xs' ys+ GT -> ascListIntersection f xs ys'+ EQ -> (xk, f xk xv yv) : ascListIntersection f xs' ys'+++-- --- Conversion ---++-- | /O(n)/. The list of all key\/value pairs contained in the map, in ascending order of keys.+toAscList :: IntervalMap k v -> [(Interval k,v)]+toAscList m = foldrWithKey (\k v r -> (k,v) : r) [] m++-- | /O(n)/. The list of all key\/value pairs contained in the map, in no particular order.+toList :: IntervalMap k v -> [(Interval k,v)]+toList m = toAscList m++-- | /O(n)/. The list of all key\/value pairs contained in the map, in descending order of keys.+toDescList :: IntervalMap k v -> [(Interval k, v)]+toDescList m = foldlWithKey (\r k v -> (k,v) : r) [] m++-- | /O(n log n)/. Build a map from a list of key\/value pairs. See also 'fromAscList'.+-- If the list contains more than one value for the same key, the last value+-- for the key is retained.+fromList :: Ord k => [(Interval k,v)] -> IntervalMap k v+fromList xs = L.foldl' (\m (k,v) -> insert k v m) empty xs++-- | /O(n log n)/. Build a map from a list of key\/value pairs with a combining function. See also 'fromAscListWith'.+fromListWith :: Ord k => (a -> a -> a) -> [(Interval k,a)] -> IntervalMap k a +fromListWith f xs = fromListWithKey (\_ x y -> f x y) xs++-- | /O(n log n)/. Build a map from a list of key\/value pairs with a combining function. See also 'fromAscListWith'.+fromListWithKey :: Ord k => (Interval k -> a -> a -> a) -> [(Interval k,a)] -> IntervalMap k a +fromListWithKey f xs = L.foldl' ins empty xs+ where+ ins t (k,x) = insertWithKey f k x t++-- | /O(n)/. Build a map from an ascending list in linear time.+-- /The precondition (input list is ascending) is not checked./+fromAscList :: Ord k => [(Interval k,v)] -> IntervalMap k v+fromAscList xs = fromAscListWith (\_ b -> b) xs++-- | /O(n)/. Build a map from an ascending list in linear time with a combining function for equal keys.+-- /The precondition (input list is ascending) is not checked./+fromAscListWith :: Ord k => (a -> a -> a) -> [(Interval k,a)] -> IntervalMap k a +fromAscListWith f xs = fromAscListWithKey (\_ a b -> f a b) xs++-- | /O(n)/. Build a map from an ascending list in linear time with a combining function for equal keys.+-- /The precondition (input list is ascending) is not checked./+fromAscListWithKey :: Ord k => (Interval k -> a -> a -> a) -> [(Interval k,a)] -> IntervalMap k a +fromAscListWithKey f xs = fromDistinctAscList (combineEq f xs)++combineEq :: Eq k => (k -> a -> a -> a) -> [(k,a)] -> [(k,a)]+combineEq _ [] = []+combineEq _ xs@[_] = xs+combineEq f (x@(xk,xv) : xs@((yk,yv) : xs'))+ | xk == yk = combineEq f ((xk, f xk xv yv) : xs')+ | otherwise = x : combineEq f xs+++-- Strict tuple+data T2 a b = T2 !a !b+++-- | /O(n)/. Build a map from an ascending list of elements with distinct keys in linear time.+-- /The precondition is not checked./+fromDistinctAscList :: (Ord k) => [(Interval k,v)] -> IntervalMap k v+-- exactly 2^n-1 items have height n. They can be all black+-- from 2^n - 2^n-2 items have height n+1. The lowest "row" should be red.+fromDistinctAscList lyst = case h (length lyst) lyst of+ (T2 result []) -> result+ _ -> error "fromDistinctAscList: list not fully consumed"+ where+ h n xs | n == 0 = T2 Nil xs+ | isPerfect n = buildB n xs+ | otherwise = buildR n (log2 n) xs++ buildB n xs | xs `seq` n <= 0 = error "fromDictinctAscList: buildB 0"+ | n == 1 = case xs of ((k,v):xs') -> T2 (Node B k k v Nil Nil) xs'+ | otherwise =+ case n `quot` 2 of { n' ->+ case buildB n' xs of { (T2 l ((k,v):xs')) ->+ case buildB n' xs' of { (T2 r xs'') ->+ T2 (mNode B k v l r) xs'' }}}++ buildR n d xs | d `seq` xs `seq` n == 0 = T2 Nil xs+ | n == 1 = case xs of ((k,v):xs') -> T2 (Node (if d==0 then R else B) k k v Nil Nil) xs'+ | otherwise =+ case n `quot` 2 of { n' ->+ case buildR n' (d-1) xs of { (T2 l ((k,v):xs')) ->+ case buildR (n - (n' + 1)) (d-1) xs' of { (T2 r xs'') ->+ T2 (mNode B k v l r) xs'' }}}+++-- is n a perfect binary tree size (2^m-1)?+isPerfect :: Int -> Bool+isPerfect n = (n .&. (n + 1)) == 0++log2 :: Int -> Int+log2 m = h (-1) m+ where+ h r n | r `seq` n <= 0 = r+ | otherwise = h (r + 1) (n `shiftR` 1)+++-- | /O(n)/. List of all values in the map, in ascending order of their keys.+elems :: IntervalMap k v -> [v]+elems m = [v | (_,v) <- toAscList m]++-- | /O(n)/. List of all keys in the map, in ascending order.+keys :: IntervalMap k v -> [Interval k]+keys m = [k | (k,_) <- toAscList m]++-- | /O(n)/. Set of the keys.+keysSet :: (Ord k) => IntervalMap k v -> Set.Set (Interval k)+keysSet m = Set.fromDistinctAscList (keys m)++-- | Same as 'toAscList'.+assocs :: IntervalMap k v -> [(Interval k, v)]+assocs m = toAscList m++-- --- Mapping ---++-- | /O(n)/. Map a function over all values in the map.+map :: (a -> b) -> IntervalMap k a -> IntervalMap k b+map f = mapWithKey (\_ x -> f x)++-- | /O(n)/. Map a function over all values in the map.+mapWithKey :: (Interval k -> a -> b) -> IntervalMap k a -> IntervalMap k b+mapWithKey f = go+ where+ go Nil = Nil+ go (Node c k m v l r) = Node c k m (f k v) (go l) (go r)++-- | /O(n)/. The function 'mapAccum' threads an accumulating+-- argument through the map in ascending order of keys.+--+-- > let f a b = (a ++ b, b ++ "X")+-- > mapAccum f "Everything: " (fromList [(5,"a"), (3,"b")]) == ("Everything: ba", fromList [(3, "bX"), (5, "aX")])+mapAccum :: (a -> b -> (a,c)) -> a -> IntervalMap k b -> (a, IntervalMap k c)+mapAccum f a m = mapAccumWithKey (\a' _ x' -> f a' x') a m++-- | /O(n)/. The function 'mapAccumWithKey' threads an accumulating+-- argument through the map in ascending order of keys.+--+-- > let f a k b = (a ++ " " ++ (show k) ++ "-" ++ b, b ++ "X")+-- > mapAccumWithKey f "Everything:" (fromList [(5,"a"), (3,"b")]) == ("Everything: 3-b 5-a", fromList [(3, "bX"), (5, "aX")])+mapAccumWithKey :: (a -> Interval k -> b -> (a,c)) -> a -> IntervalMap k b -> (a, IntervalMap k c)+mapAccumWithKey f = go+ where+ go a Nil = (a,Nil)+ go a (Node c kx m x l r) =+ let (a1,l') = go a l+ (a2,x') = f a1 kx x+ (a3,r') = go a2 r+ in (a3, Node c kx m x' l' r')++-- | /O(n)/. The function 'mapAccumRWithKey' threads an accumulating+-- argument through the map in descending order of keys.+mapAccumRWithKey :: (a -> Interval k -> b -> (a,c)) -> a -> IntervalMap k b -> (a, IntervalMap k c)+mapAccumRWithKey f = go+ where+ go a Nil = (a, Nil)+ go a (Node c kx m x l r) =+ let (a1,r') = go a r+ (a2,x') = f a1 kx x+ (a3,l') = go a2 l+ in (a3, Node c kx m x' l' r')+++-- | /O(n log n)/. @'mapKeys' f s@ is the map obtained by applying @f@ to each key of @s@.+-- +-- The size of the result may be smaller if @f@ maps two or more distinct+-- keys to the same new key. In this case the value at the smallest of+-- these keys is retained.+mapKeys :: Ord k2 => (Interval k1 -> Interval k2) -> IntervalMap k1 a -> IntervalMap k2 a+mapKeys f m = fromList [ (f k, v) | (k, v) <- toDescList m ]++-- | /O(n log n)/. @'mapKeysWith' c f s@ is the map obtained by applying @f@ to each key of @s@.+-- +-- The size of the result may be smaller if @f@ maps two or more distinct+-- keys to the same new key. In this case the associated values will be+-- combined using @c@.+mapKeysWith :: Ord k2 => (a -> a -> a) -> (Interval k1 -> Interval k2) -> IntervalMap k1 a -> IntervalMap k2 a+mapKeysWith c f m = fromListWith c [ (f k, v) | (k, v) <- toAscList m ]++-- | /O(n log n)/. @'mapKeysMonotonic' f s == 'mapKeys' f s@, but works only when @f@+-- is strictly monotonic.+-- That is, for any values @x@ and @y@, if @x@ < @y@ then @f x@ < @f y@.+-- /The precondition is not checked./+mapKeysMonotonic :: Ord k2 => (Interval k1 -> Interval k2) -> IntervalMap k1 a -> IntervalMap k2 a+mapKeysMonotonic _ Nil = Nil+mapKeysMonotonic f (Node c k _ x l r) =+ mNode c (f k) x (mapKeysMonotonic f l) (mapKeysMonotonic f r)++-- | /O(n)/. Filter values satisfying a predicate.+filter :: Ord k => (a -> Bool) -> IntervalMap k a -> IntervalMap k a+filter p m = filterWithKey (\_ v -> p v) m++-- | /O(n)/. Filter keys\/values satisfying a predicate.+filterWithKey :: Ord k => (Interval k -> a -> Bool) -> IntervalMap k a -> IntervalMap k a+filterWithKey p m = mapMaybeWithKey (\k v -> if p k v then Just v else Nothing) m++-- | /O(n)/. Partition the map according to a predicate. The first+-- map contains all elements that satisfy the predicate, the second all+-- elements that fail the predicate. See also 'split'.+partition :: Ord k => (a -> Bool) -> IntervalMap k a -> (IntervalMap k a, IntervalMap k a)+partition p m = partitionWithKey (\_ v -> p v) m++-- | /O(n)/. Partition the map according to a predicate. The first+-- map contains all elements that satisfy the predicate, the second all+-- elements that fail the predicate. See also 'split'.+partitionWithKey :: Ord k => (Interval k -> a -> Bool) -> IntervalMap k a -> (IntervalMap k a, IntervalMap k a)+partitionWithKey p m = mapEitherWithKey p' m+ where+ p' k v | p k v = Left v+ | otherwise = Right v++-- | /O(n)/. Map values and collect the 'Just' results.+mapMaybe :: Ord k => (a -> Maybe b) -> IntervalMap k a -> IntervalMap k b+mapMaybe f m = mapMaybeWithKey (\_ v -> f v) m++-- | /O(n)/. Map keys\/values and collect the 'Just' results.+mapMaybeWithKey :: Ord k => (Interval k -> a -> Maybe b) -> IntervalMap k a -> IntervalMap k b+mapMaybeWithKey f m = fromDistinctAscList (mapf [] m)+ where+ mapf z Nil = z+ mapf z (Node _ k _ v l r) = mapf (f' k v z r) l+ f' k v z r = case f k v of+ Nothing -> mapf z r+ Just v' -> (k,v') : mapf z r++-- | /O(n)/. Map values and separate the 'Left' and 'Right' results.+mapEither :: Ord k => (a -> Either b c) -> IntervalMap k a -> (IntervalMap k b, IntervalMap k c)+mapEither f m = mapEitherWithKey (\_ v -> f v) m++-- | /O(n)/. Map keys\/values and separate the 'Left' and 'Right' results.+mapEitherWithKey :: Ord k => (Interval k -> a -> Either b c) -> IntervalMap k a -> (IntervalMap k b, IntervalMap k c)+mapEitherWithKey f m = (fromDistinctAscList l, fromDistinctAscList r)+ where+ (l, r) = part [] [] (toDescList m)+ part ls rs [] = (ls, rs)+ part ls rs ((k,v):xs) = case f k v of+ Left v' -> part ((k,v'):ls) rs xs+ Right v' -> part ls ((k,v'):rs) xs++-- | /O(n)/. The expression (@'split' k map@) is a pair @(map1,map2)@ where+-- the keys in @map1@ are smaller than @k@ and the keys in @map2@ larger than @k@.+-- Any key equal to @k@ is found in neither @map1@ nor @map2@.+split :: Ord k => Interval k -> IntervalMap k a -> (IntervalMap k a, IntervalMap k a)+split x m = (l, r)+ where (l, _, r) = splitLookup x m+ +-- | /O(n)/. The expression (@'splitLookup' k map@) splits a map just+-- like 'split' but also returns @'lookup' k map@. +splitLookup :: Ord k => Interval k -> IntervalMap k a -> (IntervalMap k a, Maybe a, IntervalMap k a)+splitLookup x m = (fromDistinctAscList less, lookup x m, fromDistinctAscList greater)+ where+ less = [e | e@(k,_) <- toAscList m, k < x]+ greater = [e | e@(k,_) <- toAscList m, k > x]++-- submaps++-- | /O(n+m)/. This function is defined as (@'isSubmapOf' = 'isSubmapOfBy' (==)@).+isSubmapOf :: (Ord k, Eq a) => IntervalMap k a -> IntervalMap k a -> Bool+isSubmapOf m1 m2 = isSubmapOfBy (==) m1 m2++{- | /O(n+m)/.+ The expression (@'isSubmapOfBy' f t1 t2@) returns 'True' if+ all keys in @t1@ are in tree @t2@, and @f@ returns 'True' when+ applied to their respective values.+-}+isSubmapOfBy :: Ord k => (a -> b -> Bool) -> IntervalMap k a -> IntervalMap k b -> Bool+isSubmapOfBy f m1 m2 = go (toAscList m1) (toAscList m2)+ where+ go [] _ = True+ go (_:_) [] = False+ go s1@((k1,v1):r1) ((k2,v2):r2) =+ case compare k1 k2 of+ GT -> go s1 r2+ EQ -> f v1 v2 && go r1 r2+ LT -> False++-- | /O(n+m)/. Is this a proper submap? (ie. a submap but not equal). +-- Defined as (@'isProperSubmapOf' = 'isProperSubmapOfBy' (==)@).+isProperSubmapOf :: (Ord k, Eq a) => IntervalMap k a -> IntervalMap k a -> Bool+isProperSubmapOf m1 m2 = isProperSubmapOfBy (==) m1 m2++{- | /O(n+m)/. Is this a proper submap? (ie. a submap but not equal).+ The expression (@'isProperSubmapOfBy' f m1 m2@) returns 'True' when+ @m1@ and @m2@ are not equal,+ all keys in @m1@ are in @m2@, and when @f@ returns 'True' when+ applied to their respective values.+-}+isProperSubmapOfBy :: Ord k => (a -> b -> Bool) -> IntervalMap k a -> IntervalMap k b -> Bool+isProperSubmapOfBy f t1 t2 = size t1 < size t2 && isSubmapOfBy f t1 t2+++-- debugging++-- | Check red-black-tree and interval search augmentation invariants.+-- For testing/debugging only.+valid :: Ord k => IntervalMap k v -> Bool+valid mp = test mp && height mp <= maxHeight (size mp) && validColor mp+ where+ test Nil = True+ test n@(Node _ _ _ _ l r) = validOrder n && validMax n && test l && test r+ validMax (Node _ k m _ lo hi) = m == maxUpper k lo hi+ validMax Nil = True++ validOrder (Node _ _ _ _ Nil Nil) = True+ validOrder (Node _ k1 _ _ Nil (Node _ k2 _ _ _ _)) = k1 < k2+ validOrder (Node _ k2 _ _ (Node _ k1 _ _ _ _) Nil) = k1 < k2+ validOrder (Node _ k2 _ _ (Node _ k1 _ _ _ _) (Node _ k3 _ _ _ _)) = k1 < k2 && k2 < k3+ validOrder Nil = True++ -- validColor parentColor blackCount tree+ validColor n = blackDepth n >= 0++ -- return -1 if subtrees have diffrent black depths or two consecutive red nodes are encountered+ blackDepth :: IntervalMap k v -> Int+ blackDepth Nil = 0+ blackDepth (Node c _ _ _ l r) = case blackDepth l of+ ld -> if ld < 0 then ld+ else+ case blackDepth r of+ rd -> if rd < 0 then rd+ else if rd /= ld then -1+ else if c == R && (isRed l || isRed r) then -1+ else if c == B then rd + 1+ else rd+
Data/IntervalMap/Interval.hs view
@@ -2,7 +2,7 @@ -- Module : Data.IntervalMap.Interval -- Copyright : (c) Christoph Breitkopf 2011 -- License : BSD-style--- Maintainer : chris@chr-breitkopf.de+-- Maintainer : chbreitkopf@gmail.com -- Stability : experimental -- Portability : portable --
+ Data/IntervalMap/Lazy.hs view
@@ -0,0 +1,155 @@+{- |+Module : Data.IntervalMap.Lazy+Copyright : (c) Christoph Breitkopf 2011+License : BSD-style+Maintainer : chbreitkopf@gmail.com+Stability : experimental+Portability : portable++An implementation of maps from intervals to values. The key intervals may+overlap, and the implementation contains efficient search functions+for all keys containing a point or overlapping an interval.+Closed, open, and half-open intervals can be contained in the same map.++This module implements the same functions as "Data.IntervalMap.Strict",+but with value-lazy semantics.+-}+module Data.IntervalMap.Lazy (+ -- * re-export+ Interval(..)+ -- * Map type+ , IntervalMap -- instance Eq,Show,Read++ -- * Operators+ , (!), (\\)++ -- * Query+ , M.null+ , size+ , member+ , notMember+ , M.lookup+ , findWithDefault++ -- ** Interval query+ , containing+ , intersecting+ , within+ + -- * Construction+ , empty+ , singleton++ -- ** Insertion+ , insert+ , insertWith+ , insertWithKey+ , insertLookupWithKey+ + -- ** Delete\/Update+ , delete+ , adjust+ , adjustWithKey+ , update+ , updateWithKey+ , updateLookupWithKey+ , alter++ -- * Combine++ -- ** Union+ , union+ , unionWith+ , unionWithKey+ , unions+ , unionsWith++ -- ** Difference+ , difference+ , differenceWith+ , differenceWithKey+ + -- ** Intersection+ , intersection+ , intersectionWith+ , intersectionWithKey++ -- * Traversal+ -- ** Map+ , M.map+ , mapWithKey+ , mapAccum+ , mapAccumWithKey+ , mapAccumRWithKey+ , mapKeys+ , mapKeysWith+ , mapKeysMonotonic++ -- ** Fold+ , M.foldr, M.foldl+ , foldrWithKey, foldlWithKey++ -- * Conversion+ , elems+ , keys+ , keysSet+ , assocs++ -- ** Lists+ , toList+ , fromList+ , fromListWith+ , fromListWithKey++ -- ** Ordered lists+ , toAscList+ , toDescList+ , fromAscList+ , fromAscListWith+ , fromAscListWithKey+ , fromDistinctAscList++ -- * Filter+ , M.filter+ , filterWithKey+ , partition+ , partitionWithKey++ , mapMaybe+ , mapMaybeWithKey+ , mapEither+ , mapEitherWithKey++ , split+ , splitLookup++ -- * Submap+ , isSubmapOf, isSubmapOfBy+ , isProperSubmapOf, isProperSubmapOfBy++ -- * Min\/Max+ , findMin+ , findMax+ , findLast+ , deleteMin+ , deleteMax+ , deleteFindMin+ , deleteFindMax+ , updateMin+ , updateMax+ , updateMinWithKey+ , updateMaxWithKey+ , minView+ , maxView+ , minViewWithKey+ , maxViewWithKey++ -- * Debugging+ , valid++ -- * Testing+ , height, maxHeight, showStats++ ) where++import Data.IntervalMap.Base as M
+ Data/IntervalMap/Strict.hs view
@@ -0,0 +1,252 @@+{- |+Module : Data.IntervalMap.Strict+Copyright : (c) Christoph Breitkopf 2011+License : BSD-style+Maintainer : chbreitkopf@gmail.com+Stability : experimental+Portability : portable++An implementation of maps from intervals to values. The key intervals+may overlap, and the implementation contains efficient search+functions for all keys containing a point or overlapping an+interval. Closed, open, and half-open intervals can be contained in+the same map.++The functions in this module are strict in both the keys and the+values. If you need value-lazy maps, use "Data.IntervalMap.Lazy"+instead. The IntervalMap type itself is shared between the lazy and+strict modules, meaning that the same IntervalMap value can be passed+to functions in both modules (although that is rarely needed).++An IntervalMap cannot contain duplicate keys - if you need to map a+key to multiple values, use a collection as the value type, for+example: @IntervalMap /k/ [/v/]@.++It is an error to insert an empty interval into a map. This+precondition is not checked by the various construction functions.++Since many function names (but not the type name) clash with /Prelude/+names, this module is usually imported @qualified@, e.g.++> import Data.IntervalMap (IvMap)+> import qualified Data.IntervalMap as IvMap++It offers most of the same functions as 'Data.Map', but uses+'Interval' /k/ instead of just /k/ as the key type. Some of the+functions need stricter type constraints to maintain the additional+information for efficient interval searching, for example+'fromDistinctAscList' needs an 'Ord' /k/ constraint. Also, some+functions differ in asymptotic performance (for example 'size') or+have not been tuned for efficiency as much as their equivalents in+'Data.Map' (in particular the various set functions).++In addition, there are functions specific to maps of intervals, for+example to search for all keys containing a given point or contained+in a given interval.++To stay compatible with standard Haskell, this implementation uses a+fixed data type for intervals, and not a multi-parameter type+class. Thus, it's currently not possible to define e.g. a 2-tuple as+an instance of interval and use that map key. Instead, you must+convert your keys to 'Interval'.++The implementation is a red-black tree augmented with the maximum+upper bound of all keys.++Parts of this implementation are based on code from the 'Data.Map'+implementation, (c) Daan Leijen 2002, (c) Andriy Palamarchuk 2008. The+red-black tree deletion is based on code from llrbtree by Kazu+Yamamoto. Of course, any errors are mine.+-}+module Data.IntervalMap.Strict (+ -- * re-export+ Interval(..)+ -- * Map type+ , IntervalMap -- instance Eq,Show,Read++ -- * Operators+ , (!), (\\)++ -- * Query+ , null+ , size+ , member+ , notMember+ , lookup+ , findWithDefault++ -- ** Interval query+ , containing+ , intersecting+ , within+ + -- * Construction+ , empty+ , singleton++ -- ** Insertion+ , insert+ , insertWith+ , insertWithKey+ , insertLookupWithKey+ + -- ** Delete\/Update+ , delete+ , adjust+ , adjustWithKey+ , update+ , updateWithKey+ , updateLookupWithKey+ , alter++ -- * Combine++ -- ** Union+ , union+ , unionWith+ , unionWithKey+ , unions+ , unionsWith++ -- ** Difference+ , difference+ , differenceWith+ , differenceWithKey+ + -- ** Intersection+ , intersection+ , intersectionWith+ , intersectionWithKey++ -- * Traversal+ -- ** Map+ , map+ , mapWithKey+ , mapAccum+ , mapAccumWithKey+ , mapAccumRWithKey+ , mapKeys+ , mapKeysWith+ , mapKeysMonotonic++ -- ** Fold+ , foldr, foldl+ , foldrWithKey, foldlWithKey++ -- * Conversion+ , elems+ , keys+ , keysSet+ , assocs++ -- ** Lists+ , toList+ , fromList+ , fromListWith+ , fromListWithKey++ -- ** Ordered lists+ , toAscList+ , toDescList+ , fromAscList+ , fromAscListWith+ , fromAscListWithKey+ , fromDistinctAscList++ -- * Filter+ , filter+ , filterWithKey+ , partition+ , partitionWithKey++ , mapMaybe+ , mapMaybeWithKey+ , mapEither+ , mapEitherWithKey++ , split+ , splitLookup++ -- * Submap+ , isSubmapOf, isSubmapOfBy+ , isProperSubmapOf, isProperSubmapOfBy++ -- * Min\/Max+ , findMin+ , findMax+ , findLast+ , deleteMin+ , deleteMax+ , deleteFindMin+ , deleteFindMax+ , updateMin+ , updateMax+ , updateMinWithKey+ , updateMaxWithKey+ , minView+ , maxView+ , minViewWithKey+ , maxViewWithKey++ -- * Debugging+ , valid++ -- * Testing+ , height, maxHeight, showStats++ ) where++import Prelude hiding (null, lookup, map, filter, foldr, foldl)+import Data.IntervalMap.Base as M hiding (+ singleton+ , insert+ , insertWith+ , insertWithKey+ , findWithDefault+ )++-- | /O(1)/. A map with one entry.+singleton :: Interval k -> v -> IntervalMap k v+singleton k v = v `seq` Node B k k v Nil Nil+++-- | /O(log n)/. The expression @('findWithDefault' def k map)@ returns+-- the value at key @k@ or returns default value @def@+-- when the key is not in the map.+--+-- > findWithDefault 'x' 1 (fromList [(5,'a'), (3,'b')]) == 'x'+-- > findWithDefault 'x' 5 (fromList [(5,'a'), (3,'b')]) == 'a'+findWithDefault :: Ord k => a -> Interval k -> IntervalMap k a -> a+findWithDefault def k m = def `seq` case M.lookup k m of+ Nothing -> def+ Just x -> x++-- | /O(log n)/. Insert a new key/value pair. If the map already contains the key, its value is+-- changed to the new value.+insert :: (Ord k) => Interval k -> v -> IntervalMap k v -> IntervalMap k v+insert = insertWithKey (\_ v _ -> v)++-- | /O(log n)/. Insert with a function, combining new value and old value.+-- @'insertWith' f key value mp@ +-- will insert the pair (key, value) into @mp@ if key does+-- not exist in the map. If the key does exist, the function will+-- insert the pair @(key, f new_value old_value)@.+insertWith :: (Ord k) => (v -> v -> v) -> Interval k -> v -> IntervalMap k v -> IntervalMap k v+insertWith f = insertWithKey (\_ new old -> f new old)++-- | /O(log n)/. Insert with a function, combining key, new value and old value.+-- @'insertWithKey' f key value mp@ +-- will insert the pair (key, value) into @mp@ if key does+-- not exist in the map. If the key does exist, the function will+-- insert the pair @(key, f key new_value old_value)@.+-- Note that the key passed to f is the same key passed to 'insertWithKey'.+insertWithKey :: (Ord k) => (Interval k -> v -> v -> v) -> Interval k -> v -> IntervalMap k v -> IntervalMap k v+insertWithKey f key value mp = key `seq` turnBlack (ins mp)+ where+ singletonR k v = Node R k k v Nil Nil+ ins Nil = value `seq` singletonR key value+ ins (Node color k m v l r) =+ case compare key k of+ LT -> balanceL color k v (ins l) r+ GT -> balanceR color k v l (ins r)+ EQ -> let v' = f k value v in v' `seq` Node color k m v' l r
IntervalMap.cabal view
@@ -1,18 +1,18 @@ Name: IntervalMap-Version: 0.2.3.3+Version: 0.3.0.0 Stability: experimental Synopsis: Maps from Intervals to values, with efficient search. Homepage: http://www.chr-breitkopf.de/comp/IntervalMap License: BSD3 License-file: LICENSE Author: Christoph Breitkopf-Maintainer: Christoph Breitkopf <chbreitkopf@googlemail.com>-bug-reports: mailto:chbreitkopf@googlemail.com+Maintainer: Christoph Breitkopf <chbreitkopf@gmail.com>+bug-reports: mailto:chbreitkopf@gmail.com Copyright: Copyright 2011 Christoph Breitkopf Category: Data Build-type: Simple Cabal-version: >= 1.8-Tested-With: GHC==7.4.1, GHC==7.0.4, GHC==6.12.1+Tested-With: GHC==7.4.2, GHC==7.0.4, GHC==6.12.1 Description: A map from intervals to values, with efficient search for all keys containing a point or overlapping an interval.@@ -24,7 +24,9 @@ examples/*.lhs Library- Exposed-modules: Data.IntervalMap, Data.IntervalMap.Interval+ Exposed-modules: Data.IntervalMap, Data.IntervalMap.Lazy,+ Data.IntervalMap.Strict, Data.IntervalMap.Interval+ other-modules: Data.IntervalMap.Base Build-depends: base >= 4 && < 5, containers, deepseq ghc-options: -Wall if impl(ghc >= 6.8)
README view
@@ -13,6 +13,6 @@ $ cabal test ---Christoph Breitkopf <chbreitkopf@googlemail.com>+Christoph Breitkopf <chbreitkopf@gmail.com> Last edit: 2011-12-09
bench/BenchAll.hs view
@@ -89,7 +89,13 @@ bench "Data.Map Large/Small" $ nf (\m -> D.union m dMapSmall) dMap, bench "Data.Map Small/Large" $ nf (\m -> D.union dMapSmall m) dMap, bench "IntervalMap Large/Small" $ nf (\m -> M.union m dIvMapSmall) dIvMap,- bench "IntervalMap Small/Large" $ nf (\m -> M.union dIvMapSmall m) dIvMap+ bench "IntervalMap Small/Large" $ nf (\m -> M.union dIvMapSmall m) dIvMap,+ bench "Data.Map Large/Empty" $ nf (\m -> D.union m D.empty) dMap,+ bench "Data.Map Empty/Large" $ nf (\m -> D.union D.empty m) dMap,+ bench "IntervalMap Large/Empty" $ nf (\m -> M.union m M.empty) dIvMap,+ bench "IntervalMap Empty/Large" $ nf (\m -> M.union M.empty m) dIvMap,+ bench "Data.Map self" $ nf (\m -> D.union m m) dMap,+ bench "IntervalMap self" $ nf (\m -> M.union m m) dIvMap ], bgroup "intersection" [ bench "Data.Map Large/Small" $ nf (\m -> D.intersection m dMapSmall) dMap,