module IdeSession.Strict.IntervalMap (
StrictIntervalMap
, dominators
, fromList
, toList
, empty
, insert
, Interval(..)
) where
import Data.IntervalMap.FingerTree (Interval(..), IntervalMap)
import qualified Data.IntervalMap.FingerTree as IntervalMap
import Text.Show.Pretty
data StrictIntervalMap v a = StrictIntervalMap {
toLazyIntervalMap :: !(IntervalMap v a)
, maxInterval :: !(Maybe (Interval v))
}
instance (Ord v, Show v, Show a) => Show (StrictIntervalMap v a) where
show m = "fromList " ++ show (toList m)
instance (Ord v, PrettyVal v, PrettyVal a) => PrettyVal (StrictIntervalMap v a) where
prettyVal m = Con "fromList" [prettyVal . map flattenIntervals . toList $ m]
where
flattenIntervals :: (Interval v, a) -> ((v, v), a)
flattenIntervals (Interval lo hi, a) = ((lo, hi), a)
unionInterval :: Ord v => Interval v -> Maybe (Interval v) -> Maybe (Interval v)
unionInterval i@(Interval low high) Nothing =
low `seq` high `seq` Just i
unionInterval (Interval low1 high1) (Just (Interval low2 high2)) =
let low = min low1 low2
high = max high1 high2
in low `seq` high `seq` Just (Interval low high)
dominators :: Ord v => Interval v -> StrictIntervalMap v a -> [(Interval v, a)]
dominators i = IntervalMap.dominators i . toLazyIntervalMap
empty :: Ord v => StrictIntervalMap v a
empty = StrictIntervalMap IntervalMap.empty Nothing
insert :: Ord v => Interval v -> a -> StrictIntervalMap v a -> StrictIntervalMap v a
insert i a m =
a `seq` StrictIntervalMap {
toLazyIntervalMap = IntervalMap.insert i a $ toLazyIntervalMap m
, maxInterval = unionInterval i $ maxInterval m
}
fromList :: Ord v => [(Interval v, a)] -> StrictIntervalMap v a
fromList = foldr (\(i, a) m -> insert i a m) empty
toList :: Ord v => StrictIntervalMap v a -> [(Interval v, a)]
toList m = case maxInterval m of
Nothing -> []
Just i -> IntervalMap.intersections i (toLazyIntervalMap m)