Hello community,

here is the log from the commit of package ghc-unordered-containers for 
openSUSE:Factory checked in at 2017-04-14 13:38:59
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/ghc-unordered-containers (Old)
 and      /work/SRC/openSUSE:Factory/.ghc-unordered-containers.new (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "ghc-unordered-containers"

Fri Apr 14 13:38:59 2017 rev:10 rq:485170 version:0.2.8.0

Changes:
--------
--- 
/work/SRC/openSUSE:Factory/ghc-unordered-containers/ghc-unordered-containers.changes
        2017-01-18 21:44:36.088864755 +0100
+++ 
/work/SRC/openSUSE:Factory/.ghc-unordered-containers.new/ghc-unordered-containers.changes
   2017-04-14 13:39:00.604460824 +0200
@@ -1,0 +2,5 @@
+Mon Mar 27 12:41:23 UTC 2017 - [email protected]
+
+- Update to version 0.2.8.0 with cabal2obs.
+
+-------------------------------------------------------------------

Old:
----
  unordered-containers-0.2.7.2.tar.gz

New:
----
  unordered-containers-0.2.8.0.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ ghc-unordered-containers.spec ++++++
--- /var/tmp/diff_new_pack.wDMwpC/_old  2017-04-14 13:39:01.508333079 +0200
+++ /var/tmp/diff_new_pack.wDMwpC/_new  2017-04-14 13:39:01.512332514 +0200
@@ -19,7 +19,7 @@
 %global pkg_name unordered-containers
 %bcond_with tests
 Name:           ghc-%{pkg_name}
-Version:        0.2.7.2
+Version:        0.2.8.0
 Release:        0
 Summary:        Efficient hashing-based container types
 License:        BSD-3-Clause

++++++ unordered-containers-0.2.7.2.tar.gz -> 
unordered-containers-0.2.8.0.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/unordered-containers-0.2.7.2/CHANGES.md 
new/unordered-containers-0.2.8.0/CHANGES.md
--- old/unordered-containers-0.2.7.2/CHANGES.md 2016-12-24 04:26:14.000000000 
+0100
+++ new/unordered-containers-0.2.8.0/CHANGES.md 2017-03-18 00:38:19.000000000 
+0100
@@ -1,3 +1,13 @@
+## 0.2.8.0
+
+ * Add `Eq1/2`, `Show1/2`, `Read1` instances with `base-4.9`
+
+ * `Eq (HashSet a)` doesn't require `Hashable a` anymore, only `Eq a`.
+
+ * Add `Hashable1/2` with `hashable-1.2.6.0`
+
+ * Add `differenceWith` function.
+
 ## 0.2.7.2
 
  * Don't use -fregs-graphs
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/unordered-containers-0.2.7.2/Data/HashMap/Base.hs 
new/unordered-containers-0.2.8.0/Data/HashMap/Base.hs
--- old/unordered-containers-0.2.7.2/Data/HashMap/Base.hs       2016-12-24 
04:26:14.000000000 +0100
+++ new/unordered-containers-0.2.8.0/Data/HashMap/Base.hs       2017-03-18 
00:38:19.000000000 +0100
@@ -45,6 +45,7 @@
 
       -- * Difference and intersection
     , difference
+    , differenceWith
     , intersection
     , intersectionWith
     , intersectionWithKey
@@ -89,6 +90,7 @@
     , updateOrConcatWith
     , updateOrConcatWithKey
     , filterMapAux
+    , equalKeys
     ) where
 
 #if __GLASGOW_HASKELL__ < 710
@@ -125,7 +127,15 @@
 import qualified GHC.Exts as Exts
 #endif
 
+#if MIN_VERSION_base(4,9,0)
+import Data.Functor.Classes
+#endif
+
+#if MIN_VERSION_hashable(1,2,5)
+import qualified Data.Hashable.Lifted as H
+#endif
 
+-- | A set of values.  A set cannot contain duplicate values.
 ------------------------------------------------------------------------
 
 -- | Convenience function.  Compute a hash value for the given value.
@@ -203,6 +213,25 @@
 type Bitmap = Word
 type Shift  = Int
 
+#if MIN_VERSION_base(4,9,0)
+instance Show2 HashMap where
+    liftShowsPrec2 spk slk spv slv d m =
+        showsUnaryWith (liftShowsPrec sp sl) "fromList" d (toList m)
+      where
+        sp = liftShowsPrec2 spk slk spv slv
+        sl = liftShowList2 spk slk spv slv
+
+instance Show k => Show1 (HashMap k) where
+    liftShowsPrec = liftShowsPrec2 showsPrec showList
+
+instance (Eq k, Hashable k, Read k) => Read1 (HashMap k) where
+    liftReadsPrec rp rl = readsData $
+        readsUnaryWith (liftReadsPrec rp' rl') "fromList" fromList
+      where
+        rp' = liftReadsPrec rp rl
+        rl' = liftReadList rp rl
+#endif
+
 instance (Eq k, Hashable k, Read k, Read e) => Read (HashMap k e) where
     readPrec = parens $ prec 10 $ do
       Ident "fromList" <- lexP
@@ -218,26 +247,102 @@
 instance Traversable (HashMap k) where
     traverse f = traverseWithKey (const f)
 
+#if MIN_VERSION_base(4,9,0)
+instance Eq2 HashMap where
+    liftEq2 = equal
+
+instance Eq k => Eq1 (HashMap k) where
+    liftEq = equal (==)
+#endif
+
 instance (Eq k, Eq v) => Eq (HashMap k v) where
-    (==) = equal
+    (==) = equal (==) (==)
 
-equal :: (Eq k, Eq v) => HashMap k v -> HashMap k v -> Bool
-equal t1 t2 = go (toList' t1 []) (toList' t2 [])
+equal :: (k -> k' -> Bool) -> (v -> v' -> Bool)
+      -> HashMap k v -> HashMap k' v' -> Bool
+equal eqk eqv t1 t2 = go (toList' t1 []) (toList' t2 [])
   where
     -- If the two trees are the same, then their lists of 'Leaf's and
     -- 'Collision's read from left to right should be the same (modulo the
     -- order of elements in 'Collision').
 
     go (Leaf k1 l1 : tl1) (Leaf k2 l2 : tl2)
-      | k1 == k2 && l1 == l2
+      | k1 == k2 && leafEq l1 l2
+      = go tl1 tl2
+    go (Collision k1 ary1 : tl1) (Collision k2 ary2 : tl2)
+      | k1 == k2 && A.length ary1 == A.length ary2 &&
+        isPermutationBy leafEq (A.toList ary1) (A.toList ary2)
+      = go tl1 tl2
+    go [] [] = True
+    go _  _  = False
+
+    leafEq (L k v) (L k' v') = eqk k k' && eqv v v'
+
+-- Note: previous implemenation isPermutation = null (as // bs)
+-- was O(n^2) too.
+--
+-- This assumes lists are of equal length
+isPermutationBy :: (a -> b -> Bool) -> [a] -> [b] -> Bool
+isPermutationBy f = go
+  where
+    f' = flip f
+
+    go [] [] = True
+    go (x : xs) (y : ys)
+        | f x y     = go xs ys
+        | otherwise = go (deleteBy f' y xs) (deleteBy f x ys)
+    go [] (_ : _) = False
+    go (_ : _) [] = False
+
+-- Data.List.deleteBy :: (a -> a -> Bool) -> a -> [a] -> [a]
+deleteBy                :: (a -> b -> Bool) -> a -> [b] -> [b]
+deleteBy _  _ []        = []
+deleteBy eq x (y:ys)    = if x `eq` y then ys else y : deleteBy eq x ys
+
+-- Same as 'equal' but doesn't compare the values.
+equalKeys :: (k -> k' -> Bool) -> HashMap k v -> HashMap k' v' -> Bool
+equalKeys eq t1 t2 = go (toList' t1 []) (toList' t2 [])
+  where
+    go (Leaf k1 l1 : tl1) (Leaf k2 l2 : tl2)
+      | k1 == k2 && leafEq l1 l2
       = go tl1 tl2
     go (Collision k1 ary1 : tl1) (Collision k2 ary2 : tl2)
       | k1 == k2 && A.length ary1 == A.length ary2 &&
-        L.null (A.toList ary1 L.\\ A.toList ary2)
+        isPermutationBy leafEq (A.toList ary1) (A.toList ary2)
       = go tl1 tl2
     go [] [] = True
     go _  _  = False
 
+    leafEq (L k _) (L k' _) = eq k k'
+
+#if MIN_VERSION_hashable(1,2,5)
+instance H.Hashable2 HashMap where
+    liftHashWithSalt2 hk hv salt hm = go salt (toList' hm [])
+      where
+        -- go :: Int -> [HashMap k v] -> Int
+        go s [] = s
+        go s (Leaf _ l : tl)
+          = s `hashLeafWithSalt` l `go` tl
+        -- For collisions we hashmix hash value
+        -- and then array of values' hashes sorted
+        go s (Collision h a : tl)
+          = (s `H.hashWithSalt` h) `hashCollisionWithSalt` a `go` tl
+        go s (_ : tl) = s `go` tl
+
+        -- hashLeafWithSalt :: Int -> Leaf k v -> Int
+        hashLeafWithSalt s (L k v) = (s `hk` k) `hv` v
+
+        -- hashCollisionWithSalt :: Int -> A.Array (Leaf k v) -> Int
+        hashCollisionWithSalt s
+          = L.foldl' H.hashWithSalt s . arrayHashesSorted s
+
+        -- arrayHashesSorted :: Int -> A.Array (Leaf k v) -> [Int]
+        arrayHashesSorted s = L.sort . L.map (hashLeafWithSalt s) . A.toList
+
+instance (Hashable k) => H.Hashable1 (HashMap k) where
+    liftHashWithSalt = H.liftHashWithSalt2 H.hashWithSalt
+#endif
+
 instance (Hashable k, Hashable v) => Hashable (HashMap k v) where
     hashWithSalt salt hm = go salt (toList' hm [])
       where
@@ -256,13 +361,10 @@
 
         hashCollisionWithSalt :: Int -> A.Array (Leaf k v) -> Int
         hashCollisionWithSalt s
-          = L.foldl' H.hashWithSalt s . arrayHashesSorted
-
-        arrayHashesSorted :: A.Array (Leaf k v) -> [Int]
-        arrayHashesSorted = L.sort . L.map leafValueHash . A.toList
+          = L.foldl' H.hashWithSalt s . arrayHashesSorted s
 
-        leafValueHash :: Leaf k v -> Int
-        leafValueHash (L _ v) = H.hash v
+        arrayHashesSorted :: Int -> A.Array (Leaf k v) -> [Int]
+        arrayHashesSorted s = L.sort . L.map (hashLeafWithSalt s) . A.toList
 
   -- Helper to get 'Leaf's and 'Collision's as a list.
 toList' :: HashMap k v -> [HashMap k v] -> [HashMap k v]
@@ -833,6 +935,18 @@
                  _       -> m
 {-# INLINABLE difference #-}
 
+-- | /O(n*log m)/ Difference with a combining function. When two equal keys are
+-- encountered, the combining function is applied to the values of these keys.
+-- If it returns 'Nothing', the element is discarded (proper set difference). 
If
+-- it returns (@'Just' y@), the element is updated with a new value @y@.
+differenceWith :: (Eq k, Hashable k) => (v -> w -> Maybe v) -> HashMap k v -> 
HashMap k w -> HashMap k v
+differenceWith f a b = foldlWithKey' go empty a
+  where
+    go m k v = case lookup k b of
+                 Nothing -> insert k v m
+                 Just w  -> maybe m (\y -> insert k y m) (f v w)
+{-# INLINABLE differenceWith #-}
+
 -- | /O(n*log m)/ Intersection of two maps. Return elements of the first
 -- map for keys existing in the second.
 intersection :: (Eq k, Hashable k) => HashMap k v -> HashMap k w -> HashMap k v
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/unordered-containers-0.2.7.2/Data/HashMap/Lazy.hs 
new/unordered-containers-0.2.8.0/Data/HashMap/Lazy.hs
--- old/unordered-containers-0.2.7.2/Data/HashMap/Lazy.hs       2016-12-24 
04:26:14.000000000 +0100
+++ new/unordered-containers-0.2.8.0/Data/HashMap/Lazy.hs       2017-03-18 
00:38:19.000000000 +0100
@@ -64,6 +64,7 @@
 
       -- * Difference and intersection
     , difference
+    , differenceWith
     , intersection
     , intersectionWith
     , intersectionWithKey
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/unordered-containers-0.2.7.2/Data/HashMap/Strict.hs 
new/unordered-containers-0.2.8.0/Data/HashMap/Strict.hs
--- old/unordered-containers-0.2.7.2/Data/HashMap/Strict.hs     2016-12-24 
04:26:14.000000000 +0100
+++ new/unordered-containers-0.2.8.0/Data/HashMap/Strict.hs     2017-03-18 
00:38:19.000000000 +0100
@@ -64,6 +64,7 @@
 
       -- * Difference and intersection
     , difference
+    , differenceWith
     , intersection
     , intersectionWith
     , intersectionWithKey
@@ -98,9 +99,9 @@
 import qualified Data.HashMap.Array as A
 import qualified Data.HashMap.Base as HM
 import Data.HashMap.Base hiding (
-    alter, adjust, fromList, fromListWith, insert, insertWith, 
intersectionWith,
-    intersectionWithKey, map, mapWithKey, mapMaybe, mapMaybeWithKey, singleton,
-    update, unionWith, unionWithKey)
+    alter, adjust, fromList, fromListWith, insert, insertWith, differenceWith,
+    intersectionWith, intersectionWithKey, map, mapWithKey, mapMaybe,
+    mapMaybeWithKey, singleton, update, unionWith, unionWithKey)
 import Data.HashMap.Unsafe (runST)
 
 -- $strictness
@@ -394,6 +395,18 @@
 ------------------------------------------------------------------------
 -- * Difference and intersection
 
+-- | /O(n*log m)/ Difference with a combining function. When two equal keys are
+-- encountered, the combining function is applied to the values of these keys.
+-- If it returns 'Nothing', the element is discarded (proper set difference). 
If
+-- it returns (@'Just' y@), the element is updated with a new value @y@.
+differenceWith :: (Eq k, Hashable k) => (v -> w -> Maybe v) -> HashMap k v -> 
HashMap k w -> HashMap k v
+differenceWith f a b = foldlWithKey' go empty a
+  where
+    go m k v = case HM.lookup k b of
+                 Nothing -> insert k v m
+                 Just w  -> maybe m (\y -> insert k y m) (f v w)
+{-# INLINABLE differenceWith #-}
+
 -- | /O(n+m)/ Intersection of two maps. If a key occurs in both maps
 -- the provided function is used to combine the values from the two
 -- maps.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/unordered-containers-0.2.7.2/Data/HashSet.hs 
new/unordered-containers-0.2.8.0/Data/HashSet.hs
--- old/unordered-containers-0.2.7.2/Data/HashSet.hs    2016-12-24 
04:26:14.000000000 +0100
+++ new/unordered-containers-0.2.8.0/Data/HashSet.hs    2017-03-18 
00:38:19.000000000 +0100
@@ -74,7 +74,7 @@
 
 import Control.DeepSeq (NFData(..))
 import Data.Data hiding (Typeable)
-import Data.HashMap.Base (HashMap, foldrWithKey)
+import Data.HashMap.Base (HashMap, foldrWithKey, equalKeys)
 import Data.Hashable (Hashable(hashWithSalt))
 #if __GLASGOW_HASKELL__ >= 711
 import Data.Semigroup (Semigroup(..), Monoid(..))
@@ -93,6 +93,14 @@
 import qualified GHC.Exts as Exts
 #endif
 
+#if MIN_VERSION_base(4,9,0)
+import Data.Functor.Classes
+#endif
+
+#if MIN_VERSION_hashable(1,2,5)
+import qualified Data.Hashable.Lifted as H
+#endif
+
 -- | A set of values.  A set cannot contain duplicate values.
 newtype HashSet a = HashSet {
       asMap :: HashMap a ()
@@ -106,12 +114,15 @@
     rnf = rnf . asMap
     {-# INLINE rnf #-}
 
-instance (Hashable a, Eq a) => Eq (HashSet a) where
-    -- This performs two passes over the tree.
-    a == b = foldr f True b && size a == size b
-        where f i = (&& i `member` a)
+instance (Eq a) => Eq (HashSet a) where
+    HashSet a == HashSet b = equalKeys (==) a b
     {-# INLINE (==) #-}
 
+#if MIN_VERSION_base(4,9,0)
+instance Eq1 HashSet where
+    liftEq eq (HashSet a) (HashSet b) = equalKeys eq a b
+#endif
+
 instance Foldable.Foldable HashSet where
     foldr = Data.HashSet.foldr
     {-# INLINE foldr #-}
@@ -140,6 +151,12 @@
 
     readListPrec = readListPrecDefault
 
+#if MIN_VERSION_base(4,9,0)
+instance Show1 HashSet where
+    liftShowsPrec sp sl d m =
+        showsUnaryWith (liftShowsPrec sp sl) "fromList" d (toList m)
+#endif
+
 instance (Show a) => Show (HashSet a) where
     showsPrec d m = showParen (d > 10) $
       showString "fromList " . shows (toList m)
@@ -153,6 +170,11 @@
     dataTypeOf _   = hashSetDataType
     dataCast1 f    = gcast1 f
 
+#if MIN_VERSION_hashable(1,2,6)
+instance H.Hashable1 HashSet where
+    liftHashWithSalt h s = H.liftHashWithSalt2 h hashWithSalt s . asMap
+#endif
+
 instance (Hashable a) => Hashable (HashSet a) where
     hashWithSalt salt = hashWithSalt salt . asMap
 
@@ -204,7 +226,7 @@
 size = H.size . asMap
 {-# INLINE size #-}
 
--- | /O(min(n,W))/ Return 'True' if the given value is present in this
+-- | /O(log n)/ Return 'True' if the given value is present in this
 -- set, 'False' otherwise.
 member :: (Eq a, Hashable a) => a -> HashSet a -> Bool
 member a s = case H.lookup a (asMap s) of
@@ -212,12 +234,12 @@
                _      -> False
 {-# INLINABLE member #-}
 
--- | /O(min(n,W))/ Add the specified value to this set.
+-- | /O(log n)/ Add the specified value to this set.
 insert :: (Eq a, Hashable a) => a -> HashSet a -> HashSet a
 insert a = HashSet . H.insert a () . asMap
 {-# INLINABLE insert #-}
 
--- | /O(min(n,W))/ Remove the specified value from this set if
+-- | /O(log n)/ Remove the specified value from this set if
 -- present.
 delete :: (Eq a, Hashable a) => a -> HashSet a -> HashSet a
 delete a = HashSet . H.delete a . asMap
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/unordered-containers-0.2.7.2/tests/HashMapProperties.hs 
new/unordered-containers-0.2.8.0/tests/HashMapProperties.hs
--- old/unordered-containers-0.2.7.2/tests/HashMapProperties.hs 2016-12-24 
04:26:14.000000000 +0100
+++ new/unordered-containers-0.2.8.0/tests/HashMapProperties.hs 2017-03-18 
00:38:19.000000000 +0100
@@ -54,8 +54,9 @@
 pHashable xs is salt =
     x == y ==> hashWithSalt salt x === hashWithSalt salt y
   where
-    ys = shuffle is xs
-    x = HM.fromList xs
+    xs' = L.nubBy (\(k,_) (k',_) -> k == k') xs
+    ys = shuffle is xs'
+    x = HM.fromList xs'
     y = HM.fromList ys
     -- Shuffle the list using indexes in the second
     shuffle :: [Int] -> [a] -> [a]
@@ -162,6 +163,12 @@
 pDifference xs ys = M.difference (M.fromList xs) `eq_`
                     HM.difference (HM.fromList xs) $ ys
 
+pDifferenceWith :: [(Key, Int)] -> [(Key, Int)] -> Bool
+pDifferenceWith xs ys = M.differenceWith f (M.fromList xs) `eq_`
+                        HM.differenceWith f (HM.fromList xs) $ ys
+  where
+    f x y = if x == 0 then Nothing else Just (x - y)
+
 pIntersection :: [(Key, Int)] -> [(Key, Int)] -> Bool
 pIntersection xs ys = M.intersection (M.fromList xs) `eq_`
                       HM.intersection (HM.fromList xs) $ ys
@@ -283,6 +290,7 @@
       ]
     , testGroup "difference and intersection"
       [ testProperty "difference" pDifference
+      , testProperty "differenceWith" pDifferenceWith
       , testProperty "intersection" pIntersection
       , testProperty "intersectionWith" pIntersectionWith
       , testProperty "intersectionWithKey" pIntersectionWithKey
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/unordered-containers-0.2.7.2/tests/HashSetProperties.hs 
new/unordered-containers-0.2.8.0/tests/HashSetProperties.hs
--- old/unordered-containers-0.2.7.2/tests/HashSetProperties.hs 2016-12-24 
04:26:14.000000000 +0100
+++ new/unordered-containers-0.2.8.0/tests/HashSetProperties.hs 2017-03-18 
00:38:19.000000000 +0100
@@ -53,8 +53,9 @@
 pHashable xs is salt =
     x == y ==> hashWithSalt salt x === hashWithSalt salt y
   where
-    ys = shuffle is xs
-    x = S.fromList xs
+    xs' = L.nub xs
+    ys = shuffle is xs'
+    x = S.fromList xs'
     y = S.fromList ys
     shuffle idxs = L.map snd
                  . L.sortBy (comparing fst)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/unordered-containers-0.2.7.2/unordered-containers.cabal 
new/unordered-containers-0.2.8.0/unordered-containers.cabal
--- old/unordered-containers-0.2.7.2/unordered-containers.cabal 2016-12-24 
04:26:14.000000000 +0100
+++ new/unordered-containers-0.2.8.0/unordered-containers.cabal 2017-03-18 
00:38:19.000000000 +0100
@@ -1,5 +1,5 @@
 name:           unordered-containers
-version:        0.2.7.2
+version:        0.2.8.0
 synopsis:       Efficient hashing-based container types
 description:
   Efficient hashing-based container types.  The containers have been


Reply via email to