@@ -35,6 +35,7 @@ module Data.IntMap (
35
35
, adjustWithKey
36
36
, update
37
37
, updateWithKey
38
+ , alter
38
39
39
40
, unionWith
40
41
, unionLeft
@@ -58,7 +59,7 @@ module Data.IntMap (
58
59
) where
59
60
60
61
import Data.Foldable (class Foldable , foldMap , foldl )
61
- import Data.IntMap.Internal (Prefix , Mask (Mask), mask , branchLeft , branchingBit' , prefixAsKey , matchPrefix , maskLonger )
62
+ import Data.IntMap.Internal (Prefix (Prefix) , Mask (Mask), mask , branchLeft , branchingBit' , prefixAsKey , matchPrefix , maskLonger , branchMask )
62
63
import Data.Maybe (Maybe (Nothing, Just))
63
64
import Data.Monoid (class Monoid , mempty )
64
65
import Data.Traversable (class Traversable )
@@ -226,8 +227,38 @@ updateWithKey f k t = go t where
226
227
| branchLeft m k -> br p m (go l) r
227
228
| otherwise -> br p m l (go r)
228
229
229
- -- | Unions two `IntMap`s together using a splatting function. If
230
- -- | a key is present in both constituent lists then the resulting
230
+ -- | /O(min(n,W))/. The expresion (@'alter' f k m@) alters the value @x@
231
+ -- | at key @k@, or absence thereof.
232
+ -- | 'alter' can be used to insert, delete, or update the value under given
233
+ -- | key in the 'IntMap'.
234
+ -- | The following property holds:
235
+ -- | @'lookup' k ('alter' f k m) = f ('lookup' k m)@.
236
+ alter :: forall a . (Maybe a -> Maybe a ) -> Int -> IntMap a -> IntMap a
237
+ alter f k t =
238
+ case t of
239
+ Br p@(Prefix p') m l r
240
+ | not (matchPrefix p m k) ->
241
+ case f Nothing of
242
+ Nothing -> t
243
+ Just a -> link k (Lf k a) p' t
244
+ | branchLeft m k -> br p m (alter f k l) r
245
+ | otherwise -> br p m l (alter f k r)
246
+ Lf ky y
247
+ | k == ky ->
248
+ case f (Just y) of
249
+ Just x -> Lf ky x
250
+ Nothing -> Empty
251
+ | otherwise ->
252
+ case f Nothing of
253
+ Just x -> link k (Lf k x) ky t
254
+ Nothing -> Lf ky y
255
+ Empty ->
256
+ case f Nothing of
257
+ Just a -> Lf k a
258
+ Nothing -> Empty
259
+
260
+ -- | Unions two `IntMap`s together using a splatting function. If
261
+ -- | a key is present in both constituent lists then the resulting
231
262
-- | list will be the splat of the values from each constituent. If the key
232
263
-- | was available in only one constituent then it is available unmodified
233
264
-- | in the result.
@@ -378,3 +409,12 @@ join k1 m1 t1 k2 m2 t2 =
378
409
in if branchLeft m k1
379
410
then Br (mask m k1) m t1 t2
380
411
else Br (mask m k1) m t2 t1
412
+
413
+ link :: forall a . Int -> IntMap a -> Int -> IntMap a -> IntMap a
414
+ link k1 t1 k2 t2 =
415
+ if branchLeft m k1
416
+ then Br p m t1 t2
417
+ else Br p m t2 t1
418
+ where
419
+ m = branchMask k1 k2
420
+ p = mask m k1
0 commit comments