content: {-|
  Module      : What4.Utils.IncrHash
  Copyright   : (c) Galois Inc, 2019-2020
  License     : BSD3
  Maintainer  : rdockins@galois.com
  
  A basic datatype for incremental hashing which
  supports a monoid instance.  Currently this is
  simply implemented as bitwise xor for simplicity.
  
  If we later wish to experiment with other incremenal hash
  algorithms, this module abstracts over the implementation
  details.
  -}
  
  module What4.Utils.IncrHash
  ( IncrHash
  , mkIncrHash
  , toIncrHash
  , toIncrHashWithSalt
  ) where
  
  import Data.Bits
  import Data.Hashable
  
  newtype IncrHash = IncrHash Int
   deriving (Eq,Ord)
  
  instance Semigroup IncrHash where
    IncrHash x <> IncrHash y = IncrHash (x `xor` y)
  
  instance Monoid IncrHash where
    mempty = IncrHash 0
    mappend = (<>)
  
  mkIncrHash :: Int -> IncrHash
  mkIncrHash = IncrHash
  
  toIncrHash :: Hashable a => a -> IncrHash
  toIncrHash = IncrHash . hash
  
  toIncrHashWithSalt :: Hashable a => Int -> a -> IncrHash
  toIncrHashWithSalt s a = IncrHash (hashWithSalt s a)
  
  instance Hashable IncrHash where
    hashWithSalt s (IncrHash h) = hashWithSalt s h
  