{-# LANGUAGE TemplateHaskell #-}
{-# LANGUAGE TupleSections #-}
module Grisette.Internal.TH.Derivation.DeriveSimpleMergeable
( deriveSimpleMergeable,
deriveSimpleMergeable1,
deriveSimpleMergeable2,
)
where
import Grisette.Internal.Internal.Decl.Core.Data.Class.SimpleMergeable
( SimpleMergeable (mrgIte),
SimpleMergeable1 (liftMrgIte),
SimpleMergeable2 (liftMrgIte2),
)
import Grisette.Internal.TH.Derivation.BinaryOpCommon
( BinaryOpClassConfig
( BinaryOpClassConfig,
binaryOpAllowSumType,
binaryOpFieldConfigs,
binaryOpInstanceNames
),
BinaryOpFieldConfig
( BinaryOpFieldConfig,
extraPatNames,
fieldCombineFun,
fieldDifferentExistentialFun,
fieldFunExp,
fieldFunNames,
fieldLMatchResult,
fieldRMatchResult,
fieldResFun
),
binaryOpAllowExistential,
defaultFieldFunExp,
genBinaryOpClass,
)
import Grisette.Internal.TH.Derivation.Common (DeriveConfig)
import Language.Haskell.TH (Dec, Exp (AppE, ConE), Name, Q)
simpleMergeableConfig :: BinaryOpClassConfig
simpleMergeableConfig :: BinaryOpClassConfig
simpleMergeableConfig =
BinaryOpClassConfig
{ binaryOpFieldConfigs :: [BinaryOpFieldConfig]
binaryOpFieldConfigs =
[ BinaryOpFieldConfig
{ extraPatNames :: [String]
extraPatNames = [String
"c"],
fieldResFun :: [Exp] -> (Exp, Exp) -> Exp -> Q (Exp, [Bool])
fieldResFun = \[Exp
c] (Exp
lhs, Exp
rhs) Exp
f ->
(,[Bool
True])
(Exp -> (Exp, [Bool])) -> Q Exp -> Q (Exp, [Bool])
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [|$(Exp -> Q Exp
forall a. a -> Q a
forall (m :: * -> *) a. Monad m => a -> m a
return Exp
f) $(Exp -> Q Exp
forall a. a -> Q a
forall (m :: * -> *) a. Monad m => a -> m a
return Exp
c) $(Exp -> Q Exp
forall a. a -> Q a
forall (m :: * -> *) a. Monad m => a -> m a
return Exp
lhs) $(Exp -> Q Exp
forall a. a -> Q a
forall (m :: * -> *) a. Monad m => a -> m a
return Exp
rhs)|],
fieldCombineFun :: Name -> [Exp] -> Q (Exp, [Bool])
fieldCombineFun =
\Name
con [Exp]
lst -> (Exp, [Bool]) -> Q (Exp, [Bool])
forall a. a -> Q a
forall (m :: * -> *) a. Monad m => a -> m a
return ((Exp -> Exp -> Exp) -> Exp -> [Exp] -> Exp
forall b a. (b -> a -> b) -> b -> [a] -> b
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl Exp -> Exp -> Exp
AppE (Name -> Exp
ConE Name
con) [Exp]
lst, [Bool
False]),
fieldDifferentExistentialFun :: Exp -> Q Exp
fieldDifferentExistentialFun = Q Exp -> Exp -> Q Exp
forall a b. a -> b -> a
const [|undefined|],
fieldFunExp :: FieldFunExp
fieldFunExp =
[Name] -> FieldFunExp
defaultFieldFunExp ['mrgIte, 'liftMrgIte, 'liftMrgIte2],
fieldFunNames :: [Name]
fieldFunNames = ['mrgIte, 'liftMrgIte, 'liftMrgIte2],
fieldLMatchResult :: Q Exp
fieldLMatchResult = [|undefined|],
fieldRMatchResult :: Q Exp
fieldRMatchResult = [|undefined|]
}
],
binaryOpInstanceNames :: [Name]
binaryOpInstanceNames =
[''SimpleMergeable, ''SimpleMergeable1, ''SimpleMergeable2],
binaryOpAllowSumType :: Bool
binaryOpAllowSumType = Bool
False,
binaryOpAllowExistential :: Bool
binaryOpAllowExistential = Bool
True
}
deriveSimpleMergeable :: DeriveConfig -> Name -> Q [Dec]
deriveSimpleMergeable :: DeriveConfig -> Name -> Q [Dec]
deriveSimpleMergeable DeriveConfig
deriveConfig =
DeriveConfig -> BinaryOpClassConfig -> Int -> Name -> Q [Dec]
genBinaryOpClass DeriveConfig
deriveConfig BinaryOpClassConfig
simpleMergeableConfig Int
0
deriveSimpleMergeable1 :: DeriveConfig -> Name -> Q [Dec]
deriveSimpleMergeable1 :: DeriveConfig -> Name -> Q [Dec]
deriveSimpleMergeable1 DeriveConfig
deriveConfig =
DeriveConfig -> BinaryOpClassConfig -> Int -> Name -> Q [Dec]
genBinaryOpClass DeriveConfig
deriveConfig BinaryOpClassConfig
simpleMergeableConfig Int
1
deriveSimpleMergeable2 :: DeriveConfig -> Name -> Q [Dec]
deriveSimpleMergeable2 :: DeriveConfig -> Name -> Q [Dec]
deriveSimpleMergeable2 DeriveConfig
deriveConfig =
DeriveConfig -> BinaryOpClassConfig -> Int -> Name -> Q [Dec]
genBinaryOpClass DeriveConfig
deriveConfig BinaryOpClassConfig
simpleMergeableConfig Int
2