Skip to content

Commit 67a0263

Browse files
committed
Add insertWith for Map
1 parent 341247b commit 67a0263

File tree

3 files changed

+17
-1
lines changed

3 files changed

+17
-1
lines changed

src/Data/Map.purs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ module Data.Map
55

66
import Prelude
77

8-
import Data.Map.Internal (Map, alter, checkValid, delete, empty, filter, filterKeys, filterWithKey, findMax, findMin, foldSubmap, fromFoldable, fromFoldableWith, fromFoldableWithIndex, insert, isEmpty, isSubmap, lookup, lookupGE, lookupGT, lookupLE, lookupLT, member, pop, showTree, singleton, size, submap, toUnfoldable, toUnfoldableUnordered, union, unionWith, unions, difference, update, values, mapMaybeWithKey, mapMaybe)
8+
import Data.Map.Internal (Map, alter, checkValid, delete, empty, filter, filterKeys, filterWithKey, findMax, findMin, foldSubmap, fromFoldable, fromFoldableWith, fromFoldableWithIndex, insert, insertWith, isEmpty, isSubmap, lookup, lookupGE, lookupGT, lookupLE, lookupLT, member, pop, showTree, singleton, size, submap, toUnfoldable, toUnfoldableUnordered, union, unionWith, unions, difference, update, values, mapMaybeWithKey, mapMaybe)
99
import Data.Set (Set)
1010
import Unsafe.Coerce (unsafeCoerce)
1111

src/Data/Map/Internal.purs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ module Data.Map.Internal
99
, singleton
1010
, checkValid
1111
, insert
12+
, insertWith
1213
, lookup
1314
, lookupLE
1415
, lookupLT
@@ -455,6 +456,13 @@ insert k v = down Nil
455456
ThreeMiddle a k1 v1 k2 v2 d, KickUp b k' v' c -> up ctx (KickUp (Two a k1 v1 b) k' v' (Two c k2 v2 d))
456457
ThreeRight a k1 v1 b k2 v2, KickUp c k' v' d -> up ctx (KickUp (Two a k1 v1 b) k2 v2 (Two c k' v' d))
457458

459+
-- | Inserts or updates a value with the given function.
460+
-- |
461+
-- | The combining function is called with the existing value as the first
462+
-- | argument and the new value as the second argument.
463+
insertWith :: forall k v. Ord k => (v -> v -> v) -> k -> v -> Map k v -> Map k v
464+
insertWith f k v = alter (Just <<< maybe v (flip f v)) k
465+
458466
-- | Delete a key and its corresponding value from a map.
459467
delete :: forall k v. Ord k => k -> Map k v -> Map k v
460468
delete k m = maybe m snd (pop k m)

test/Test/Data/Map.purs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,14 @@ mapTests = do
8383
quickCheck $ \k v1 v2 ->
8484
M.lookup (smallKey k) (M.insert k v2 (M.insert k v1 M.empty)) == Just (number v2)
8585

86+
log "Test insertWith combining values"
87+
quickCheck $ \k v1 v2 ->
88+
M.lookup (smallKey k) (M.insertWith (+) k v2 (M.insert k v1 M.empty)) == Just (number (v1 + v2))
89+
90+
log "Test insertWith passes the first value as the first argument to the combining function"
91+
quickCheck $ \k v1 v2 ->
92+
M.lookup (smallKey k) (M.insertWith const k v2 (M.insert k v1 M.empty)) == Just (number v1)
93+
8694
log "Test delete after inserting"
8795
quickCheck $ \k v -> M.isEmpty (M.delete (smallKey k) (M.insert k (number v) M.empty))
8896
<?> ("k: " <> show k <> ", v: " <> show v)

0 commit comments

Comments
 (0)