Hello community, here is the log from the commit of package ghc-hashable for openSUSE:Factory checked in at 2017-04-14 13:37:56 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/ghc-hashable (Old) and /work/SRC/openSUSE:Factory/.ghc-hashable.new (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "ghc-hashable" Fri Apr 14 13:37:56 2017 rev:11 rq:485129 version:1.2.6.0 Changes: -------- --- /work/SRC/openSUSE:Factory/ghc-hashable/ghc-hashable.changes 2017-03-14 10:04:49.079067071 +0100 +++ /work/SRC/openSUSE:Factory/.ghc-hashable.new/ghc-hashable.changes 2017-04-14 13:37:58.029304571 +0200 @@ -1,0 +2,5 @@ +Mon Mar 27 12:41:05 UTC 2017 - [email protected] + +- Update to version 1.2.6.0 revision 1 with cabal2obs. + +------------------------------------------------------------------- Old: ---- hashable-1.2.5.0.tar.gz New: ---- hashable-1.2.6.0.tar.gz hashable.cabal ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ ghc-hashable.spec ++++++ --- /var/tmp/diff_new_pack.yu9mof/_old 2017-04-14 13:38:00.592942254 +0200 +++ /var/tmp/diff_new_pack.yu9mof/_new 2017-04-14 13:38:00.596941688 +0200 @@ -19,15 +19,17 @@ %global pkg_name hashable %bcond_with tests Name: ghc-%{pkg_name} -Version: 1.2.5.0 +Version: 1.2.6.0 Release: 0 Summary: A class for types that can be converted to a hash value License: BSD-3-Clause Group: Development/Languages/Other Url: https://hackage.haskell.org/package/%{pkg_name} Source0: https://hackage.haskell.org/package/%{pkg_name}-%{version}/%{pkg_name}-%{version}.tar.gz +Source1: https://hackage.haskell.org/package/%{pkg_name}-%{version}/revision/1.cabal#/%{pkg_name}.cabal BuildRequires: ghc-Cabal-devel BuildRequires: ghc-bytestring-devel +BuildRequires: ghc-deepseq-devel BuildRequires: ghc-rpm-macros BuildRequires: ghc-text-devel BuildRoot: %{_tmppath}/%{name}-%{version}-build @@ -60,6 +62,7 @@ %prep %setup -q -n %{pkg_name}-%{version} +cp -p %{SOURCE1} %{pkg_name}.cabal %build %ifarch i586 ++++++ hashable-1.2.5.0.tar.gz -> hashable-1.2.6.0.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/hashable-1.2.5.0/CHANGES.md new/hashable-1.2.6.0/CHANGES.md --- old/hashable-1.2.5.0/CHANGES.md 2017-01-02 09:44:38.000000000 +0100 +++ new/hashable-1.2.6.0/CHANGES.md 2017-03-18 00:26:23.000000000 +0100 @@ -1,3 +1,9 @@ +## Version 1.2.6.0 + + * Add support for type-indexed `Typeable`. + + * Rework the `Generic` hashable for sums. + ## Version 1.2.5.0 * Add `Hashable1` and `Hashable2` diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/hashable-1.2.5.0/Data/Hashable/Class.hs new/hashable-1.2.6.0/Data/Hashable/Class.hs --- old/hashable-1.2.5.0/Data/Hashable/Class.hs 2017-01-02 09:44:38.000000000 +0100 +++ new/hashable-1.2.6.0/Data/Hashable/Class.hs 2017-03-18 00:26:23.000000000 +0100 @@ -1,5 +1,14 @@ {-# LANGUAGE BangPatterns, CPP, ForeignFunctionInterface, MagicHash, - ScopedTypeVariables, UnliftedFFITypes, DeriveDataTypeable #-} + ScopedTypeVariables, UnliftedFFITypes #-} + +#if __GLASGOW_HASKELL__ < 710 +{-# LANGUAGE DeriveDataTypeable #-} +#endif + +#if __GLASGOW_HASKELL__ >= 801 +{-# LANGUAGE PolyKinds #-} -- For TypeRep instances +#endif + #ifdef GENERICS {-# LANGUAGE DefaultSignatures, FlexibleContexts, GADTs, MultiParamTypeClasses, EmptyDataDecls #-} @@ -56,9 +65,9 @@ import Control.Applicative (Const(..)) import Control.Exception (assert) +import Control.DeepSeq (NFData(rnf)) import Data.Bits (shiftL, shiftR, xor) import qualified Data.ByteString as B -import qualified Data.ByteString.Internal as B import qualified Data.ByteString.Lazy as BL import qualified Data.ByteString.Unsafe as B import Data.Int (Int8, Int16, Int32, Int64) @@ -68,7 +77,6 @@ import qualified Data.Text.Array as TA import qualified Data.Text.Internal as T import qualified Data.Text.Lazy as TL -import Data.Typeable (Typeable, TypeRep) import Data.Version (Version(..)) import Data.Word (Word8, Word16, Word32, Word64) import Foreign.C (CString) @@ -78,7 +86,7 @@ import GHC.Base (ByteArray#) import GHC.Conc (ThreadId(..)) import GHC.Prim (ThreadId#) -import System.IO.Unsafe (unsafePerformIO) +import System.IO.Unsafe (unsafeDupablePerformIO) import System.Mem.StableName import Data.Unique (Unique, hashUnique) @@ -101,14 +109,17 @@ import GHC.Generics #endif -#if __GLASGOW_HASKELL__ >= 710 -import Data.Typeable (typeRepFingerprint) +#if __GLASGOW_HASKELL__ >= 801 +import Type.Reflection (typeRepFingerprint, Typeable, TypeRep, SomeTypeRep(..)) +import GHC.Fingerprint.Type(Fingerprint(..)) +#elif __GLASGOW_HASKELL__ >= 710 +import Data.Typeable (typeRepFingerprint, Typeable, TypeRep) import GHC.Fingerprint.Type(Fingerprint(..)) #elif __GLASGOW_HASKELL__ >= 702 -import Data.Typeable.Internal (TypeRep (..)) +import Data.Typeable.Internal (Typeable, TypeRep (..)) import GHC.Fingerprint.Type(Fingerprint(..)) #elif __GLASGOW_HASKELL__ >= 606 -import Data.Typeable (typeRepKey) +import Data.Typeable (typeRepKey, Typeable, TypeRep) #endif #if __GLASGOW_HASKELL__ >= 703 @@ -267,11 +278,10 @@ defaultLiftHashWithSalt :: (Hashable2 f, Hashable a) => (Int -> b -> Int) -> Int -> f a b -> Int defaultLiftHashWithSalt h = liftHashWithSalt2 hashWithSalt h --- Since we support a generic implementation of 'hashWithSalt' we +-- | Since we support a generic implementation of 'hashWithSalt' we -- cannot also provide a default implementation for that method for -- the non-generic instance use case. Instead we provide -- 'defaultHashWith'. - defaultHashWithSalt :: Hashable a => Int -> a -> Int defaultHashWithSalt salt x = salt `combine` hash x @@ -443,7 +453,7 @@ | isIEEE x = assert (sizeOf x >= sizeOf (0::Word32) && alignment x >= alignment (0::Word32)) $ - hash ((unsafePerformIO $ with x $ peek . castPtr) :: Word32) + hash ((unsafeDupablePerformIO $ with x $ peek . castPtr) :: Word32) | otherwise = hash (show x) hashWithSalt = defaultHashWithSalt @@ -452,7 +462,7 @@ | isIEEE x = assert (sizeOf x >= sizeOf (0::Word64) && alignment x >= alignment (0::Word64)) $ - hash ((unsafePerformIO $ with x $ peek . castPtr) :: Word64) + hash ((unsafeDupablePerformIO $ with x $ peek . castPtr) :: Word64) | otherwise = hash (show x) hashWithSalt = defaultHashWithSalt @@ -591,7 +601,7 @@ step (SP s l) x = SP (h s x) (l + 1) instance Hashable B.ByteString where - hashWithSalt salt bs = B.inlinePerformIO $ + hashWithSalt salt bs = unsafeDupablePerformIO $ B.unsafeUseAsCStringLen bs $ \(p, len) -> hashPtrWithSalt p (fromIntegral len) salt @@ -641,6 +651,7 @@ hash n = fromIntegral n hashWithSalt = defaultHashWithSalt +#if __GLASGOW_HASKELL__ < 801 -- | Compute the hash of a TypeRep, in various GHC versions we can do this quickly. hashTypeRep :: TypeRep -> Int {-# INLINE hashTypeRep #-} @@ -651,7 +662,7 @@ -- Fingerprint is just the MD5, so taking any Int from it is fine hashTypeRep (TypeRep (Fingerprint x _) _ _) = fromIntegral x #elif __GLASGOW_HASKELL__ >= 606 -hashTypeRep = B.inlinePerformIO . typeRepKey +hashTypeRep = unsafeDupablePerformIO . typeRepKey #else hashTypeRep = hash . show #endif @@ -661,6 +672,23 @@ hashWithSalt = defaultHashWithSalt {-# INLINE hash #-} +#else + +hashTypeRep :: Type.Reflection.TypeRep a -> Int +hashTypeRep tr = + let Fingerprint x _ = typeRepFingerprint tr in fromIntegral x + +instance Hashable Type.Reflection.SomeTypeRep where + hash (Type.Reflection.SomeTypeRep r) = hashTypeRep r + hashWithSalt = defaultHashWithSalt + {-# INLINE hash #-} + +instance Hashable (Type.Reflection.TypeRep a) where + hash = hashTypeRep + hashWithSalt = defaultHashWithSalt + {-# INLINE hash #-} +#endif + #if MIN_VERSION_base(4,8,0) instance Hashable Void where hashWithSalt _ = absurd @@ -855,6 +883,9 @@ instance F.Foldable Hashed where foldr f acc (Hashed a _) = f a acc +instance NFData a => NFData (Hashed a) where + rnf = rnf . unhashed + -- | 'Hashed' cannot be 'Functor' mapHashed :: Hashable b => (a -> b) -> Hashed a -> Hashed b mapHashed f (Hashed a _) = hashed (f a) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/hashable-1.2.5.0/Data/Hashable/Generic.hs new/hashable-1.2.6.0/Data/Hashable/Generic.hs --- old/hashable-1.2.5.0/Data/Hashable/Generic.hs 2017-01-02 09:44:38.000000000 +0100 +++ new/hashable-1.2.6.0/Data/Hashable/Generic.hs 2017-03-18 00:26:23.000000000 +0100 @@ -22,7 +22,6 @@ import Data.Hashable.Class import GHC.Generics - -- Type without constructors instance GHashable arity V1 where ghashWithSalt _ salt _ = hashWithSalt salt () @@ -52,25 +51,64 @@ instance (Hashable1 f, GHashable One g) => GHashable One (f :.: g) where ghashWithSalt targs salt = liftHashWithSalt (ghashWithSalt targs) salt . unComp1 -class GSum arity f where - hashSum :: HashArgs arity a -> Int -> Int -> Int -> f a -> Int - -instance (GSum arity a, GSum arity b, SumSize a, SumSize b) => GHashable arity (a :+: b) where - ghashWithSalt toHash salt = hashSum toHash salt 0 size - where size = unTagged (sumSize :: Tagged (a :+: b)) +class SumSize f => GSum arity f where + hashSum :: HashArgs arity a -> Int -> Int -> f a -> Int + -- hashSum args salt index value = ... + +-- [Note: Hashing a sum type] +-- +-- The tree structure is used in GHC.Generics to represent the sum (and +-- product) part of the generic represention of the type, e.g.: +-- +-- (C0 ... :+: C1 ...) :+: (C2 ... :+: (C3 ... :+: C4 ...)) +-- +-- The value constructed with C2 constructor is represented as (R1 (L1 ...)). +-- Yet, if we think that this tree is a flat (heterogenous) list: +-- +-- [C0 ..., C1 ..., C2 ..., C3 ..., C4... ] +-- +-- then the value constructed with C2 is a (dependent) pair (2, ...), and +-- hashing it is simple: +-- +-- salt `hashWithSalt` (2 :: Int) `hashWithSalt` ... +-- +-- This is what we do below. When drilling down the tree, we count how many +-- leafs are to the left (`index` variable). At the leaf case C1, we'll have an +-- actual index into the sum. +-- +-- This works well for balanced data. However for recursive types like: +-- +-- data Nat = Z | S Nat +-- +-- the `hashWithSalt salt (S (S (S Z)))` is +-- +-- salt `hashWithSalt` (1 :: Int) -- first S +-- `hashWithSalt` (1 :: Int) -- second S +-- `hashWithSalt` (1 :: Int) -- third S +-- `hashWithSalt` (0 :: Int) -- Z +-- `hashWithSalt` () -- U1 +-- +-- For that type the manual implementation: +-- +-- instance Hashable Nat where +-- hashWithSalt salt n = hashWithSalt salt (natToInteger n) +-- +-- would be better performing CPU and hash-quality wise (assuming that +-- Integer's Hashable is of high quality). +-- +instance (GSum arity a, GSum arity b) => GHashable arity (a :+: b) where + ghashWithSalt toHash salt = hashSum toHash salt 0 instance (GSum arity a, GSum arity b) => GSum arity (a :+: b) where - hashSum toHash !salt !code !size s = case s of - L1 x -> hashSum toHash salt code sizeL x - R1 x -> hashSum toHash salt (code + sizeL) sizeR x + hashSum toHash !salt !index s = case s of + L1 x -> hashSum toHash salt index x + R1 x -> hashSum toHash salt (index + sizeL) x where - sizeL = size `shiftR` 1 - sizeR = size - sizeL + sizeL = unTagged (sumSize :: Tagged a) {-# INLINE hashSum #-} instance GHashable arity a => GSum arity (C1 c a) where - -- hashSum toHash !salt !code _ (M1 x) = ghashWithSalt toHash (hashWithSalt salt code) x - hashSum toHash !salt !code _ (M1 x) = hashWithSalt salt (ghashWithSalt toHash code x) + hashSum toHash !salt !index (M1 x) = ghashWithSalt toHash (hashWithSalt salt index) x {-# INLINE hashSum #-} class SumSize f where diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/hashable-1.2.5.0/hashable.cabal new/hashable-1.2.6.0/hashable.cabal --- old/hashable-1.2.5.0/hashable.cabal 2017-01-02 09:44:38.000000000 +0100 +++ new/hashable-1.2.6.0/hashable.cabal 2017-03-18 00:26:23.000000000 +0100 @@ -1,5 +1,5 @@ Name: hashable -Version: 1.2.5.0 +Version: 1.2.6.0 Synopsis: A class for types that can be converted to a hash value Description: This package defines a class, 'Hashable', for types that can be converted to a hash value. This class @@ -46,8 +46,9 @@ Exposed-modules: Data.Hashable Data.Hashable.Lifted Other-modules: Data.Hashable.Class - Build-depends: base >= 4.0 && < 4.10, - bytestring >= 0.9 && < 0.11 + Build-depends: base >= 4.0 && < 4.11, + bytestring >= 0.9 && < 0.11, + deepseq >= 1.3 if impl(ghc) Build-depends: ghc-prim, text >= 0.11.0.5 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/hashable-1.2.5.0/tests/Regress.hs new/hashable-1.2.6.0/tests/Regress.hs --- old/hashable-1.2.5.0/tests/Regress.hs 2017-01-02 09:44:38.000000000 +0100 +++ new/hashable-1.2.6.0/tests/Regress.hs 2017-03-18 00:26:23.000000000 +0100 @@ -1,15 +1,47 @@ {-# LANGUAGE CPP #-} +{-# LANGUAGE DeriveGeneric #-} module Regress (regressions) where import qualified Test.Framework as F +import Test.Framework.Providers.HUnit (testCase) +import Test.HUnit ((@=?)) +import GHC.Generics (Generic) +import Data.List (nub) #ifdef HAVE_MMAP import qualified Regress.Mmap as Mmap #endif +import Data.Hashable + regressions :: [F.Test] -regressions = [] +regressions = [] ++ #ifdef HAVE_MMAP - ++ Mmap.regressions + Mmap.regressions ++ #endif + [ F.testGroup "Generic: sum of nullary constructors" + [ testCase "0" $ nullaryCase 0 S0 + , testCase "1" $ nullaryCase 1 S1 + , testCase "2" $ nullaryCase 2 S2 + , testCase "3" $ nullaryCase 3 S3 + , testCase "4" $ nullaryCase 4 S4 + ] + , testCase "Generic: Peano https://github.com/tibbe/hashable/issues/135" $ do + let ns = take 20 $ iterate S Z + let hs = map hash ns + hs @=? nub hs + ] + where + nullaryCase :: Int -> SumOfNullary -> IO () + nullaryCase n s = do + let salt = 42 + let expected = salt `hashWithSalt` n `hashWithSalt` () + let actual = hashWithSalt salt s + expected @=? actual + +data SumOfNullary = S0 | S1 | S2 | S3 | S4 deriving (Generic) +instance Hashable SumOfNullary + +data Nat = Z | S Nat deriving (Generic) +instance Hashable Nat ++++++ hashable.cabal ++++++ Name: hashable Version: 1.2.6.0 x-revision: 1 Synopsis: A class for types that can be converted to a hash value Description: This package defines a class, 'Hashable', for types that can be converted to a hash value. This class exists for the benefit of hashing-based data structures. The package provides instances for basic types and a way to combine hash values. Homepage: http://github.com/tibbe/hashable License: BSD3 License-file: LICENSE Author: Milan Straka <[email protected]> Johan Tibell <[email protected]> Maintainer: [email protected] bug-reports: https://github.com/tibbe/hashable/issues Stability: Provisional Category: Data Build-type: Simple Cabal-version: >=1.8 -- tests/Properties.hs shouldn't have to go here, but the source files -- for the test-suite stanzas don't get picked up by `cabal sdist`. Extra-source-files: CHANGES.md, README.md, tests/Properties.hs, benchmarks/Benchmarks.hs, benchmarks/cbits/*.c, benchmarks/cbits/*.h Flag integer-gmp Description: Are we using integer-gmp to provide fast Integer instances? Default: True Flag sse2 Description: Do we want to assume that a target supports SSE 2? Default: True Manual: True Flag sse41 Description: Do we want to assume that a target supports SSE 4.1? Default: False Manual: True Flag examples Description: Build example modules Default: False Manual: True Library Exposed-modules: Data.Hashable Data.Hashable.Lifted Other-modules: Data.Hashable.Class Build-depends: base >= 4.4 && < 4.11, bytestring >= 0.9 && < 0.11, deepseq >= 1.3 if impl(ghc) Build-depends: ghc-prim, text >= 0.11.0.5 if impl(ghc) && flag(integer-gmp) Build-depends: integer-gmp >= 0.2 if impl(ghc >= 7.2.1) CPP-Options: -DGENERICS Other-modules: Data.Hashable.Generic C-sources: cbits/fnv.c Ghc-options: -Wall if impl(ghc >= 6.8) Ghc-options: -fwarn-tabs else c-sources: cbits/getRandomBytes.c other-modules: Data.Hashable.RandomSource if os(windows) extra-libraries: advapi32 Test-suite tests Type: exitcode-stdio-1.0 Hs-source-dirs: tests Main-is: Main.hs Other-modules: Properties Regress Build-depends: base >= 4.0 && < 5.0, bytestring, ghc-prim, hashable, test-framework >= 0.3.3, test-framework-hunit, test-framework-quickcheck2 >= 0.2.9, HUnit, QuickCheck >= 2.4.0.1, random >= 1.0 && < 1.2, text >= 0.11.0.5 if !os(windows) Build-depends: unix CPP-options: -DHAVE_MMAP Other-modules: Regress.Mmap Ghc-options: -Wall -fno-warn-orphans if impl(ghc >= 7.2.1) CPP-Options: -DGENERICS benchmark benchmarks -- We cannot depend on the hashable library directly as that creates -- a dependency cycle. hs-source-dirs: . benchmarks main-is: Benchmarks.hs other-modules: Data.Hashable Data.Hashable.Class Data.Hashable.RandomSource Data.Hashable.SipHash type: exitcode-stdio-1.0 build-depends: base, bytestring, criterion >= 1.0, ghc-prim, siphash, text if impl(ghc) Build-depends: ghc-prim, text >= 0.11.0.5 if impl(ghc) && flag(integer-gmp) Build-depends: integer-gmp >= 0.2 if impl(ghc >= 7.2.1) CPP-Options: -DGENERICS include-dirs: benchmarks/cbits includes: siphash.h c-sources: benchmarks/cbits/inthash.c benchmarks/cbits/siphash.c benchmarks/cbits/wang.c cbits/fnv.c if (arch(i386) || arch(x86_64)) && flag(sse2) cpp-options: -DHAVE_SSE2 c-sources: benchmarks/cbits/siphash-sse2.c if flag(sse41) cpp-options: -DHAVE_SSE41 c-sources: benchmarks/cbits/siphash-sse41.c Ghc-options: -Wall -O2 if impl(ghc >= 6.8) Ghc-options: -fwarn-tabs else c-sources: cbits/getRandomBytes.c other-modules: Data.Hashable.RandomSource if os(windows) extra-libraries: advapi32 Executable hashable-examples if flag(examples) build-depends: base, hashable else buildable: False hs-source-dirs: examples main-is: Main.hs source-repository head type: git location: https://github.com/tibbe/hashable.git
