Skip to content

Commit 85a1ab5

Browse files
authored
Add {drop,preserve}Matched merge strategies (#1240)
dropMatched is added for Map, IntMap and Set. preserveMatched is added only for Set. Note that unlike dropMissing and preserveMissing, dropMatched and preserveMatched are simply for convenience and do not offer a performance advantage over mapMaybeMatched/filterMatched.
1 parent 722218d commit 85a1ab5

15 files changed

Lines changed: 94 additions & 13 deletions

File tree

containers-tests/tests/intmap-properties.hs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1461,6 +1461,7 @@ prop_merge miss1 miss2 match m1 m2 =
14611461
MapMissing f -> mapMissing (applyFun2 f)
14621462
MapMaybeMissing f -> mapMaybeMissing (applyFun2 f)
14631463
whenMatched spec = case spec of
1464+
DropMatched -> dropMatched
14641465
ZipWithMatched f -> zipWithMatched (applyFun3 f)
14651466
ZipWithMaybeMatched f -> zipWithMaybeMatched (applyFun3 f)
14661467

@@ -1504,6 +1505,7 @@ prop_mergeA miss1 miss2 match m1 m2 =
15041505
MapMissing f -> traverseMissing (\k x -> ([k], applyFun2 f k x))
15051506
MapMaybeMissing f -> traverseMaybeMissing (\k x -> ([k], applyFun2 f k x))
15061507
whenMatched spec = case spec of
1508+
DropMatched -> dropMatched
15071509
ZipWithMatched f -> zipWithAMatched (\k x y -> ([k], applyFun3 f k x y))
15081510
ZipWithMaybeMatched f -> zipWithMaybeAMatched (\k x y -> ([k], applyFun3 f k x y))
15091511

@@ -1526,14 +1528,16 @@ instance (Arbitrary a, CoArbitrary a, Function a)
15261528
]
15271529

15281530
data WhenMatchedSpec a
1529-
= ZipWithMatched (Fun (Int, a, a) a)
1531+
= DropMatched
1532+
| ZipWithMatched (Fun (Int, a, a) a)
15301533
| ZipWithMaybeMatched (Fun (Int, a, a) (Maybe a))
15311534
deriving Show
15321535

15331536
instance (Arbitrary a, CoArbitrary a, Function a)
15341537
=> Arbitrary (WhenMatchedSpec a) where
15351538
arbitrary = oneof
1536-
[ ZipWithMatched <$> arbitrary
1539+
[ pure DropMatched
1540+
, ZipWithMatched <$> arbitrary
15371541
, ZipWithMaybeMatched <$> arbitrary
15381542
]
15391543

containers-tests/tests/map-properties.hs

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1318,6 +1318,7 @@ prop_merge miss1 miss2 match m1 m2 =
13181318
MapMissing f -> mapMissing (applyFun2 f)
13191319
MapMaybeMissing f -> mapMaybeMissing (applyFun2 f)
13201320
whenMatched spec = case spec of
1321+
DropMatched -> dropMatched
13211322
ZipWithMatched f -> zipWithMatched (applyFun3 f)
13221323
ZipWithMaybeMatched f -> zipWithMaybeMatched (applyFun3 f)
13231324

@@ -1361,6 +1362,7 @@ prop_mergeA miss1 miss2 match m1 m2 =
13611362
MapMissing f -> traverseMissing (\k x -> ([k], applyFun2 f k x))
13621363
MapMaybeMissing f -> traverseMaybeMissing (\k x -> ([k], applyFun2 f k x))
13631364
whenMatched spec = case spec of
1365+
DropMatched -> dropMatched
13641366
ZipWithMatched f -> zipWithAMatched (\k x y -> ([k], applyFun3 f k x y))
13651367
ZipWithMaybeMatched f -> zipWithMaybeAMatched (\k x y -> ([k], applyFun3 f k x y))
13661368

@@ -1383,14 +1385,16 @@ instance (Arbitrary a, CoArbitrary a, Function a, CoArbitrary k, Function k)
13831385
]
13841386

13851387
data WhenMatchedSpec k a
1386-
= ZipWithMatched (Fun (k, a, a) a)
1388+
= DropMatched
1389+
| ZipWithMatched (Fun (k, a, a) a)
13871390
| ZipWithMaybeMatched (Fun (k, a, a) (Maybe a))
13881391
deriving Show
13891392

13901393
instance (Arbitrary a, CoArbitrary a, Function a, CoArbitrary k, Function k)
13911394
=> Arbitrary (WhenMatchedSpec k a) where
13921395
arbitrary = oneof
1393-
[ ZipWithMatched <$> arbitrary
1396+
[ pure DropMatched
1397+
, ZipWithMatched <$> arbitrary
13941398
, ZipWithMaybeMatched <$> arbitrary
13951399
]
13961400

@@ -1429,6 +1433,7 @@ prop_mergeMapSet miss1 miss2 match m1 s2 =
14291433
GenerateMissingMapSet f -> MergeSet.generateMissingSet (applyFun f)
14301434
GenerateMaybeMissingMapSet f -> MergeSet.generateMaybeMissingSet (applyFun f)
14311435
whenMatched spec = case spec of
1436+
DropMatchedMapSet -> MergeSet.dropMatched
14321437
FilterMatchedMapSet f -> MergeSet.filterMatched (applyFun2 f)
14331438
MapMatchedMapSet f -> MergeSet.mapMatched (applyFun2 f)
14341439
MapMaybeMatchedMapSet f -> MergeSet.mapMaybeMatched (applyFun2 f)
@@ -1477,6 +1482,7 @@ prop_mergeAMapSet miss1 miss2 match m1 s2 =
14771482
GenerateMissingMapSet f -> MergeSet.generateAMissingSet (\k -> ([k], applyFun f k))
14781483
GenerateMaybeMissingMapSet f -> MergeSet.generateMaybeAMissingSet (\k -> ([k], applyFun f k))
14791484
whenMatched spec = case spec of
1485+
DropMatchedMapSet -> MergeSet.dropMatched
14801486
FilterMatchedMapSet f -> MergeSet.filterAMatched (\k x -> ([k], applyFun2 f k x))
14811487
MapMatchedMapSet f -> MergeSet.traverseMatched (\k x -> ([k], applyFun2 f k x))
14821488
MapMaybeMatchedMapSet f -> MergeSet.traverseMaybeMatched (\k x -> ([k], applyFun2 f k x))
@@ -1500,19 +1506,22 @@ instance (Arbitrary a, CoArbitrary a, Function a, CoArbitrary k, Function k)
15001506
GenerateMaybeMissingMapSet f -> GenerateMaybeMissingMapSet <$> shrink f
15011507

15021508
data WhenMatchedMapSetSpec k a
1503-
= FilterMatchedMapSet (Fun (k, a) Bool)
1509+
= DropMatchedMapSet
1510+
| FilterMatchedMapSet (Fun (k, a) Bool)
15041511
| MapMatchedMapSet (Fun (k, a) a)
15051512
| MapMaybeMatchedMapSet (Fun (k, a) (Maybe a))
15061513
deriving Show
15071514

15081515
instance (Arbitrary a, CoArbitrary a, Function a, CoArbitrary k, Function k)
15091516
=> Arbitrary (WhenMatchedMapSetSpec k a) where
15101517
arbitrary = oneof
1511-
[ FilterMatchedMapSet <$> arbitrary
1518+
[ pure DropMatchedMapSet
1519+
, FilterMatchedMapSet <$> arbitrary
15121520
, MapMatchedMapSet <$> arbitrary
15131521
, MapMaybeMatchedMapSet <$> arbitrary
15141522
]
15151523
shrink spec = case spec of
1524+
DropMatchedMapSet -> []
15161525
FilterMatchedMapSet f -> FilterMatchedMapSet <$> shrink f
15171526
MapMatchedMapSet f -> MapMatchedMapSet <$> shrink f
15181527
MapMaybeMatchedMapSet f -> MapMaybeMatchedMapSet <$> shrink f

containers-tests/tests/set-properties.hs

Lines changed: 25 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
21
import qualified Data.IntSet as IntSet
32
import Data.Coerce (coerce)
43
import Data.List (nub, sort, sortBy)
@@ -809,7 +808,10 @@ prop_merge miss1 miss2 match s1 s2 =
809808
PreserveMissing -> preserveMissing
810809
FilterMissing f -> filterMissing (applyFun f)
811810

812-
toSimpleWhenMatched (FilterMatched f) = filterMatched (applyFun f)
811+
toSimpleWhenMatched spec = case spec of
812+
DropMatched -> dropMatched
813+
PreserveMatched -> preserveMatched
814+
FilterMatched f -> filterMatched (applyFun f)
813815

814816
prop_mergeA
815817
:: WhenMissingSpec Int
@@ -841,16 +843,18 @@ prop_mergeA miss1 miss2 match s1 s2 =
841843
PreserveMissing -> preserveMissing
842844
FilterMissing f -> filterAMissing (\x -> ([x], applyFun f x))
843845

844-
toWhenMatched (FilterMatched f) = filterAMatched (\x -> ([x], applyFun f x))
846+
toWhenMatched spec = case spec of
847+
DropMatched -> dropMatched
848+
PreserveMatched -> preserveMatched
849+
FilterMatched f -> filterAMatched (\x -> ([x], applyFun f x))
845850

846851
data WhenMissingSpec a
847852
= DropMissing
848853
| PreserveMissing
849854
| FilterMissing (Fun a Bool)
850855
deriving Show
851856

852-
instance (Arbitrary a, CoArbitrary a, Function a)
853-
=> Arbitrary (WhenMissingSpec a) where
857+
instance (CoArbitrary a, Function a) => Arbitrary (WhenMissingSpec a) where
854858
arbitrary = oneof
855859
[ pure DropMissing
856860
, pure PreserveMissing
@@ -861,5 +865,19 @@ instance (Arbitrary a, CoArbitrary a, Function a)
861865
PreserveMissing -> []
862866
FilterMissing f -> FilterMissing <$> shrink f
863867

864-
newtype WhenMatchedSpec a = FilterMatched (Fun a Bool)
865-
deriving (Show, Arbitrary)
868+
data WhenMatchedSpec a
869+
= DropMatched
870+
| PreserveMatched
871+
| FilterMatched (Fun a Bool)
872+
deriving Show
873+
874+
instance (CoArbitrary a, Function a) => Arbitrary (WhenMatchedSpec a) where
875+
arbitrary = oneof
876+
[ pure DropMatched
877+
, pure PreserveMatched
878+
, FilterMatched <$> arbitrary
879+
]
880+
shrink spec = case spec of
881+
DropMatched -> []
882+
PreserveMatched -> []
883+
FilterMatched f -> FilterMatched <$> shrink f

containers/src/Data/IntMap/Internal.hs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,7 @@ module Data.IntMap.Internal (
158158
, runWhenMissing
159159
, merge
160160
-- *** @WhenMatched@ tactics
161+
, dropMatched
161162
, zipWithMaybeMatched
162163
, zipWithMatched
163164
-- *** @WhenMissing@ tactics
@@ -1831,6 +1832,12 @@ mapWhenMatched f (WhenMatched g) =
18311832
-- @since 0.5.9
18321833
type SimpleWhenMatched = WhenMatched Identity
18331834

1835+
-- | When a key is found in both maps, drop the key and values.
1836+
--
1837+
-- @since FIXME
1838+
dropMatched :: Applicative f => WhenMatched f x y z
1839+
dropMatched = WhenMatched (\_ _ _ -> pure Nothing)
1840+
{-# INLINE dropMatched #-}
18341841

18351842
-- | When a key is found in both maps, apply a function to the key
18361843
-- and values and use the result in the merged map.

containers/src/Data/IntMap/Merge/Lazy.hs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ module Data.IntMap.Merge.Lazy (
4040
, merge
4141

4242
-- *** @WhenMatched@ tactics
43+
, dropMatched
4344
, zipWithMaybeMatched
4445
, zipWithMatched
4546

containers/src/Data/IntMap/Merge/Strict.hs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ module Data.IntMap.Merge.Strict (
4141
, merge
4242

4343
-- *** @WhenMatched@ tactics
44+
, dropMatched
4445
, zipWithMaybeMatched
4546
, zipWithMatched
4647

@@ -94,6 +95,7 @@ import Data.IntMap.Internal
9495
, WhenMatched (..)
9596
, mergeA
9697
, filterAMissing
98+
, dropMatched
9799
, runWhenMatched
98100
, runWhenMissing
99101
)

containers/src/Data/Map/Internal.hs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -195,6 +195,7 @@ module Data.Map.Internal (
195195
, runWhenMissing
196196
, merge
197197
-- *** @WhenMatched@ tactics
198+
, dropMatched
198199
, zipWithMaybeMatched
199200
, zipWithMatched
200201
-- *** @WhenMissing@ tactics
@@ -2277,6 +2278,13 @@ mapWhenMatched f (WhenMatched g) = WhenMatched $ \k x y -> fmap (fmap f) (g k x
22772278
-- @since 0.5.9
22782279
type SimpleWhenMatched = WhenMatched Identity
22792280

2281+
-- | When a key is found in both maps, drop the key and values.
2282+
--
2283+
-- @since FIXME
2284+
dropMatched :: Applicative f => WhenMatched f k x y z
2285+
dropMatched = WhenMatched (\_ _ _ -> pure Nothing)
2286+
{-# INLINE dropMatched #-}
2287+
22802288
-- | When a key is found in both maps, apply a function to the
22812289
-- key and values and use the result in the merged map.
22822290
--

containers/src/Data/Map/Merge/Lazy.hs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ module Data.Map.Merge.Lazy (
4040
, merge
4141

4242
-- *** @WhenMatched@ tactics
43+
, dropMatched
4344
, zipWithMaybeMatched
4445
, zipWithMatched
4546

containers/src/Data/Map/Merge/Set/Internal.hs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
module Data.Map.Merge.Set.Internal
2424
( WhenMatched(..)
2525
, SimpleWhenMatched
26+
, dropMatched
2627
, filterMatched
2728
, filterAMatched
2829

@@ -70,6 +71,13 @@ runWhenMatched = matchedKey
7071
-- @since FIXME
7172
type SimpleWhenMatched = WhenMatched Identity
7273

74+
-- | When a key is found in both the map and the set, drop the key and value.
75+
--
76+
-- @since FIXME
77+
dropMatched :: Applicative f => WhenMatched f k a b
78+
dropMatched = WhenMatched (\_ _ -> pure Nothing)
79+
{-# INLINE dropMatched #-}
80+
7381
-- | When a key is found in both the map and the set, apply a function to the
7482
-- key and the value in the map and keep the value in the merged map if the
7583
-- result is @True@.

containers/src/Data/Map/Merge/Set/Lazy.hs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ module Data.Map.Merge.Set.Lazy
2323
, Internal.merge
2424

2525
-- *** @WhenMatched@ tactics
26+
, Internal.dropMatched
2627
, Internal.filterMatched
2728
, mapMatched
2829
, mapMaybeMatched

0 commit comments

Comments
 (0)