{-# LANGUAGE BangPatterns, FlexibleInstances, KindSignatures,
ScopedTypeVariables, TypeOperators,
MultiParamTypeClasses, GADTs, FlexibleContexts #-}
{-# OPTIONS_GHC -fno-warn-orphans #-}
{-# LANGUAGE Trustworthy #-}
module Data.Hashable.Generic.Instances () where
import Data.Hashable.Class
import GHC.Generics
import Data.Kind (Type)
instance GHashable arity V1 where
ghashWithSalt :: forall a. HashArgs arity a -> Int -> V1 a -> Int
ghashWithSalt HashArgs arity a
_ Int
salt V1 a
_ = forall a. Hashable a => Int -> a -> Int
hashWithSalt Int
salt ()
instance GHashable arity U1 where
ghashWithSalt :: forall a. HashArgs arity a -> Int -> U1 a -> Int
ghashWithSalt HashArgs arity a
_ Int
salt U1 a
U1 = forall a. Hashable a => Int -> a -> Int
hashWithSalt Int
salt ()
instance (GHashable arity a, GHashable arity b) => GHashable arity (a :*: b) where
ghashWithSalt :: forall a. HashArgs arity a -> Int -> (:*:) a b a -> Int
ghashWithSalt HashArgs arity a
toHash Int
salt (a a
x :*: b a
y) =
(forall arity (f :: * -> *) a.
GHashable arity f =>
HashArgs arity a -> Int -> f a -> Int
ghashWithSalt HashArgs arity a
toHash (forall arity (f :: * -> *) a.
GHashable arity f =>
HashArgs arity a -> Int -> f a -> Int
ghashWithSalt HashArgs arity a
toHash Int
salt a a
x) b a
y)
instance GHashable arity a => GHashable arity (M1 i c a) where
ghashWithSalt :: forall a. HashArgs arity a -> Int -> M1 i c a a -> Int
ghashWithSalt HashArgs arity a
targs Int
salt = forall arity (f :: * -> *) a.
GHashable arity f =>
HashArgs arity a -> Int -> f a -> Int
ghashWithSalt HashArgs arity a
targs Int
salt forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall k i (c :: Meta) (f :: k -> *) (p :: k). M1 i c f p -> f p
unM1
instance Hashable a => GHashable arity (K1 i a) where
ghashWithSalt :: forall a. HashArgs arity a -> Int -> K1 i a a -> Int
ghashWithSalt HashArgs arity a
_ = forall b a. Hashable b => (a -> b) -> Int -> a -> Int
hashUsing forall k i c (p :: k). K1 i c p -> c
unK1
instance GHashable One Par1 where
ghashWithSalt :: forall a. HashArgs One a -> Int -> Par1 a -> Int
ghashWithSalt (HashArgs1 Int -> a -> Int
h) Int
salt = Int -> a -> Int
h Int
salt forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall p. Par1 p -> p
unPar1
instance Hashable1 f => GHashable One (Rec1 f) where
ghashWithSalt :: forall a. HashArgs One a -> Int -> Rec1 f a -> Int
ghashWithSalt (HashArgs1 Int -> a -> Int
h) Int
salt = forall (t :: * -> *) a.
Hashable1 t =>
(Int -> a -> Int) -> Int -> t a -> Int
liftHashWithSalt Int -> a -> Int
h Int
salt forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall k (f :: k -> *) (p :: k). Rec1 f p -> f p
unRec1
instance (Hashable1 f, GHashable One g) => GHashable One (f :.: g) where
ghashWithSalt :: forall a. HashArgs One a -> Int -> (:.:) f g a -> Int
ghashWithSalt HashArgs One a
targs Int
salt = forall (t :: * -> *) a.
Hashable1 t =>
(Int -> a -> Int) -> Int -> t a -> Int
liftHashWithSalt (forall arity (f :: * -> *) a.
GHashable arity f =>
HashArgs arity a -> Int -> f a -> Int
ghashWithSalt HashArgs One a
targs) Int
salt forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall k2 k1 (f :: k2 -> *) (g :: k1 -> k2) (p :: k1).
(:.:) f g p -> f (g p)
unComp1
class SumSize f => GSum arity f where
hashSum :: HashArgs arity a -> Int -> Int -> f a -> Int
instance (GSum arity a, GSum arity b) => GHashable arity (a :+: b) where
ghashWithSalt :: forall a. HashArgs arity a -> Int -> (:+:) a b a -> Int
ghashWithSalt HashArgs arity a
toHash Int
salt = forall arity (f :: * -> *) a.
GSum arity f =>
HashArgs arity a -> Int -> Int -> f a -> Int
hashSum HashArgs arity a
toHash Int
salt Int
0
instance (GSum arity a, GSum arity b) => GSum arity (a :+: b) where
hashSum :: forall a. HashArgs arity a -> Int -> Int -> (:+:) a b a -> Int
hashSum HashArgs arity a
toHash !Int
salt !Int
index (:+:) a b a
s = case (:+:) a b a
s of
L1 a a
x -> forall arity (f :: * -> *) a.
GSum arity f =>
HashArgs arity a -> Int -> Int -> f a -> Int
hashSum HashArgs arity a
toHash Int
salt Int
index a a
x
R1 b a
x -> forall arity (f :: * -> *) a.
GSum arity f =>
HashArgs arity a -> Int -> Int -> f a -> Int
hashSum HashArgs arity a
toHash Int
salt (Int
index forall a. Num a => a -> a -> a
+ Int
sizeL) b a
x
where
sizeL :: Int
sizeL = forall (s :: * -> *). Tagged s -> Int
unTagged (forall (f :: * -> *). SumSize f => Tagged f
sumSize :: Tagged a)
{-# INLINE hashSum #-}
instance GHashable arity a => GSum arity (C1 c a) where
hashSum :: forall a. HashArgs arity a -> Int -> Int -> C1 c a a -> Int
hashSum HashArgs arity a
toHash !Int
salt !Int
index (M1 a a
x) = forall arity (f :: * -> *) a.
GHashable arity f =>
HashArgs arity a -> Int -> f a -> Int
ghashWithSalt HashArgs arity a
toHash (forall a. Hashable a => Int -> a -> Int
hashWithSalt Int
salt Int
index) a a
x
{-# INLINE hashSum #-}
class SumSize f where
sumSize :: Tagged f
newtype Tagged (s :: Type -> Type) = Tagged {forall (s :: * -> *). Tagged s -> Int
unTagged :: Int}
instance (SumSize a, SumSize b) => SumSize (a :+: b) where
sumSize :: Tagged (a :+: b)
sumSize = forall (s :: * -> *). Int -> Tagged s
Tagged forall a b. (a -> b) -> a -> b
$ forall (s :: * -> *). Tagged s -> Int
unTagged (forall (f :: * -> *). SumSize f => Tagged f
sumSize :: Tagged a) forall a. Num a => a -> a -> a
+
forall (s :: * -> *). Tagged s -> Int
unTagged (forall (f :: * -> *). SumSize f => Tagged f
sumSize :: Tagged b)
instance SumSize (C1 c a) where
sumSize :: Tagged (C1 c a)
sumSize = forall (s :: * -> *). Int -> Tagged s
Tagged Int
1