{-# LANGUAGE DeriveGeneric #-} {-# LANGUAGE TypeApplications #-} -- | Standard 'Spec's for 'Hashable' instances. -- -- You will need @TypeApplications@ to use these. module Test.Validity.HashableSpec where import Data.GenValidity import Data.Hashable import GHC.Generics import Test.Hspec import Test.Validity.Hashable import Test.Validity.Utils spec :: Spec spec = do hashableSpec @Rational hashableSpec @Double hashableSpec @Int hashableSpecOnArbitrary @Int hashableSpec @HashableValid failsBecause "Two equal elements aren't hashed to the same value!" $ hashableSpec @HashableInvalid newtype HashableValid = HashableValid Int deriving (Show, Generic) hT :: Int -- Number used in the definition of HashableValid hT = 7 instance Eq HashableValid where (==) (HashableValid x) (HashableValid y) = (x `mod` hT) == (y `mod` hT) instance Hashable HashableValid where hashWithSalt n (HashableValid a) = (int ^ expo) `mod` hT where int = 1 + (a `mod` hT) expo = 1 + (n `mod` hT) instance Validity HashableValid instance GenValid HashableValid newtype HashableInvalid = HashableInvalid Int deriving (Show, Generic) hF :: Int -- Numbers used in the definition of HashableInvalid hF = 8 hM :: Int hM = 3 instance Eq HashableInvalid where (==) (HashableInvalid x) (HashableInvalid y) = (x `mod` hF) == (y `mod` hF) instance Hashable HashableInvalid where hashWithSalt n (HashableInvalid a) = (int ^ expo) `mod` hM where int = 1 + (a `mod` hM) expo = 1 + (n `mod` hM) instance Validity HashableInvalid instance GenValid HashableInvalid