/compiler/GHC/Types/Unique/Map.hs

https://github.com/bgamari/ghc · Haskell · 214 lines · 160 code · 42 blank · 12 comment · 0 complexity · 0aafe02bc1f13d4ba89c1cc57d3dc937 MD5 · raw file

  1. {-# LANGUAGE RoleAnnotations #-}
  2. {-# LANGUAGE TupleSections #-}
  3. {-# LANGUAGE DeriveDataTypeable #-}
  4. {-# LANGUAGE DeriveFunctor #-}
  5. {-# OPTIONS_GHC -Wall #-}
  6. -- Like 'UniqFM', these are maps for keys which are Uniquable.
  7. -- Unlike 'UniqFM', these maps also remember their keys, which
  8. -- makes them a much better drop in replacement for 'Data.Map.Map'.
  9. --
  10. -- Key preservation is right-biased.
  11. module GHC.Types.Unique.Map (
  12. UniqMap(..),
  13. emptyUniqMap,
  14. isNullUniqMap,
  15. unitUniqMap,
  16. listToUniqMap,
  17. listToUniqMap_C,
  18. addToUniqMap,
  19. addListToUniqMap,
  20. addToUniqMap_C,
  21. addToUniqMap_Acc,
  22. alterUniqMap,
  23. addListToUniqMap_C,
  24. adjustUniqMap,
  25. delFromUniqMap,
  26. delListFromUniqMap,
  27. plusUniqMap,
  28. plusUniqMap_C,
  29. plusMaybeUniqMap_C,
  30. plusUniqMapList,
  31. minusUniqMap,
  32. intersectUniqMap,
  33. disjointUniqMap,
  34. mapUniqMap,
  35. filterUniqMap,
  36. partitionUniqMap,
  37. sizeUniqMap,
  38. elemUniqMap,
  39. lookupUniqMap,
  40. lookupWithDefaultUniqMap,
  41. anyUniqMap,
  42. allUniqMap,
  43. nonDetEltsUniqMap,
  44. nonDetFoldUniqMap
  45. -- Non-deterministic functions omitted
  46. ) where
  47. import GHC.Prelude
  48. import GHC.Types.Unique.FM
  49. import GHC.Types.Unique
  50. import GHC.Utils.Outputable
  51. import Data.Semigroup as Semi ( Semigroup(..) )
  52. import Data.Coerce
  53. import Data.Maybe
  54. import Data.Data
  55. -- | Maps indexed by 'Uniquable' keys
  56. newtype UniqMap k a = UniqMap (UniqFM k (k, a))
  57. deriving (Data, Eq, Functor)
  58. type role UniqMap nominal representational
  59. instance Semigroup (UniqMap k a) where
  60. (<>) = plusUniqMap
  61. instance Monoid (UniqMap k a) where
  62. mempty = emptyUniqMap
  63. mappend = (Semi.<>)
  64. instance (Outputable k, Outputable a) => Outputable (UniqMap k a) where
  65. ppr (UniqMap m) =
  66. brackets $ fsep $ punctuate comma $
  67. [ ppr k <+> text "->" <+> ppr v
  68. | (k, v) <- nonDetEltsUFM m ]
  69. liftC :: (a -> a -> a) -> (k, a) -> (k, a) -> (k, a)
  70. liftC f (_, v) (k', v') = (k', f v v')
  71. emptyUniqMap :: UniqMap k a
  72. emptyUniqMap = UniqMap emptyUFM
  73. isNullUniqMap :: UniqMap k a -> Bool
  74. isNullUniqMap (UniqMap m) = isNullUFM m
  75. unitUniqMap :: Uniquable k => k -> a -> UniqMap k a
  76. unitUniqMap k v = UniqMap (unitUFM k (k, v))
  77. listToUniqMap :: Uniquable k => [(k,a)] -> UniqMap k a
  78. listToUniqMap kvs = UniqMap (listToUFM [ (k,(k,v)) | (k,v) <- kvs])
  79. listToUniqMap_C :: Uniquable k => (a -> a -> a) -> [(k,a)] -> UniqMap k a
  80. listToUniqMap_C f kvs = UniqMap $
  81. listToUFM_C (liftC f) [ (k,(k,v)) | (k,v) <- kvs]
  82. addToUniqMap :: Uniquable k => UniqMap k a -> k -> a -> UniqMap k a
  83. addToUniqMap (UniqMap m) k v = UniqMap $ addToUFM m k (k, v)
  84. addListToUniqMap :: Uniquable k => UniqMap k a -> [(k,a)] -> UniqMap k a
  85. addListToUniqMap (UniqMap m) kvs = UniqMap $
  86. addListToUFM m [(k,(k,v)) | (k,v) <- kvs]
  87. addToUniqMap_C :: Uniquable k
  88. => (a -> a -> a)
  89. -> UniqMap k a
  90. -> k
  91. -> a
  92. -> UniqMap k a
  93. addToUniqMap_C f (UniqMap m) k v = UniqMap $
  94. addToUFM_C (liftC f) m k (k, v)
  95. addToUniqMap_Acc :: Uniquable k
  96. => (b -> a -> a)
  97. -> (b -> a)
  98. -> UniqMap k a
  99. -> k
  100. -> b
  101. -> UniqMap k a
  102. addToUniqMap_Acc exi new (UniqMap m) k0 v0 = UniqMap $
  103. addToUFM_Acc (\b (k, v) -> (k, exi b v))
  104. (\b -> (k0, new b))
  105. m k0 v0
  106. alterUniqMap :: Uniquable k
  107. => (Maybe a -> Maybe a)
  108. -> UniqMap k a
  109. -> k
  110. -> UniqMap k a
  111. alterUniqMap f (UniqMap m) k = UniqMap $
  112. alterUFM (fmap (k,) . f . fmap snd) m k
  113. addListToUniqMap_C
  114. :: Uniquable k
  115. => (a -> a -> a)
  116. -> UniqMap k a
  117. -> [(k, a)]
  118. -> UniqMap k a
  119. addListToUniqMap_C f (UniqMap m) kvs = UniqMap $
  120. addListToUFM_C (liftC f) m
  121. [(k,(k,v)) | (k,v) <- kvs]
  122. adjustUniqMap
  123. :: Uniquable k
  124. => (a -> a)
  125. -> UniqMap k a
  126. -> k
  127. -> UniqMap k a
  128. adjustUniqMap f (UniqMap m) k = UniqMap $
  129. adjustUFM (\(_,v) -> (k,f v)) m k
  130. delFromUniqMap :: Uniquable k => UniqMap k a -> k -> UniqMap k a
  131. delFromUniqMap (UniqMap m) k = UniqMap $ delFromUFM m k
  132. delListFromUniqMap :: Uniquable k => UniqMap k a -> [k] -> UniqMap k a
  133. delListFromUniqMap (UniqMap m) ks = UniqMap $ delListFromUFM m ks
  134. plusUniqMap :: UniqMap k a -> UniqMap k a -> UniqMap k a
  135. plusUniqMap (UniqMap m1) (UniqMap m2) = UniqMap $ plusUFM m1 m2
  136. plusUniqMap_C :: (a -> a -> a) -> UniqMap k a -> UniqMap k a -> UniqMap k a
  137. plusUniqMap_C f (UniqMap m1) (UniqMap m2) = UniqMap $
  138. plusUFM_C (liftC f) m1 m2
  139. plusMaybeUniqMap_C :: (a -> a -> Maybe a) -> UniqMap k a -> UniqMap k a -> UniqMap k a
  140. plusMaybeUniqMap_C f (UniqMap m1) (UniqMap m2) = UniqMap $
  141. plusMaybeUFM_C (\(_, v) (k', v') -> fmap (k',) (f v v')) m1 m2
  142. plusUniqMapList :: [UniqMap k a] -> UniqMap k a
  143. plusUniqMapList xs = UniqMap $ plusUFMList (coerce xs)
  144. minusUniqMap :: UniqMap k a -> UniqMap k b -> UniqMap k a
  145. minusUniqMap (UniqMap m1) (UniqMap m2) = UniqMap $ minusUFM m1 m2
  146. intersectUniqMap :: UniqMap k a -> UniqMap k b -> UniqMap k a
  147. intersectUniqMap (UniqMap m1) (UniqMap m2) = UniqMap $ intersectUFM m1 m2
  148. disjointUniqMap :: UniqMap k a -> UniqMap k b -> Bool
  149. disjointUniqMap (UniqMap m1) (UniqMap m2) = disjointUFM m1 m2
  150. mapUniqMap :: (a -> b) -> UniqMap k a -> UniqMap k b
  151. mapUniqMap f (UniqMap m) = UniqMap $ mapUFM (fmap f) m -- (,) k instance
  152. filterUniqMap :: (a -> Bool) -> UniqMap k a -> UniqMap k a
  153. filterUniqMap f (UniqMap m) = UniqMap $ filterUFM (f . snd) m
  154. partitionUniqMap :: (a -> Bool) -> UniqMap k a -> (UniqMap k a, UniqMap k a)
  155. partitionUniqMap f (UniqMap m) =
  156. coerce $ partitionUFM (f . snd) m
  157. sizeUniqMap :: UniqMap k a -> Int
  158. sizeUniqMap (UniqMap m) = sizeUFM m
  159. elemUniqMap :: Uniquable k => k -> UniqMap k a -> Bool
  160. elemUniqMap k (UniqMap m) = elemUFM k m
  161. lookupUniqMap :: Uniquable k => UniqMap k a -> k -> Maybe a
  162. lookupUniqMap (UniqMap m) k = fmap snd (lookupUFM m k)
  163. lookupWithDefaultUniqMap :: Uniquable k => UniqMap k a -> a -> k -> a
  164. lookupWithDefaultUniqMap (UniqMap m) a k = fromMaybe a (fmap snd (lookupUFM m k))
  165. anyUniqMap :: (a -> Bool) -> UniqMap k a -> Bool
  166. anyUniqMap f (UniqMap m) = anyUFM (f . snd) m
  167. allUniqMap :: (a -> Bool) -> UniqMap k a -> Bool
  168. allUniqMap f (UniqMap m) = allUFM (f . snd) m
  169. nonDetEltsUniqMap :: UniqMap k a -> [(k, a)]
  170. nonDetEltsUniqMap (UniqMap m) = nonDetEltsUFM m
  171. nonDetFoldUniqMap :: ((k, a) -> b -> b) -> b -> UniqMap k a -> b
  172. nonDetFoldUniqMap go z (UniqMap m) = foldUFM go z m