Skip to content
This repository was archived by the owner on Oct 4, 2020. It is now read-only.

Commit 1101cca

Browse files
committed
add unionWith
1 parent 4c5c3f8 commit 1101cca

File tree

3 files changed

+20
-2
lines changed

3 files changed

+20
-2
lines changed

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,8 @@
5454

5555
union :: forall k v. (P.Ord k) => Map k v -> Map k v -> Map k v
5656

57+
unionWith :: forall k v. (P.Ord k) => (v -> v -> v) -> Map k v -> Map k v -> Map k v
58+
5759
unions :: forall k v. (P.Ord k) => [Map k v] -> Map k v
5860

5961
update :: forall k v. (P.Ord k) => (v -> Maybe v) -> k -> Map k v -> Map k v

src/Data/Map.purs

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ module Data.Map
2222
keys,
2323
values,
2424
union,
25+
unionWith,
2526
unions,
2627
map,
2728
size
@@ -230,8 +231,15 @@ values Leaf = []
230231
values (Two left _ v right) = values left P.++ [v] P.++ values right
231232
values (Three left _ v1 mid _ v2 right) = values left P.++ [v1] P.++ values mid P.++ [v2] P.++ values right
232233

234+
-- Computes the union of two maps, except that when a key exists in both maps, its value in the result
235+
-- is computed by combining them with the supplied function.
236+
unionWith :: forall k v. (P.Ord k) => (v -> v -> v) -> Map k v -> Map k v -> Map k v
237+
unionWith f m1 m2 = foldl go m2 (toList m1)
238+
where
239+
go m (Tuple k v) = alter (Just P.<<< maybe v (f v)) k m
240+
233241
union :: forall k v. (P.Ord k) => Map k v -> Map k v -> Map k v
234-
union m1 m2 = foldl (\m (Tuple k v) -> insert k v m) m2 (toList m1)
242+
union = unionWith P.const
235243

236244
unions :: forall k v. (P.Ord k) => [Map k v] -> Map k v
237245
unions = foldl union empty

tests/Data/Map.purs

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import Data.Maybe
66
import Data.Tuple
77
import Data.Array (map, length, nubBy)
88
import Data.Function (on)
9-
import Data.Foldable (foldl)
9+
import Data.Foldable (foldl, for_)
1010

1111
import Test.QuickCheck
1212

@@ -166,6 +166,14 @@ mapTests = do
166166
trace "Union is idempotent"
167167
quickCheck $ \m1 m2 -> (m1 `M.union` m2) == ((m1 `M.union` m2) `M.union` (m2 :: M.Map SmallKey Number))
168168

169+
trace "unionWith"
170+
for_ [Tuple (+) 0, Tuple (*) 1] $ \(Tuple op ident) ->
171+
quickCheck $ \m1 m2 k ->
172+
let u = M.unionWith op m1 m2 :: M.Map SmallKey Number
173+
in case M.lookup k u of
174+
Nothing -> not (M.member k m1 || M.member k m2)
175+
Just v -> v == op (fromMaybe ident (M.lookup k m1)) (fromMaybe ident (M.lookup k m2))
176+
169177
trace "size"
170178
quickCheck $ \xs ->
171179
let xs' = nubBy ((==) `on` fst) xs

0 commit comments

Comments
 (0)