From 2391b3b42e75b3a1fc90629c46646355644150cd Mon Sep 17 00:00:00 2001 From: Cole Haus Date: Fri, 13 Apr 2018 20:53:14 -0700 Subject: [PATCH 1/2] Add `unionsWith` Straightforward combo of `unionWith` and `unions`. Haskell's `container` has it. --- src/Data/Map.purs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/Data/Map.purs b/src/Data/Map.purs index e764370b..cba4d51b 100644 --- a/src/Data/Map.purs +++ b/src/Data/Map.purs @@ -608,6 +608,9 @@ union = unionWith const unions :: forall k v f. Ord k => Foldable f => f (Map k v) -> Map k v unions = foldl union empty +unionsWith :: forall k v f. Ord k => Foldable f => (v -> v -> v) -> f (Map k v) -> Map k v +unionsWith f = foldl (unionWith f) empty + -- | Test whether one map contains all of the keys and values contained in another map isSubmap :: forall k v. Ord k => Eq v => Map k v -> Map k v -> Boolean isSubmap m1 m2 = LL.all f $ (toUnfoldable m1 :: LL.List (Tuple k v)) From 22e3ee612d6c3868b59a6f58000e7cfdb4b6a8c3 Mon Sep 17 00:00:00 2001 From: Cole Haus Date: Thu, 10 May 2018 00:30:29 -0700 Subject: [PATCH 2/2] Test `unionsWith` --- src/Data/Map.purs | 1 + test/Test/Data/Map.purs | 23 +++++++++++++++++++++++ 2 files changed, 24 insertions(+) diff --git a/src/Data/Map.purs b/src/Data/Map.purs index cba4d51b..798ef32a 100644 --- a/src/Data/Map.purs +++ b/src/Data/Map.purs @@ -32,6 +32,7 @@ module Data.Map , union , unionWith , unions + , unionsWith , isSubmap , size , mapWithKey diff --git a/test/Test/Data/Map.purs b/test/Test/Data/Map.purs index bc38e615..e53f81aa 100644 --- a/test/Test/Data/Map.purs +++ b/test/Test/Data/Map.purs @@ -23,6 +23,9 @@ import Test.QuickCheck.Gen (elements, oneOf) newtype TestMap k v = TestMap (M.Map k v) +unwrap :: forall k v. TestMap k v -> M.Map k v +unwrap (TestMap m) = m + instance arbTestMap :: (Eq k, Ord k, Arbitrary k, Arbitrary v) => Arbitrary (TestMap k v) where arbitrary = TestMap <$> genMap arbitrary arbitrary @@ -214,6 +217,26 @@ mapTests = do Just v -> Just v == v2 Nothing -> not (in1 || in2) + log "unionsWith" + for_ [Tuple (+) 0, Tuple (*) 1] $ \(Tuple op ident) -> + quickCheck $ \(testMaps :: Array (TestMap SmallKey Int)) k -> + let testMaps' = unwrap <$> testMaps + u = M.unionsWith op testMaps' + in case M.lookup k u of + Nothing -> A.all (not <<< M.member k) testMaps' + Just v -> (v == _) <<< A.foldl op ident <<< map (fromMaybe ident <<< M.lookup k) $ testMaps' + + log "unionsWith argument order" + quickCheck $ \(testMaps :: Array (TestMap SmallKey Int)) k -> + let testMaps' = unwrap <$> testMaps + u = M.unionsWith (-) testMaps' + in case M.lookup k u of + Just v -> + case A.uncons <<< A.mapMaybe (M.lookup k) $ testMaps' of + Nothing -> false + Just { head, tail } -> v == foldl (-) head tail + Nothing -> A.all (not <<< M.member k) testMaps' + log "size" quickCheck $ \xs -> let xs' = nubBy ((==) `on` fst) xs