{-# LANGUAGE TemplateHaskell #-}
module Grisette.Internal.TH.Derivation.DeriveHashable
( deriveHashable,
deriveHashable1,
deriveHashable2,
)
where
import Data.Hashable (Hashable (hashWithSalt))
import Data.Hashable.Lifted
( Hashable1 (liftHashWithSalt),
Hashable2 (liftHashWithSalt2),
)
import Grisette.Internal.TH.Derivation.Common (DeriveConfig)
import Grisette.Internal.TH.Derivation.UnaryOpCommon
( UnaryOpClassConfig
( UnaryOpClassConfig,
unaryOpAllowExistential,
unaryOpConfigs,
unaryOpContextNames,
unaryOpExtraVars,
unaryOpInstanceNames,
unaryOpInstanceTypeFromConfig
),
UnaryOpConfig (UnaryOpConfig),
UnaryOpFieldConfig
( UnaryOpFieldConfig,
extraLiftedPatNames,
extraPatNames,
fieldCombineFun,
fieldFunExp,
fieldResFun
),
defaultFieldFunExp,
defaultUnaryOpInstanceTypeFromConfig,
genUnaryOpClass,
)
import Language.Haskell.TH (Dec, Name, Q)
hashableConfig :: UnaryOpClassConfig
hashableConfig :: UnaryOpClassConfig
hashableConfig =
UnaryOpClassConfig
{ unaryOpConfigs :: [UnaryOpConfig]
unaryOpConfigs =
[ UnaryOpFieldConfig -> [Name] -> UnaryOpConfig
forall config.
UnaryOpFunConfig config =>
config -> [Name] -> UnaryOpConfig
UnaryOpConfig
UnaryOpFieldConfig
{ extraPatNames :: [String]
extraPatNames = [String
"salt"],
extraLiftedPatNames :: Int -> [String]
extraLiftedPatNames = [String] -> Int -> [String]
forall a b. a -> b -> a
const [],
fieldCombineFun :: Int
-> Int
-> ConstructorVariant
-> Name
-> [Exp]
-> [Exp]
-> Q (Exp, [Bool])
fieldCombineFun =
\Int
_ Int
_ ConstructorVariant
_ Name
_ [Exp
salt] [Exp]
exp -> do
r <-
(Q Exp -> Exp -> Q Exp) -> Q Exp -> [Exp] -> Q Exp
forall b a. (b -> a -> b) -> b -> [a] -> b
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl
(\Q Exp
salt Exp
exp -> [|$(Exp -> Q Exp
forall a. a -> Q a
forall (m :: * -> *) a. Monad m => a -> m a
return Exp
exp) $Q Exp
salt|])
(Exp -> Q Exp
forall a. a -> Q a
forall (m :: * -> *) a. Monad m => a -> m a
return Exp
salt)
[Exp]
exp
return (r, [True]),
fieldResFun :: ConstructorVariant
-> Name -> [Exp] -> Int -> Exp -> Exp -> Q (Exp, [Bool])
fieldResFun = \ConstructorVariant
_ Name
_ [Exp]
_ Int
_ Exp
fieldPat Exp
fieldFun -> do
r <- [|\salt -> $(Exp -> Q Exp
forall a. a -> Q a
forall (m :: * -> *) a. Monad m => a -> m a
return Exp
fieldFun) salt $(Exp -> Q Exp
forall a. a -> Q a
forall (m :: * -> *) a. Monad m => a -> m a
return Exp
fieldPat)|]
return (r, [False]),
fieldFunExp :: FieldFunExp
fieldFunExp =
[Name] -> FieldFunExp
defaultFieldFunExp
['hashWithSalt, 'liftHashWithSalt, 'liftHashWithSalt2]
}
['hashWithSalt, 'liftHashWithSalt, 'liftHashWithSalt2]
],
unaryOpInstanceNames :: [Name]
unaryOpInstanceNames =
[''Hashable, ''Hashable1, ''Hashable2],
unaryOpExtraVars :: DeriveConfig -> Q [(Type, Type)]
unaryOpExtraVars = Q [(Type, Type)] -> DeriveConfig -> Q [(Type, Type)]
forall a b. a -> b -> a
const (Q [(Type, Type)] -> DeriveConfig -> Q [(Type, Type)])
-> Q [(Type, Type)] -> DeriveConfig -> Q [(Type, Type)]
forall a b. (a -> b) -> a -> b
$ [(Type, Type)] -> Q [(Type, Type)]
forall a. a -> Q a
forall (m :: * -> *) a. Monad m => a -> m a
return [],
unaryOpInstanceTypeFromConfig :: DeriveConfig -> [(Type, Type)] -> [(Type, Type)] -> Name -> Q Type
unaryOpInstanceTypeFromConfig = DeriveConfig -> [(Type, Type)] -> [(Type, Type)] -> Name -> Q Type
defaultUnaryOpInstanceTypeFromConfig,
unaryOpAllowExistential :: Bool
unaryOpAllowExistential = Bool
True,
unaryOpContextNames :: Maybe [Name]
unaryOpContextNames = Maybe [Name]
forall a. Maybe a
Nothing
}
deriveHashable :: DeriveConfig -> Name -> Q [Dec]
deriveHashable :: DeriveConfig -> Name -> Q [Dec]
deriveHashable DeriveConfig
deriveConfig = DeriveConfig -> UnaryOpClassConfig -> Int -> Name -> Q [Dec]
genUnaryOpClass DeriveConfig
deriveConfig UnaryOpClassConfig
hashableConfig Int
0
deriveHashable1 :: DeriveConfig -> Name -> Q [Dec]
deriveHashable1 :: DeriveConfig -> Name -> Q [Dec]
deriveHashable1 DeriveConfig
deriveConfig = DeriveConfig -> UnaryOpClassConfig -> Int -> Name -> Q [Dec]
genUnaryOpClass DeriveConfig
deriveConfig UnaryOpClassConfig
hashableConfig Int
1
deriveHashable2 :: DeriveConfig -> Name -> Q [Dec]
deriveHashable2 :: DeriveConfig -> Name -> Q [Dec]
deriveHashable2 DeriveConfig
deriveConfig = DeriveConfig -> UnaryOpClassConfig -> Int -> Name -> Q [Dec]
genUnaryOpClass DeriveConfig
deriveConfig UnaryOpClassConfig
hashableConfig Int
2