@@ -50,6 +50,8 @@ module Data.HashMap.Strict.Refined
5050 , FromTraversableProof(..)
5151 -- * Insertion
5252 , insert
53+ , insertWith
54+ , insertWithKey
5355 , InsertProof(..)
5456 , reinsert
5557 , insertLookupWithKey
@@ -206,6 +208,35 @@ insert
206208insert k v (HashMap m) = SomeHashMapWith (HashMap $ HashMap.insert k v m)
207209 $ InsertProof (unsafeKey k) unsafeSubset
208210
211+-- | Insert a key-value pair into the map to obtain a potentially larger map,
212+-- guaranteed to contain the given key. If the key was already present, the
213+-- supplied function is used to combine the new value with the old (in that
214+-- order).
215+insertWith
216+ :: forall s k a. Hashable k
217+ => (a -> a -> a)
218+ -> k
219+ -> a
220+ -> HashMap s k a
221+ -> SomeHashMapWith (InsertProof 'Hashed k s) k a
222+insertWith f k v (HashMap m) = SomeHashMapWith
223+ (HashMap $ HashMap.insertWith f k v m)
224+ $ InsertProof (unsafeKey k) unsafeSubset
225+
226+-- | Insert a key-value pair into the map to obtain a potentially larger map,
227+-- guaranteed to contain the given key. Like 'insertWith', but the combining
228+-- function has access to the key, which is guaranteed to be in the old map.
229+insertWithKey
230+ :: forall s k a. Hashable k
231+ => (Key s k -> a -> a -> a)
232+ -> k
233+ -> a
234+ -> HashMap s k a
235+ -> SomeHashMapWith (InsertProof 'Hashed k s) k a
236+insertWithKey f k v (HashMap m) = SomeHashMapWith
237+ (HashMap $ HashMap.insertWith (f $ unsafeKey k) k v m)
238+ $ InsertProof (unsafeKey k) unsafeSubset
239+
209240-- | Overwrite a key-value pair that is known to already be in the map. The set
210241-- of keys remains the same.
211242reinsert