packages feed

hashable 1.3.5.0 → 1.4.0.0

raw patch · 7 files changed

+154/−42 lines, 7 filesdep +base-orphansdep +functor-classes-compatdep +ghc-bignum-orphansdep ~basedep ~containersdep ~ghc-bignumPVP ok

version bump matches the API change (PVP)

Dependencies added: base-orphans, functor-classes-compat, ghc-bignum-orphans, transformers, transformers-compat

Dependency ranges changed: base, containers, ghc-bignum

API changes (from Hackage documentation)

+ Data.Hashable: hashedHash :: Hashed a -> Int
- Data.Hashable: class Hashable a
+ Data.Hashable: class Eq a => Hashable a
- Data.Hashable.Lifted: class Hashable1 t
+ Data.Hashable.Lifted: class Eq1 t => Hashable1 t
- Data.Hashable.Lifted: class Hashable2 t
+ Data.Hashable.Lifted: class Eq2 t => Hashable2 t

Files

CHANGES.md view
@@ -1,5 +1,14 @@ See also https://pvp.haskell.org/faq +## Version 1.4.0.0++ * `Eq` is now a superclass of `Hashable`.+   Also `Eq1` is a superclass of `Hashable1` and `Eq2` is a superclass of `Hashable2`+   when exists.++ * Remove `Hashable1 Fixed` instance+ * Remove `Hashable1 Semi.Min/Max/...` instances as they don't have `Eq1` instance.+ ## Version 1.3.5.0   * Add `Solo` instance (base-4.15+, GHC-9+)
examples/Main.hs view
@@ -6,12 +6,12 @@ data Foo   = Foo1 Int Char Bool   | Foo2 String ()-  deriving (Generic)+  deriving (Eq, Generic)  instance Hashable Foo  data Bar = Bar Double Float-  deriving (Generic)+  deriving (Eq, Generic)  instance Hashable Bar @@ -31,6 +31,8 @@ -- Higher Rank Hashable Examples -- ----------------------------------- +{- TODO:+ newtype WriterT w m a = WriterT { runWriterT :: m (a, w) } data Free f a = Pure a | Free (f (Free f a)) @@ -47,4 +49,4 @@     hashWithSalt = hashWithSalt1 instance (Hashable1 f, Hashable a) => Hashable (Free f a) where     hashWithSalt = hashWithSalt1-+-}
hashable.cabal view
@@ -1,6 +1,6 @@ cabal-version:      1.12 name:               hashable-version:            1.3.5.0+version:            1.4.0.0 synopsis:           A class for types that can be converted to a hash value description:   This package defines a class, 'Hashable', for types that@@ -41,8 +41,8 @@  extra-source-files:   CHANGES.md-  README.md   include/HsHashable.h+  README.md  flag integer-gmp   description:@@ -61,6 +61,11 @@   manual:      True   default:     False +flag containers+  description: 'containers >= 0.5.9.1'+  manual:      False+  default:     True+ library   exposed-modules:     Data.Hashable@@ -69,24 +74,31 @@    other-modules:     Data.Hashable.Class+    Data.Hashable.Generic.Instances     Data.Hashable.Imports     Data.Hashable.LowLevel-    Data.Hashable.Generic.Instances    c-sources:        cbits/fnv.c   include-dirs:     include   hs-source-dirs:   src   build-depends:-      base        >=4.5  && <4.17-    , bytestring  >=0.9  && <0.12+      base        >=4.5     && <4.17+    , bytestring  >=0.9     && <0.12     , containers  >=0.4.2.1 && <0.7-    , deepseq     >=1.3  && <1.5+    , deepseq     >=1.3     && <1.5     , ghc-prim-    , text        >=0.12 && <1.3+    , text        >=0.12    && <1.3 +  if !impl(ghc >=9.2)+    build-depends: base-orphans >=0.8.6++  -- Integer internals   if impl(ghc >=9)-    build-depends: ghc-bignum ==1.0.* || ==1.2.*+    build-depends: ghc-bignum >=1.0 && <1.1 || >=1.2 && <1.3 +    if !impl(ghc >=9.2)+      build-depends: ghc-bignum-orphans >=0.1 && <0.2+   else     if flag(integer-gmp)       build-depends: integer-gmp >=0.4 && <1.1@@ -95,6 +107,11 @@       -- this is needed for the automatic flag to be well-balanced       build-depends: integer-simple +  if !impl(ghc >=8)+    build-depends:+        transformers         >=0.3   && <0.7+      , transformers-compat  >=0.7.1 && <0.8+   if (flag(random-initial-seed) && impl(ghc))     cpp-options: -DHASHABLE_RANDOM_SEED=1 @@ -103,6 +120,13 @@      else       c-sources: cbits-unix/init.c++  if flag(containers)+    build-depends: containers >=0.5.9.1++  else+    build-depends: containers <0.5.9.1+    build-depends: functor-classes-compat >=2 && <2.1    default-language: Haskell2010   other-extensions:
src/Data/Hashable.hs view
@@ -63,6 +63,7 @@     -- * Caching hashes     , Hashed     , hashed+    , hashedHash     , unhashed     , mapHashed     , traverseHashed
src/Data/Hashable/Class.hs view
@@ -56,6 +56,7 @@     -- * Caching hashes     , Hashed     , hashed+    , hashedHash     , unhashed     , mapHashed     , traverseHashed@@ -168,10 +169,24 @@ #endif #endif +import Data.Functor.Classes (Eq1(..),Ord1(..),Show1(..))++-- Whether we have lifted classes, in particular, Eq2+#ifndef MIN_VERSION_transformers+#define LIFTED_FUNCTOR_CLASSES 1+#else+#if !(MIN_VERSION_transformers(0,4,0) && !MIN_VERSION_transformers(0,5,0))+#define LIFTED_FUNCTOR_CLASSES 1+#endif+#endif++#ifdef LIFTED_FUNCTOR_CLASSES+import Data.Functor.Classes (Eq2)+#endif+ #if MIN_VERSION_base(4,9,0) import qualified Data.List.NonEmpty as NE import Data.Semigroup-import Data.Functor.Classes (Eq1(..),Ord1(..),Show1(..),showsUnaryWith)  import Data.Functor.Compose (Compose(..)) import qualified Data.Functor.Product as FP@@ -195,6 +210,26 @@ import Data.Hashable.Imports import Data.Hashable.LowLevel +#ifdef VERSION_base_orphans+import Data.Orphans ()+#endif++#ifdef VERSION_transformers_compat+import Control.Monad.Trans.Instances ()+#endif++#ifdef VERSION_ghc_bignum_orphans+import GHC.Num.Orphans ()+#endif++#ifdef VERSION_functor_classes_compat+import Data.Map.Functor.Classes ()+import Data.Set.Functor.Classes ()+import Data.IntMap.Functor.Classes ()+import Data.Sequence.Functor.Classes ()+import Data.Tree.Functor.Classes ()+#endif+ #include "MachDeps.h"  infixl 0 `hashWithSalt`@@ -213,7 +248,7 @@ -- If you are looking for 'Hashable' instance in @time@ package, -- check [time-compat](https://hackage.haskell.org/package/time-compat) ---class Hashable a where+class Eq a => Hashable a where     -- | Return a hash value for the argument, using the given salt.     --     -- The general contract of 'hashWithSalt' is:@@ -270,7 +305,7 @@ class GHashable arity f where     ghashWithSalt :: HashArgs arity a -> Int -> f a -> Int -class Hashable1 t where+class Eq1 t => Hashable1 t where     -- | Lift a hashing function through the type constructor.     liftHashWithSalt :: (Int -> a -> Int) -> Int -> t a -> Int @@ -285,7 +320,11 @@ genericLiftHashWithSalt = \h salt -> ghashWithSalt (HashArgs1 h) salt . from1 {-# INLINE genericLiftHashWithSalt #-} +#if LIFTED_FUNCTOR_CLASSES+class Eq2 t => Hashable2 t where+#else class Hashable2 t where+#endif     -- | Lift a hashing function through the binary type constructor.     liftHashWithSalt2 :: (Int -> a -> Int) -> (Int -> b -> Int) -> Int -> t a b -> Int @@ -588,8 +627,11 @@     hash (a1, a2, a3, a4, a5) =         hash a1 `hashWithSalt` a2 `hashWithSalt` a3         `hashWithSalt` a4 `hashWithSalt` a5-    hashWithSalt = hashWithSalt1+    hashWithSalt s (a1, a2, a3, a4, a5) =+        s `hashWithSalt` a1 `hashWithSalt` a2 `hashWithSalt` a3+        `hashWithSalt` a4 `hashWithSalt` a5 +{- instance (Hashable a1, Hashable a2, Hashable a3,           Hashable a4) => Hashable1 ((,,,,) a1 a2 a3 a4) where     liftHashWithSalt = defaultLiftHashWithSalt@@ -599,15 +641,18 @@     liftHashWithSalt2 h1 h2 s (a1, a2, a3, a4, a5) =       (s `hashWithSalt` a1 `hashWithSalt` a2          `hashWithSalt` a3) `h1` a4 `h2` a5-+-}  instance (Hashable a1, Hashable a2, Hashable a3, Hashable a4, Hashable a5,           Hashable a6) => Hashable (a1, a2, a3, a4, a5, a6) where     hash (a1, a2, a3, a4, a5, a6) =         hash a1 `hashWithSalt` a2 `hashWithSalt` a3         `hashWithSalt` a4 `hashWithSalt` a5 `hashWithSalt` a6-    hashWithSalt = hashWithSalt1+    hashWithSalt s (a1, a2, a3, a4, a5, a6) =+        s `hashWithSalt` a1 `hashWithSalt` a2 `hashWithSalt` a3+        `hashWithSalt` a4 `hashWithSalt` a5 `hashWithSalt` a6 +{- instance (Hashable a1, Hashable a2, Hashable a3, Hashable a4,           Hashable a5) => Hashable1 ((,,,,,) a1 a2 a3 a4 a5) where     liftHashWithSalt = defaultLiftHashWithSalt@@ -617,7 +662,7 @@     liftHashWithSalt2 h1 h2 s (a1, a2, a3, a4, a5, a6) =       (s `hashWithSalt` a1 `hashWithSalt` a2 `hashWithSalt` a3          `hashWithSalt` a4) `h1` a5 `h2` a6-+-}  instance (Hashable a1, Hashable a2, Hashable a3, Hashable a4, Hashable a5,           Hashable a6, Hashable a7) =>@@ -629,6 +674,7 @@         s `hashWithSalt` a1 `hashWithSalt` a2 `hashWithSalt` a3         `hashWithSalt` a4 `hashWithSalt` a5 `hashWithSalt` a6 `hashWithSalt` a7 +{- instance (Hashable a1, Hashable a2, Hashable a3, Hashable a4, Hashable a5, Hashable a6) => Hashable1 ((,,,,,,) a1 a2 a3 a4 a5 a6) where     liftHashWithSalt = defaultLiftHashWithSalt @@ -637,6 +683,7 @@     liftHashWithSalt2 h1 h2 s (a1, a2, a3, a4, a5, a6, a7) =       (s `hashWithSalt` a1 `hashWithSalt` a2 `hashWithSalt` a3          `hashWithSalt` a4 `hashWithSalt` a5) `h1` a6 `h2` a7+-}  instance Hashable (StableName a) where     hash = hashStableName@@ -792,15 +839,14 @@ #if MIN_VERSION_base(4,7,0) instance Hashable (Fixed a) where     hashWithSalt salt (MkFixed i) = hashWithSalt salt i--- Using hashWithSalt1 would cause needless constraint-instance Hashable1 Fixed where-    liftHashWithSalt _ salt (MkFixed i) = hashWithSalt salt i #else instance Hashable (Fixed a) where     hashWithSalt salt x = hashWithSalt salt (unsafeCoerce x :: Integer) #endif + #if MIN_VERSION_base(4,8,0)+-- TODO: make available on all base instance Hashable a => Hashable (Identity a) where     hashWithSalt = hashWithSalt1 instance Hashable1 Identity where@@ -838,15 +884,9 @@ instance Hashable a => Hashable (Min a) where     hashWithSalt p (Min a) = hashWithSalt p a --- | @since 1.3.1.0-instance Hashable1 Min where liftHashWithSalt h salt (Min a) = h salt a- instance Hashable a => Hashable (Max a) where     hashWithSalt p (Max a) = hashWithSalt p a --- | @since 1.3.1.0-instance Hashable1 Max where liftHashWithSalt h salt (Max a) = h salt a- -- | __Note__: Prior to @hashable-1.3.0.0@ the hash computation included the second argument of 'Arg' which wasn't consistent with its 'Eq' instance. -- -- @since 1.3.0.0@@ -856,33 +896,49 @@ instance Hashable a => Hashable (First a) where     hashWithSalt p (First a) = hashWithSalt p a --- | @since 1.3.1.0-instance Hashable1 First where liftHashWithSalt h salt (First a) = h salt a  instance Hashable a => Hashable (Last a) where     hashWithSalt p (Last a) = hashWithSalt p a --- | @since 1.3.1.0-instance Hashable1 Last where liftHashWithSalt h salt (Last a) = h salt a  instance Hashable a => Hashable (WrappedMonoid a) where     hashWithSalt p (WrapMonoid a) = hashWithSalt p a --- | @since 1.3.1.0-instance Hashable1 WrappedMonoid where liftHashWithSalt h salt (WrapMonoid a) = h salt a  #if !MIN_VERSION_base(4,16,0) instance Hashable a => Hashable (Option a) where     hashWithSalt p (Option a) = hashWithSalt p a +#endif++-- TODO: this instance is removed as there isn't Eq1 Min/Max, ...++#if 0 -- | @since 1.3.1.0-instance Hashable1 Option where liftHashWithSalt h salt (Option a) = liftHashWithSalt h salt a+-- instance Hashable1 Min where liftHashWithSalt h salt (Min a) = h salt a++-- | @since 1.3.1.0+-- instance Hashable1 Max where liftHashWithSalt h salt (Max a) = h salt a++-- | @since 1.3.1.0+-- instance Hashable1 First where liftHashWithSalt h salt (First a) = h salt a++-- | @since 1.3.1.0+-- instance Hashable1 Last where liftHashWithSalt h salt (Last a) = h salt a+++-- | @since 1.3.1.0+-- instance Hashable1 WrappedMonoid where liftHashWithSalt h salt (WrapMonoid a) = h salt a++-- | @since 1.3.1.0+-- instance Hashable1 Option where liftHashWithSalt h salt (Option a) = liftHashWithSalt h salt a #endif #endif  -- instances for @Data.Functor.{Product,Sum,Compose}@, present -- in base-4.9 and onward. #if MIN_VERSION_base(4,9,0)+ -- | In general, @hash (Compose x) ≠ hash x@. However, @hashWithSalt@ satisfies -- its variant of this equivalence. instance (Hashable1 f, Hashable1 g, Hashable a) => Hashable (Compose f g a) where@@ -917,6 +973,12 @@ unhashed :: Hashed a -> a unhashed (Hashed a _) = a +-- | 'hash' has 'Eq' requirement.+--+-- @since 1.4.0.0+hashedHash :: Hashed a -> Int+hashedHash (Hashed _ h) = h+ -- | Uses precomputed hash to detect inequality faster instance Eq a => Eq (Hashed a) where   Hashed a ha == Hashed b hb = ha == hb && a == b@@ -928,10 +990,11 @@   showsPrec d (Hashed a _) = showParen (d > 10) $     showString "hashed" . showChar ' ' . showsPrec 11 a -instance Hashable (Hashed a) where+instance Eq a => Hashable (Hashed a) where   hashWithSalt = defaultHashWithSalt-  hash (Hashed _ h) = h+  hash = hashedHash + -- This instance is a little unsettling. It is unusal for -- 'liftHashWithSalt' to ignore its first argument when a -- value is actually available for it to work on.@@ -955,9 +1018,17 @@ traverseHashed :: (Hashable b, Functor f) => (a -> f b) -> Hashed a -> f (Hashed b) traverseHashed f (Hashed a _) = fmap hashed (f a) +#if MIN_VERSION_base(4,9,0)+#define LIFTED_FUNCTOR_CLASSES 1+#elif defined(MIN_VERSION_transformers)+#if !(MIN_VERSION_transformers(0,4,0)) || MIN_VERSION_transformers(0,5,0)+#define LIFTED_FUNCTOR_CLASSES 1+#endif+#endif+ -- instances for @Data.Functor.Classes@ higher rank typeclasses -- in base-4.9 and onward.-#if MIN_VERSION_base(4,9,0)+#if LIFTED_FUNCTOR_CLASSES instance Eq1 Hashed where   liftEq f (Hashed a ha) (Hashed b hb) = ha == hb && f a b @@ -965,7 +1036,12 @@   liftCompare f (Hashed a _) (Hashed b _) = f a b  instance Show1 Hashed where-  liftShowsPrec sp _ d (Hashed a _) = showsUnaryWith sp "hashed" d a+  liftShowsPrec sp _ d (Hashed a _) = showParen (d > 10) $+    showString "hashed " . sp 11 a+#else+instance Eq1 Hashed where eq1 = (==)+instance Ord1 Hashed where compare1 = compare+instance Show1 Hashed where showsPrec1 = showsPrec #endif  -------------------------------------------------------------------------------
tests/Properties.hs view
@@ -154,7 +154,7 @@ -- Generics  data Product2 a b = Product2 a b-                    deriving (Generic)+                    deriving (Eq, Generic)  instance (Arbitrary a, Arbitrary b) => Arbitrary (Product2 a b) where     arbitrary = Product2 `liftM` arbitrary `ap` arbitrary@@ -162,7 +162,7 @@ instance (Hashable a, Hashable b) => Hashable (Product2 a b)  data Product3 a b c = Product3 a b c-                    deriving (Generic)+                    deriving (Eq, Generic)  instance (Arbitrary a, Arbitrary b, Arbitrary c) =>     Arbitrary (Product3 a b c) where
tests/Regress.hs view
@@ -100,8 +100,8 @@         let actual = hashWithSalt salt s         expected @=? actual -data SumOfNullary = S0 | S1 | S2 | S3 | S4 deriving (Generic)+data SumOfNullary = S0 | S1 | S2 | S3 | S4 deriving (Eq, Generic) instance Hashable SumOfNullary -data Nat = Z | S Nat deriving (Generic)+data Nat = Z | S Nat deriving (Eq, Generic) instance Hashable Nat