instant-hashable-0.2: src/lib/Generics/Instant/Functions/Hashable.hs
{-# LANGUAGE BangPatterns #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE TypeOperators #-}
{-# LANGUAGE PolyKinds #-}
{-# LANGUAGE UndecidableInstances #-}
module Generics.Instant.Functions.Hashable
( -- $defaults
ghashWithSaltDefault
, RepGHashable
-- * Internals
, GHashable(..)
) where
import Data.Hashable (Hashable(hashWithSalt))
import Generics.Instant
--------------------------------------------------------------------------------
-- $defaults
--
-- You can use 'ghashWithSaltDefault' as your generic 'hashWithSalt' for any
-- 'Representable' type as follows:
--
-- @
-- instance 'Hashable' MyType where hashWithSalt = 'ghashWithSaltDefault'
-- @
ghashWithSaltDefault :: (Representable a, GHashable (Rep a)) => Int -> a -> Int
ghashWithSaltDefault = \s a -> ghashWithSalt s (from a)
{-# INLINABLE ghashWithSaltDefault #-}
-- | @'RepGHashable'@ is simply a synonym for
-- @('Representable' a, 'GHashable' ('Rep' a))@ with the convenient
-- kind @(* -> 'GHC.Exts.Constraint')@
class (Representable a, GHashable (Rep a)) => RepGHashable a
instance (Representable a, GHashable (Rep a)) => RepGHashable a
--------------------------------------------------------------------------------
class GHashable a where
ghashWithSalt :: Int -> a -> Int
instance GHashable Z where
ghashWithSalt _ _ = error
"Generics.Instant.Functions.Hashable.GHashable Z ghashWithSalt - impossible"
instance GHashable U where
ghashWithSalt s U = hashWithSalt s ()
{-# INLINABLE ghashWithSalt #-}
instance GHashable a => GHashable (CEq c p q a) where
ghashWithSalt s (C a) = ghashWithSalt s a
{-# INLINABLE ghashWithSalt #-}
instance (GHashable a, GHashable b) => GHashable (a :*: b) where
ghashWithSalt s (a :*: b) = ghashWithSalt (ghashWithSalt s a) b
{-# INLINABLE ghashWithSalt #-}
instance (GHashable a, GHashable b) => GHashable (a :+: b) where
ghashWithSalt s lr = 0 `hashWithSalt` case lr of
L a -> Left (ghashWithSalt s a)
R b -> Right (ghashWithSalt s b)
{-# INLINABLE ghashWithSalt #-}
instance Hashable a => GHashable (Var a) where
ghashWithSalt s (Var a) = hashWithSalt s a
{-# INLINABLE ghashWithSalt #-}
instance Hashable a => GHashable (Rec a) where
ghashWithSalt s (Rec a) = hashWithSalt s a
{-# INLINABLE ghashWithSalt #-}