@@ -1,4 +1,4 @@
1−module Dict (empty,singleton,insert
1+module Dict (empty,singleton,insert,update
2 ,lookup,findWithDefault
2 ,lookup,findWithDefault
3 ,remove,member
3 ,remove,member
4 ,foldl,foldr,map
4 ,foldl,foldr,map
@@ -14,7 +14,7 @@ lists of comparable types.
14Insert, remove, and query operations all take *O(log n)* time.
14Insert, remove, and query operations all take *O(log n)* time.
17−@docs empty, singleton, insert, remove
17+@docs empty, singleton, insert, update, remove
20@docs member, lookup, findWithDefault
20@docs member, lookup, findWithDefault
@@ -148,17 +148,23 @@ ensureBlackRoot t =
148{-| Insert a key-value pair into a dictionary. Replaces value when there is
148{-| Insert a key-value pair into a dictionary. Replaces value when there is
149a collision. -}
149a collision. -}
150insert : comparable -> v -> Dict comparable v -> Dict comparable v
150insert : comparable -> v -> Dict comparable v -> Dict comparable v
151+insert k v t = let updater _ = v
152+ in update k updater t
154+{-| Update the value of a dictionary for a specific key with a given function. -}
155+update : comparable -> (Maybe v -> v) -> Dict comparable v -> Dict comparable v
151−insert k v t = -- Invariant: t is a valid left-leaning rb tree
156+update k u t = -- Invariant: t is a valid left-leaning rb tree
152− let ins t =
157+ let up t =
153 case t of
158 case t of
154− RBEmpty LBlack -> RBNode Red k v (RBEmpty LBlack) (RBEmpty LBlack)
160+ RBEmpty LBlack -> RBNode Red k (u Nothing) (RBEmpty LBlack) (RBEmpty LBlack)
155 RBNode c k' v' l r ->
161 RBNode c k' v' l r ->
156 let h = case Native.Utils.compare k k' of
162 let h = case Native.Utils.compare k k' of
157− LT -> RBNode c k' v' (ins l) r
163+ LT -> RBNode c k' v' (up l) r
158− EQ -> RBNode c k' v l r -- replace
164+ EQ -> RBNode c k' (u (Just v')) l r -- update case
159− GT -> RBNode c k' v' l (ins r)
165+ GT -> RBNode c k' v' l (up r)
160 in fixUp h
166 in fixUp h
161− in ensureBlackRoot (ins t)
167+ in ensureBlackRoot (up t)
163{-| Create a dictionary with one key-value pair. -}
169{-| Create a dictionary with one key-value pair. -}
164singleton : comparable -> v -> Dict comparable v
170singleton : comparable -> v -> Dict comparable v