Permalink
Browse files

Add 'differenceSet'

  • Loading branch information...
1 parent 0847603 commit 7fad0f8dd8b171cb6529e3e459dd29af0100aa7f @bovinespirit committed Nov 15, 2012
Showing with 38 additions and 6 deletions.
  1. +10 −1 Data/EnumMapMap/Base.hs
  2. +8 −2 Data/EnumMapMap/Lazy.hs
  3. +9 −2 Data/EnumMapMap/Strict.hs
  4. +0 −1 README.md
  5. +11 −0 test/UnitEnumMapMap.hs
View
@@ -209,12 +209,16 @@ class SubKey k1 k2 v where
k1 -> EnumMapMap k2 v -> EnumMapMap k2 v
class SubKeyS k s where
- -- | The intersection of an 'EnumMapMap' and an EnumMapSet. If a key is
+ -- | The intersection of an 'EnumMapMap' and an 'EnumMapSet'. If a key is
-- present in the EnumMapSet then it will be present in the resulting
-- 'EnumMapMap'. Works with 'EnumMapSet's that are submaps of the
-- 'EnumMapMap'.
intersectSet :: (IsKey k, IsKey s) =>
EnumMapMap k v -> EnumMapMap s () -> EnumMapMap k v
+ -- | The difference between an 'EnumMapMap' and an 'EnumMapSet'. If a key
+ -- is present in the 'EnumMapSet' it will not be present in the result.
+ differenceSet :: (IsKey k, IsKey s) =>
+ EnumMapMap k v -> EnumMapMap s () -> EnumMapMap k v
class HasSKey k where
type Skey k :: *
@@ -415,6 +419,11 @@ instance (Enum k, IsKey t1, IsKey t2, SubKeyS t1 t2) =>
where
go = \(Tip k1 x1) (Tip _ x2) ->
tip k1 $ intersectSet x1 x2
+ differenceSet (KCC emm) (KCC ems) =
+ KCC $ mergeWithKey' binD go id (const Nil) emm ems
+ where
+ go = \(Tip k1 x1) (Tip _ x2) ->
+ tip k1 $ differenceSet x1 x2
instance (Eq k, Enum k, IsKey t, HasSKey t) => IsKey (k :& t) where
data EnumMapMap (k :& t) v = KCC (EMM k (EnumMapMap t v))
View
@@ -63,6 +63,7 @@ module Data.EnumMapMap.Lazy (
difference,
differenceWith,
differenceWithKey,
+ differenceSet,
-- ** Intersection
intersection,
intersectionWith,
@@ -266,9 +267,11 @@ instance (Enum k) => SubKey (K k) (K k) v where
instance (Enum k1, k1 ~ k2) => SubKeyS (k1 :& t) (EMS.S k2) where
intersectSet (KCC emm) (EMS.KSC ems) = KCC $ intersectSet_ emm ems
+ differenceSet (KCC emm) (EMS.KSC ems) = KCC $ differenceSet_ emm ems
instance (Enum k) => SubKeyS (K k) (EMS.S k) where
intersectSet (KEC emm) (EMS.KSC ems) = KEC $ intersectSet_ emm ems
+ differenceSet (KEC emm) (EMS.KSC ems) = KEC $ differenceSet_ emm ems
member_ :: Key -> EMM k v -> Bool
member_ key emm = go emm
@@ -353,6 +356,9 @@ fromSet_ f = go
intersectSet_ :: EMM k v -> EMS.EMS k -> EMM k v
intersectSet_ emm ems =
mergeWithKey' bin const (const Nil) (const Nil) emm ems'
- where
- ems' = fromSet_ (\_ -> ()) ems
+ where ems' = fromSet_ (\_ -> ()) ems
+differenceSet_ :: EMM k v -> EMS.EMS k -> EMM k v
+differenceSet_ emm ems =
+ mergeWithKey' bin (\_ _ -> Nil) id (const Nil) emm ems'
+ where ems' = fromSet_ (\_ -> ()) ems
View
@@ -63,6 +63,7 @@ module Data.EnumMapMap.Strict (
difference,
differenceWith,
differenceWithKey,
+ differenceSet,
-- ** Intersection
intersection,
intersectionWith,
@@ -266,9 +267,11 @@ instance (Enum k) => SubKey (K k) (K k) v where
instance (Enum k1, k1 ~ k2) => SubKeyS (k1 :& t) (EMS.S k2) where
intersectSet (KCC emm) (EMS.KSC ems) = KCC $ intersectSet_ emm ems
+ differenceSet (KCC emm) (EMS.KSC ems) = KCC $ differenceSet_ emm ems
instance (Enum k) => SubKeyS (K k) (EMS.S k) where
intersectSet (KEC emm) (EMS.KSC ems) = KEC $ intersectSet_ emm ems
+ differenceSet (KEC emm) (EMS.KSC ems) = KEC $ differenceSet_ emm ems
member_ :: Key -> EMM k v -> Bool
member_ key emm = go emm
@@ -354,5 +357,9 @@ fromSet_ f = go
intersectSet_ :: EMM k v -> EMS.EMS k -> EMM k v
intersectSet_ emm ems =
mergeWithKey' bin const (const Nil) (const Nil) emm ems'
- where
- ems' = fromSet_ (\_ -> ()) ems
+ where ems' = fromSet_ (\_ -> ()) ems
+
+differenceSet_ :: EMM k v -> EMS.EMS k -> EMM k v
+differenceSet_ emm ems =
+ mergeWithKey' bin (\_ _ -> Nil) id (const Nil) emm ems'
+ where ems' = fromSet_ (\_ -> ()) ems
View
@@ -63,7 +63,6 @@ IntMap for speed.
TODO:
- Finish operations on subtrees: alter
-- differenceSet -- needs some thought...
- Check that Strict really is strict and Lazy really is lazy.
- More functions - mapMaybe, update, mergeWithKey, foldr'
- More benchmarks and optimisation
View
@@ -74,6 +74,8 @@ l2tens = EMM.fromList $ zip (do
l1odds :: EnumMapMap (K Int) Int
l1odds = EMM.fromList $ map (\(key, v) -> (K key, v)) $ zip odds odds
+l1fewOdds :: EnumMapMap (K Int) Int
+l1fewOdds = EMM.fromList $ map (\(key, v) -> (K key, v)) $ zip fewOdds fewOdds
l2odds :: EnumMapMap (Int :& K Int) Int
l2odds = EMM.fromList $ zip (do
k1 <- fewOdds
@@ -323,3 +325,12 @@ main =
it "leaves correct subtree" $
(EMM.intersectSet l2odds $ EMS.fromList [s 1])
@?= EMM.fromList [(1 :& k 1, 1), (1 :& k 3, 3), (1 :& k 5, 5)]
+ -- TODO: check for empty subtrees
+
+ describe "differenceSet" $ do
+ it "works correctly" $
+ (EMM.differenceSet l1fewOdds $ EMS.fromList [s 3, s 4, s 5])
+ @?= EMM.fromList [(k 1, 1)]
+ it "leaves correct subtree" $
+ (EMM.differenceSet l2odds $ EMS.fromList [s 3, s 4, s 5])
+ @?= EMM.fromList [(1 :& k 1, 1), (1 :& k 3, 3), (1 :& k 5, 5)]

0 comments on commit 7fad0f8

Please sign in to comment.