diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/IntMapClass.hs | 324 |
1 files changed, 324 insertions, 0 deletions
diff --git a/lib/IntMapClass.hs b/lib/IntMapClass.hs new file mode 100644 index 0000000..c5e6a88 --- /dev/null +++ b/lib/IntMapClass.hs | |||
@@ -0,0 +1,324 @@ | |||
1 | {-# LANGUAGE CPP, | ||
2 | FlexibleContexts, | ||
3 | MultiParamTypeClasses, | ||
4 | GeneralizedNewtypeDeriving, | ||
5 | DeriveTraversable, | ||
6 | DeriveDataTypeable #-} | ||
7 | module IntMapClass where | ||
8 | |||
9 | import qualified Data.IntMap.Strict as IntMap | ||
10 | import Data.IntMap.Strict ( IntMap ) | ||
11 | import Data.Typeable ( Typeable ) | ||
12 | import Data.Data ( Data ) | ||
13 | import Data.Foldable ( Foldable ) | ||
14 | import Data.Traversable ( Traversable ) | ||
15 | import Data.Monoid ( Monoid ) | ||
16 | import Control.DeepSeq ( NFData ) | ||
17 | import Control.Applicative ( Applicative ) | ||
18 | import Data.Coerce | ||
19 | |||
20 | newtype IMap k a = IMap { intmap :: IntMap a } | ||
21 | deriving | ||
22 | ( Functor | ||
23 | , Typeable | ||
24 | , Foldable | ||
25 | , Traversable | ||
26 | , Eq | ||
27 | , Data | ||
28 | , Ord | ||
29 | , Read | ||
30 | , Show | ||
31 | , Semigroup | ||
32 | , Monoid | ||
33 | , NFData | ||
34 | ) | ||
35 | |||
36 | adaptm_k_a_m f k a m = IMap $ adapt_k_a_m f k a m | ||
37 | adapt_k_a_m f k a m = adapt_m (adapt_k f k a) m | ||
38 | |||
39 | adapt_m_k :: Coercible k Int => (IntMap a -> Int -> x) -> IMap k a -> k -> x | ||
40 | adapt_m_k f (IMap m) k = f m (coerce k) | ||
41 | |||
42 | adapt_k_m :: Coercible k Int => (Int -> IntMap a -> x) -> k -> IMap k a -> x | ||
43 | adapt_k_m f k (IMap m) = f (coerce k) m | ||
44 | -- adapt_k_m2 :: Coercible k Int => (Int -> IntMap a -> x) -> k -> IMap k a -> x | ||
45 | -- adapt_k_m2 f k m = (adapt_k f) k (intmap m) | ||
46 | |||
47 | adaptm_k_m | ||
48 | :: Coercible k Int => | ||
49 | (Int -> IntMap a -> IntMap a) -> k -> IMap k a -> IMap k a | ||
50 | adaptm_k_m f k m = IMap $ adapt_k_m f k m | ||
51 | |||
52 | adapt_k :: Coercible k Int => (Int -> x) -> k -> x | ||
53 | adapt_k f k = f (coerce k) | ||
54 | |||
55 | adapt_m_m :: (IntMap a -> IntMap a -> x) -> IMap k a -> IMap k a -> x | ||
56 | adapt_m_m f m = adapt_m (adapt_m f m) | ||
57 | |||
58 | adaptm_m_m :: (IntMap a -> IntMap a -> IntMap a) -> IMap k a -> IMap k a -> IMap k a | ||
59 | adaptm_m_m f a b = IMap $ adapt_m_m f a b | ||
60 | |||
61 | adapt_m :: (IntMap a -> x) -> IMap k a -> x | ||
62 | adapt_m f (IMap m) = f m | ||
63 | |||
64 | first f (x,y) = (f x,y) | ||
65 | second f (x,y) = (x,f y) | ||
66 | |||
67 | |||
68 | (!) :: Coercible k Int => IMap k a -> k -> a | ||
69 | (!) = adapt_m_k (IntMap.!) | ||
70 | |||
71 | (\\) :: IMap k a -> IMap k a -> IMap k a | ||
72 | (\\) a b = IMap $ adapt_m_m (IntMap.\\) a b | ||
73 | |||
74 | null = adapt_m (IntMap.null) | ||
75 | size = adapt_m (IntMap.size) | ||
76 | |||
77 | member :: Coercible k Int => k -> IMap k a -> Bool | ||
78 | member = adapt_k_m (IntMap.member) | ||
79 | |||
80 | notMember :: Coercible k Int => k -> IMap k a -> Bool | ||
81 | notMember = adapt_k_m (IntMap.notMember) | ||
82 | |||
83 | lookup :: Coercible k Int => k -> IMap k a -> Maybe a | ||
84 | lookup = adapt_k_m (IntMap.lookup) | ||
85 | |||
86 | findWithDefault :: Coercible k Int => x -> k -> IMap k x -> x | ||
87 | findWithDefault a = adapt_k_m (IntMap.findWithDefault a) | ||
88 | |||
89 | -- FIXME: fmap (first coerce) probably incurs cost | ||
90 | lookupLT :: ( Coercible Int k, Coercible k Int ) => k -> IMap k a -> Maybe (k, a) | ||
91 | lookupLT k m = fmap (first coerce) $ adapt_k_m (IntMap.lookupLT) k m | ||
92 | lookupGT :: ( Coercible Int k, Coercible k Int ) => k -> IMap k a -> Maybe (k, a) | ||
93 | lookupGT k m = fmap (first coerce) $ adapt_k_m (IntMap.lookupGT) k m | ||
94 | lookupLE :: ( Coercible Int k, Coercible k Int ) => k -> IMap k a -> Maybe (k, a) | ||
95 | lookupLE k m = fmap (first coerce) $ adapt_k_m (IntMap.lookupLE) k m | ||
96 | lookupGE :: ( Coercible Int k, Coercible k Int ) => k -> IMap k a -> Maybe (k, a) | ||
97 | lookupGE k m = fmap (first coerce) $ adapt_k_m (IntMap.lookupGE) k m | ||
98 | |||
99 | empty = IMap IntMap.empty | ||
100 | |||
101 | singleton :: Coercible k Int => k -> a -> IMap k a | ||
102 | singleton = (IMap .) . adapt_k IntMap.singleton | ||
103 | |||
104 | insert :: Coercible k Int => k -> a -> IMap k a -> IMap k a | ||
105 | insert = adaptm_k_a_m IntMap.insert | ||
106 | |||
107 | insertWith :: Coercible k Int => (a -> a -> a) -> k -> a -> IMap k a -> IMap k a | ||
108 | insertWith f = adaptm_k_a_m (IntMap.insertWith f) | ||
109 | |||
110 | insertWithKey :: (Coercible Int k, Coercible k Int) => (k -> a -> a -> a) -> k -> a -> IMap k a -> IMap k a | ||
111 | insertWithKey f = adaptm_k_a_m (IntMap.insertWithKey $ f . coerce) | ||
112 | |||
113 | insertLookupWithKey :: (Coercible Int k, Coercible k Int) => | ||
114 | (k -> a -> a -> a) -> k -> a -> IMap k a -> (Maybe a, IMap k a) | ||
115 | insertLookupWithKey f k a m = second IMap $ adapt_k_a_m (IntMap.insertLookupWithKey $ f . coerce) k a m | ||
116 | |||
117 | delete :: Coercible k Int => k -> IMap k a -> IMap k a | ||
118 | delete = adaptm_k_m IntMap.delete | ||
119 | |||
120 | adjust :: Coercible k Int => (a -> a) -> k -> IMap k a -> IMap k a | ||
121 | adjust f = adaptm_k_m (IntMap.adjust f) | ||
122 | |||
123 | adjustWithKey :: ( Coercible Int k, Coercible k Int ) => | ||
124 | (k -> a -> a) -> k -> IMap k a -> IMap k a | ||
125 | adjustWithKey f = adaptm_k_m (IntMap.adjustWithKey $ f . coerce) | ||
126 | |||
127 | update | ||
128 | :: Coercible k Int => (a -> Maybe a) -> k -> IMap k a -> IMap k a | ||
129 | update f = adaptm_k_m (IntMap.update f) | ||
130 | |||
131 | |||
132 | updateWithKey | ||
133 | :: (Coercible k Int, Coercible Int k) => | ||
134 | (k -> a -> Maybe a) -> k -> IMap k a -> IMap k a | ||
135 | updateWithKey f = adaptm_k_m (IntMap.updateWithKey $ f . coerce) | ||
136 | |||
137 | updateLookupWithKey :: | ||
138 | (Coercible k Int, Coercible Int k) => | ||
139 | (k -> a -> Maybe a) -> k -> IMap k a -> (Maybe a, IMap k a) | ||
140 | updateLookupWithKey f k m = | ||
141 | second IMap $ adapt_k_m (IntMap.updateLookupWithKey $ f . coerce) k m | ||
142 | |||
143 | alter :: Coercible k Int => (Maybe a -> Maybe a) -> k -> IMap k a -> IMap k a | ||
144 | alter f = adaptm_k_m (IntMap.alter f) | ||
145 | |||
146 | union :: IMap k a -> IMap k a -> IMap k a | ||
147 | union = adaptm_m_m IntMap.union | ||
148 | |||
149 | unionWith :: (a -> a -> a) -> IMap k a -> IMap k a -> IMap k a | ||
150 | unionWith f = adaptm_m_m (IntMap.unionWith f) | ||
151 | |||
152 | |||
153 | unionWithKey :: Coercible Int k => (k -> a -> a -> a) -> IMap k a -> IMap k a -> IMap k a | ||
154 | unionWithKey f = adaptm_m_m (IntMap.unionWithKey $ f . coerce) | ||
155 | |||
156 | -- unions :: Coercible [IMap k a] [IntMap a] => [IMap k a] -> IMap k a | ||
157 | -- unions ms = IMap $ IntMap.unions (coerce ms) | ||
158 | |||
159 | -- unionsWith :: Coercible [IMap k a] [IntMap a] => (a->a->a) -> [IMap k a] -> IMap k a | ||
160 | -- unionsWith f ms = IMap $ IntMap.unionsWith f (coerce ms) | ||
161 | |||
162 | difference = adaptm_m_m IntMap.difference | ||
163 | |||
164 | differenceWith f = adaptm_m_m (IntMap.differenceWith f) | ||
165 | |||
166 | differenceWithKey :: | ||
167 | Coercible Int k => | ||
168 | (k -> a -> a -> Maybe a) -> IMap k a -> IMap k a -> IMap k a | ||
169 | differenceWithKey f = adaptm_m_m (IntMap.differenceWithKey $ f . coerce) | ||
170 | |||
171 | intersection = adaptm_m_m IntMap.intersection | ||
172 | intersectionWith f = adaptm_m_m (IntMap.intersectionWith f) | ||
173 | |||
174 | mergeWithKey :: | ||
175 | Coercible Int k => | ||
176 | (k -> a -> b -> Maybe c) | ||
177 | -> (IMap k a -> IMap k c) | ||
178 | -> (IMap k b -> IMap k c) | ||
179 | -> IMap k a | ||
180 | -> IMap k b | ||
181 | -> IMap k c | ||
182 | mergeWithKey f g1 g2 = adaptm_m_m (IntMap.mergeWithKey f' g1' g2') | ||
183 | where f' = f . coerce | ||
184 | g1' = intmap . g1 . IMap | ||
185 | g2' = intmap . g2 . IMap | ||
186 | adapt_m_m f m = adapt_m (adapt_m f m) | ||
187 | adaptm_m_m f a b = IMap $ adapt_m_m f a b | ||
188 | |||
189 | map :: (a -> b) -> IMap k a -> IMap k b | ||
190 | map f = IMap . adapt_m (IntMap.map f) | ||
191 | |||
192 | mapWithKey :: Coercible Int k => (k -> a -> b) -> IMap k a -> IMap k b | ||
193 | mapWithKey f = IMap . adapt_m (IntMap.mapWithKey $ f . coerce) | ||
194 | |||
195 | -- FIXME: fmap IMap ? | ||
196 | traverseWithKey :: | ||
197 | (Applicative f, Coercible Int k) => | ||
198 | (k -> a -> f b) -> IMap k a -> f (IMap k b) | ||
199 | traverseWithKey f = fmap IMap . adapt_m (IntMap.traverseWithKey $ f . coerce) | ||
200 | |||
201 | mapAccum :: (t -> b -> (t, a)) -> t -> IMap k b -> (t, IMap k a) | ||
202 | mapAccum f a m = second IMap $ IntMap.mapAccum f a (intmap m) | ||
203 | |||
204 | mapAccumWithKey :: Coercible Int k => | ||
205 | (t -> k -> b -> (t, a)) -> t -> IMap k b -> (t, IMap k a) | ||
206 | mapAccumWithKey f a m = second IMap $ IntMap.mapAccumWithKey f' a (intmap m) | ||
207 | where f' a k b = f a (coerce k) b | ||
208 | |||
209 | |||
210 | mapAccumRWithKey :: Coercible Int k => | ||
211 | (t -> k -> b -> (t, a)) -> t -> IMap k b -> (t, IMap k a) | ||
212 | mapAccumRWithKey f a m = second IMap $ IntMap.mapAccumRWithKey f' a (intmap m) | ||
213 | where f' a k b = f a (coerce k) b | ||
214 | |||
215 | mapKeys :: (Coercible Int k1, Coercible k2 Int) => | ||
216 | (k1 -> k2) -> IMap k1 a -> IMap k2 a | ||
217 | mapKeys f = IMap . adapt_m (IntMap.mapKeys (coerce . f . coerce)) | ||
218 | |||
219 | mapKeysWith :: (Coercible Int k1, Coercible k2 Int) => | ||
220 | (a->a->a) -> (k1 -> k2) -> IMap k1 a -> IMap k2 a | ||
221 | mapKeysWith c f = IMap . adapt_m (IntMap.mapKeysWith c (coerce . f . coerce)) | ||
222 | |||
223 | mapKeysMonotonic :: (Coercible Int k1, Coercible k2 Int) => | ||
224 | (k1 -> k2) -> IMap k1 a -> IMap k2 a | ||
225 | mapKeysMonotonic f = IMap . adapt_m (IntMap.mapKeysMonotonic (coerce . f . coerce)) | ||
226 | |||
227 | foldr :: (a -> x -> x) -> x -> IMap k a -> x | ||
228 | foldr f b = adapt_m (IntMap.foldr f b) | ||
229 | |||
230 | foldl :: (x -> a -> x) -> x -> IMap k a -> x | ||
231 | foldl f a = adapt_m (IntMap.foldl f a) | ||
232 | |||
233 | foldrWithKey :: Coercible Int b => (b -> a -> x -> x) -> x -> IMap k a -> x | ||
234 | foldrWithKey f b = adapt_m (IntMap.foldrWithKey (f . coerce) b) | ||
235 | |||
236 | foldlWithKey :: | ||
237 | Coercible Int k => (x -> k -> a -> x) -> x -> IMap k a -> x | ||
238 | foldlWithKey f a = adapt_m (IntMap.foldlWithKey f' a) where f' a = f a . coerce | ||
239 | |||
240 | foldMapWithKey :: (Monoid m, Coercible k Int) => (k -> a -> m) -> IMap k a -> m | ||
241 | foldMapWithKey f = adapt_m (IntMap.foldMapWithKey $ f . coerce) | ||
242 | |||
243 | foldr' :: (a -> x -> x) -> x -> IMap k a -> x | ||
244 | foldr' f b = adapt_m (IntMap.foldr' f b) | ||
245 | |||
246 | foldl' :: (a -> x -> a) -> a -> IMap k x -> a | ||
247 | foldl' f b = adapt_m (IntMap.foldl' f b) | ||
248 | |||
249 | foldrWithKey' :: Coercible Int b => (b -> a -> x -> x) -> x -> IMap k a -> x | ||
250 | foldrWithKey' f b = adapt_m (IntMap.foldrWithKey' (f . coerce) b) | ||
251 | |||
252 | foldlWithKey' :: | ||
253 | Coercible Int k => (x -> k -> a -> x) -> x -> IMap k a -> x | ||
254 | foldlWithKey' f a = adapt_m (IntMap.foldlWithKey' f' a) where f' a = f a . coerce | ||
255 | |||
256 | elems :: IMap k a -> [a] | ||
257 | elems = IntMap.elems . intmap | ||
258 | |||
259 | keys :: Coercible [Int] [k] => IMap k a -> [k] | ||
260 | keys = coerce . IntMap.keys . intmap | ||
261 | |||
262 | assocs :: Coercible [(Int,a)] [(k,a)] => IMap k a -> [(k, a)] | ||
263 | assocs = coerce . IntMap.assocs . intmap | ||
264 | |||
265 | -- Not implementing... (doing it right requires wrapping IntSet) | ||
266 | -- keysSet :: IntMap a -> IntSet | ||
267 | -- fromSet :: (Key -> a) -> IntSet -> IntMap a | ||
268 | |||
269 | toList :: Coercible [(Int,a)] [(k,a)] => IMap k a -> [(k, a)] | ||
270 | toList = coerce . IntMap.toList . intmap | ||
271 | |||
272 | fromList :: Coercible [(k,a)] [(Int,a)] => [(k, a)] -> IMap k a | ||
273 | fromList = IMap . IntMap.fromList . coerce | ||
274 | |||
275 | fromListWith :: Coercible [(k,a)] [(Int,a)] => (a -> a -> a) -> [(k, a)] -> IMap k a | ||
276 | fromListWith f = IMap . IntMap.fromListWith f . coerce | ||
277 | |||
278 | fromListWithKey :: ( Coercible Int k | ||
279 | , Coercible [(k,a)] [(Int,a)] ) => | ||
280 | (k -> a -> a -> a) -> [(k, a)] -> IMap k a | ||
281 | fromListWithKey f = IMap . IntMap.fromListWithKey (f . coerce) . coerce | ||
282 | |||
283 | toAscList :: Coercible [(Int,a)] [(k,a)] => IMap k a -> [(k,a)] | ||
284 | toAscList (IMap m) = coerce $ IntMap.toAscList m | ||
285 | |||
286 | toDescList :: Coercible [(Int,a)] [(k,a)] => IMap k a -> [(k,a)] | ||
287 | toDescList (IMap m) = coerce $ IntMap.toDescList m | ||
288 | |||
289 | fromAscList :: Coercible [(k,a)] [(Int,a)] => [(k, a)] -> IMap k a | ||
290 | fromAscList = IMap . IntMap.fromAscList . coerce | ||
291 | |||
292 | fromAscListWith :: | ||
293 | Coercible [(k,a)] [(Int, a)] => | ||
294 | (a -> a -> a) -> [(k,a)] -> IMap k a | ||
295 | fromAscListWith f = IMap . IntMap.fromAscListWith f . coerce | ||
296 | |||
297 | fromAscListWithKey :: | ||
298 | (Coercible Int k, Coercible [(k,a)] [(Int, a)]) => | ||
299 | (k -> a -> a -> a) -> [(k,a)] -> IMap k a | ||
300 | fromAscListWithKey f = IMap . IntMap.fromAscListWithKey (f . coerce) . coerce | ||
301 | |||
302 | fromDistinctAscList :: Coercible [(k,a)] [(Int,a)] => [(k, a)] -> IMap k a | ||
303 | fromDistinctAscList = IMap . IntMap.fromDistinctAscList . coerce | ||
304 | |||
305 | filter :: (a -> Bool) -> IMap k a -> IMap k a | ||
306 | filter f = IMap . adapt_m (IntMap.filter f) | ||
307 | |||
308 | filterWithKey :: Coercible Int k => (k -> a -> Bool) -> IMap k a -> IMap k a | ||
309 | filterWithKey f = IMap . adapt_m (IntMap.filterWithKey $ f . coerce) | ||
310 | |||
311 | partition :: Coercible (IntMap a,IntMap a) (IMap k a,IMap k a) | ||
312 | => (a -> Bool) -> IMap k a -> (IMap k a, IMap k a) | ||
313 | partition f m = coerce $ IntMap.partition f (intmap m) | ||
314 | |||
315 | |||
316 | partitionWithKey :: ( Coercible Int k | ||
317 | , Coercible (IntMap a,IntMap a) (IMap k a,IMap k a) ) | ||
318 | => (k -> a -> Bool) -> IMap k a -> (IMap k a, IMap k a) | ||
319 | partitionWithKey f m = coerce $ IntMap.partitionWithKey (f . coerce) (intmap m) | ||
320 | |||
321 | mapMaybe :: (a -> Maybe b) -> IMap k a -> IMap k b | ||
322 | mapMaybe f = IMap . IntMap.mapMaybe f . intmap | ||
323 | |||
324 | |||