@@ -125,6 +125,9 @@ module Data.IntMap.Internal (
125
125
, intersectionWith
126
126
, intersectionWithKey
127
127
128
+ -- ** Symmetric difference
129
+ , symmetricDifference
130
+
128
131
-- ** Compose
129
132
, compose
130
133
@@ -1304,6 +1307,49 @@ intersectionWithKey :: (Key -> a -> b -> c) -> IntMap a -> IntMap b -> IntMap c
1304
1307
intersectionWithKey f m1 m2
1305
1308
= mergeWithKey' bin (\ (Tip k1 x1) (Tip _k2 x2) -> Tip k1 (f k1 x1 x2)) (const Nil ) (const Nil ) m1 m2
1306
1309
1310
+ {- -------------------------------------------------------------------
1311
+ Symmetric difference
1312
+ --------------------------------------------------------------------}
1313
+
1314
+ -- | \(O(n+m)\). The symmetric difference of two maps.
1315
+ --
1316
+ -- The result contains entries whose keys appear in exactly one of the two maps.
1317
+ --
1318
+ -- @
1319
+ -- symmetricDifference
1320
+ -- (fromList [(0,\'q\'),(2,\'b\'),(4,\'w\'),(6,\'o\')])
1321
+ -- (fromList [(0,\'e\'),(3,\'r\'),(6,\'t\'),(9,\'s\')])
1322
+ -- ==
1323
+ -- fromList [(2,\'b\'),(3,\'r\'),(4,\'w\'),(9,\'s\')]
1324
+ -- @
1325
+ --
1326
+ -- @since FIXME
1327
+ symmetricDifference :: IntMap a -> IntMap a -> IntMap a
1328
+ symmetricDifference t1@ (Bin p1 l1 r1) t2@ (Bin p2 l2 r2) =
1329
+ case treeTreeBranch p1 p2 of
1330
+ ABL -> bin p1 (symmetricDifference l1 t2) r1
1331
+ ABR -> bin p1 l1 (symmetricDifference r1 t2)
1332
+ BAL -> bin p2 (symmetricDifference t1 l2) r2
1333
+ BAR -> bin p2 l2 (symmetricDifference t1 r2)
1334
+ EQL -> bin p1 (symmetricDifference l1 l2) (symmetricDifference r1 r2)
1335
+ NOM -> link (unPrefix p1) t1 (unPrefix p2) t2
1336
+ symmetricDifference t1@ (Bin _ _ _) t2@ (Tip k2 _) = symDiffTip t2 k2 t1
1337
+ symmetricDifference t1@ (Bin _ _ _) Nil = t1
1338
+ symmetricDifference t1@ (Tip k1 _) t2 = symDiffTip t1 k1 t2
1339
+ symmetricDifference Nil t2 = t2
1340
+
1341
+ symDiffTip :: IntMap a -> Int -> IntMap a -> IntMap a
1342
+ symDiffTip ! t1 ! k1 = go
1343
+ where
1344
+ go t2@ (Bin p2 l2 r2)
1345
+ | nomatch k1 p2 = linkKey k1 t1 p2 t2
1346
+ | left k1 p2 = bin p2 (go l2) r2
1347
+ | otherwise = bin p2 l2 (go r2)
1348
+ go t2@ (Tip k2 _)
1349
+ | k1 == k2 = Nil
1350
+ | otherwise = link k1 t1 k2 t2
1351
+ go Nil = t1
1352
+
1307
1353
{- -------------------------------------------------------------------
1308
1354
MergeWithKey
1309
1355
--------------------------------------------------------------------}
0 commit comments