{-# LANGUAGE BangPatterns #-}
{-# LANGUAGE CPP #-}
{-# LANGUAGE ViewPatterns #-}
module Generics.Deriving.TH (
deriveMeta
, deriveData
, deriveConstructors
, deriveSelectors
, deriveAll
, deriveAll0
, deriveAll1
, deriveAll0And1
, deriveRepresentable0
, deriveRepresentable1
, deriveRep0
, deriveRep1
, makeRep0Inline
, makeRep0
, makeRep0FromType
, makeFrom
, makeFrom0
, makeTo
, makeTo0
, makeRep1Inline
, makeRep1
, makeRep1FromType
, makeFrom1
, makeTo1
, Options(..)
, defaultOptions
, RepOptions(..)
, defaultRepOptions
, KindSigOptions
, defaultKindSigOptions
, EmptyCaseOptions
, defaultEmptyCaseOptions
, deriveAll0Options
, deriveAll1Options
, deriveAll0And1Options
, deriveRepresentable0Options
, deriveRepresentable1Options
, deriveRep0Options
, deriveRep1Options
, makeFrom0Options
, makeTo0Options
, makeFrom1Options
, makeTo1Options
) where
import Control.Monad ((>=>), unless, when)
import qualified Data.Map as Map (empty, fromList)
import Generics.Deriving.TH.Internal
#if MIN_VERSION_base(4,9,0)
import Generics.Deriving.TH.Post4_9
#else
import Generics.Deriving.TH.Pre4_9
#endif
import Language.Haskell.TH.Datatype
import Language.Haskell.TH.Lib
import Language.Haskell.TH
data Options = Options
{ Options -> RepOptions
repOptions :: RepOptions
, Options -> KindSigOptions
kindSigOptions :: KindSigOptions
, Options -> KindSigOptions
emptyCaseOptions :: EmptyCaseOptions
} deriving (Options -> Options -> KindSigOptions
(Options -> Options -> KindSigOptions)
-> (Options -> Options -> KindSigOptions) -> Eq Options
forall a.
(a -> a -> KindSigOptions) -> (a -> a -> KindSigOptions) -> Eq a
/= :: Options -> Options -> KindSigOptions
$c/= :: Options -> Options -> KindSigOptions
== :: Options -> Options -> KindSigOptions
$c== :: Options -> Options -> KindSigOptions
Eq, Eq Options
Eq Options
-> (Options -> Options -> Ordering)
-> (Options -> Options -> KindSigOptions)
-> (Options -> Options -> KindSigOptions)
-> (Options -> Options -> KindSigOptions)
-> (Options -> Options -> KindSigOptions)
-> (Options -> Options -> Options)
-> (Options -> Options -> Options)
-> Ord Options
Options -> Options -> KindSigOptions
Options -> Options -> Ordering
Options -> Options -> Options
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> KindSigOptions)
-> (a -> a -> KindSigOptions)
-> (a -> a -> KindSigOptions)
-> (a -> a -> KindSigOptions)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: Options -> Options -> Options
$cmin :: Options -> Options -> Options
max :: Options -> Options -> Options
$cmax :: Options -> Options -> Options
>= :: Options -> Options -> KindSigOptions
$c>= :: Options -> Options -> KindSigOptions
> :: Options -> Options -> KindSigOptions
$c> :: Options -> Options -> KindSigOptions
<= :: Options -> Options -> KindSigOptions
$c<= :: Options -> Options -> KindSigOptions
< :: Options -> Options -> KindSigOptions
$c< :: Options -> Options -> KindSigOptions
compare :: Options -> Options -> Ordering
$ccompare :: Options -> Options -> Ordering
$cp1Ord :: Eq Options
Ord, ReadPrec [Options]
ReadPrec Options
Int -> ReadS Options
ReadS [Options]
(Int -> ReadS Options)
-> ReadS [Options]
-> ReadPrec Options
-> ReadPrec [Options]
-> Read Options
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
readListPrec :: ReadPrec [Options]
$creadListPrec :: ReadPrec [Options]
readPrec :: ReadPrec Options
$creadPrec :: ReadPrec Options
readList :: ReadS [Options]
$creadList :: ReadS [Options]
readsPrec :: Int -> ReadS Options
$creadsPrec :: Int -> ReadS Options
Read, Int -> Options -> ShowS
[Options] -> ShowS
Options -> String
(Int -> Options -> ShowS)
-> (Options -> String) -> ([Options] -> ShowS) -> Show Options
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Options] -> ShowS
$cshowList :: [Options] -> ShowS
show :: Options -> String
$cshow :: Options -> String
showsPrec :: Int -> Options -> ShowS
$cshowsPrec :: Int -> Options -> ShowS
Show)
defaultOptions :: Options
defaultOptions :: Options
defaultOptions = Options :: RepOptions -> KindSigOptions -> KindSigOptions -> Options
Options
{ repOptions :: RepOptions
repOptions = RepOptions
defaultRepOptions
, kindSigOptions :: KindSigOptions
kindSigOptions = KindSigOptions
defaultKindSigOptions
, emptyCaseOptions :: KindSigOptions
emptyCaseOptions = KindSigOptions
defaultEmptyCaseOptions
}
data RepOptions = InlineRep
| TypeSynonymRep
deriving (RepOptions -> RepOptions -> KindSigOptions
(RepOptions -> RepOptions -> KindSigOptions)
-> (RepOptions -> RepOptions -> KindSigOptions) -> Eq RepOptions
forall a.
(a -> a -> KindSigOptions) -> (a -> a -> KindSigOptions) -> Eq a
/= :: RepOptions -> RepOptions -> KindSigOptions
$c/= :: RepOptions -> RepOptions -> KindSigOptions
== :: RepOptions -> RepOptions -> KindSigOptions
$c== :: RepOptions -> RepOptions -> KindSigOptions
Eq, Eq RepOptions
Eq RepOptions
-> (RepOptions -> RepOptions -> Ordering)
-> (RepOptions -> RepOptions -> KindSigOptions)
-> (RepOptions -> RepOptions -> KindSigOptions)
-> (RepOptions -> RepOptions -> KindSigOptions)
-> (RepOptions -> RepOptions -> KindSigOptions)
-> (RepOptions -> RepOptions -> RepOptions)
-> (RepOptions -> RepOptions -> RepOptions)
-> Ord RepOptions
RepOptions -> RepOptions -> KindSigOptions
RepOptions -> RepOptions -> Ordering
RepOptions -> RepOptions -> RepOptions
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> KindSigOptions)
-> (a -> a -> KindSigOptions)
-> (a -> a -> KindSigOptions)
-> (a -> a -> KindSigOptions)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: RepOptions -> RepOptions -> RepOptions
$cmin :: RepOptions -> RepOptions -> RepOptions
max :: RepOptions -> RepOptions -> RepOptions
$cmax :: RepOptions -> RepOptions -> RepOptions
>= :: RepOptions -> RepOptions -> KindSigOptions
$c>= :: RepOptions -> RepOptions -> KindSigOptions
> :: RepOptions -> RepOptions -> KindSigOptions
$c> :: RepOptions -> RepOptions -> KindSigOptions
<= :: RepOptions -> RepOptions -> KindSigOptions
$c<= :: RepOptions -> RepOptions -> KindSigOptions
< :: RepOptions -> RepOptions -> KindSigOptions
$c< :: RepOptions -> RepOptions -> KindSigOptions
compare :: RepOptions -> RepOptions -> Ordering
$ccompare :: RepOptions -> RepOptions -> Ordering
$cp1Ord :: Eq RepOptions
Ord, ReadPrec [RepOptions]
ReadPrec RepOptions
Int -> ReadS RepOptions
ReadS [RepOptions]
(Int -> ReadS RepOptions)
-> ReadS [RepOptions]
-> ReadPrec RepOptions
-> ReadPrec [RepOptions]
-> Read RepOptions
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
readListPrec :: ReadPrec [RepOptions]
$creadListPrec :: ReadPrec [RepOptions]
readPrec :: ReadPrec RepOptions
$creadPrec :: ReadPrec RepOptions
readList :: ReadS [RepOptions]
$creadList :: ReadS [RepOptions]
readsPrec :: Int -> ReadS RepOptions
$creadsPrec :: Int -> ReadS RepOptions
Read, Int -> RepOptions -> ShowS
[RepOptions] -> ShowS
RepOptions -> String
(Int -> RepOptions -> ShowS)
-> (RepOptions -> String)
-> ([RepOptions] -> ShowS)
-> Show RepOptions
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [RepOptions] -> ShowS
$cshowList :: [RepOptions] -> ShowS
show :: RepOptions -> String
$cshow :: RepOptions -> String
showsPrec :: Int -> RepOptions -> ShowS
$cshowsPrec :: Int -> RepOptions -> ShowS
Show)
defaultRepOptions :: RepOptions
defaultRepOptions :: RepOptions
defaultRepOptions = RepOptions
InlineRep
type KindSigOptions = Bool
defaultKindSigOptions :: KindSigOptions
defaultKindSigOptions :: KindSigOptions
defaultKindSigOptions = KindSigOptions
True
type EmptyCaseOptions = Bool
defaultEmptyCaseOptions :: EmptyCaseOptions
defaultEmptyCaseOptions :: KindSigOptions
defaultEmptyCaseOptions = KindSigOptions
False
deriveAll :: Name -> Q [Dec]
deriveAll :: Name -> Q [Dec]
deriveAll = Name -> Q [Dec]
deriveAll0
deriveAll0 :: Name -> Q [Dec]
deriveAll0 :: Name -> Q [Dec]
deriveAll0 = Options -> Name -> Q [Dec]
deriveAll0Options Options
defaultOptions
deriveAll0Options :: Options -> Name -> Q [Dec]
deriveAll0Options :: Options -> Name -> Q [Dec]
deriveAll0Options = KindSigOptions -> KindSigOptions -> Options -> Name -> Q [Dec]
deriveAllCommon KindSigOptions
True KindSigOptions
False
deriveAll1 :: Name -> Q [Dec]
deriveAll1 :: Name -> Q [Dec]
deriveAll1 = Options -> Name -> Q [Dec]
deriveAll1Options Options
defaultOptions
deriveAll1Options :: Options -> Name -> Q [Dec]
deriveAll1Options :: Options -> Name -> Q [Dec]
deriveAll1Options = KindSigOptions -> KindSigOptions -> Options -> Name -> Q [Dec]
deriveAllCommon KindSigOptions
False KindSigOptions
True
deriveAll0And1 :: Name -> Q [Dec]
deriveAll0And1 :: Name -> Q [Dec]
deriveAll0And1 = Options -> Name -> Q [Dec]
deriveAll0And1Options Options
defaultOptions
deriveAll0And1Options :: Options -> Name -> Q [Dec]
deriveAll0And1Options :: Options -> Name -> Q [Dec]
deriveAll0And1Options = KindSigOptions -> KindSigOptions -> Options -> Name -> Q [Dec]
deriveAllCommon KindSigOptions
True KindSigOptions
True
deriveAllCommon :: Bool -> Bool -> Options -> Name -> Q [Dec]
deriveAllCommon :: KindSigOptions -> KindSigOptions -> Options -> Name -> Q [Dec]
deriveAllCommon KindSigOptions
generic KindSigOptions
generic1 Options
opts Name
n = do
[Dec]
a <- Name -> Q [Dec]
deriveMeta Name
n
[Dec]
b <- if KindSigOptions
generic
then GenericClass -> Options -> Name -> Q [Dec]
deriveRepresentableCommon GenericClass
Generic Options
opts Name
n
else [Dec] -> Q [Dec]
forall (m :: * -> *) a. Monad m => a -> m a
return []
[Dec]
c <- if KindSigOptions
generic1
then GenericClass -> Options -> Name -> Q [Dec]
deriveRepresentableCommon GenericClass
Generic1 Options
opts Name
n
else [Dec] -> Q [Dec]
forall (m :: * -> *) a. Monad m => a -> m a
return []
[Dec] -> Q [Dec]
forall (m :: * -> *) a. Monad m => a -> m a
return ([Dec]
a [Dec] -> [Dec] -> [Dec]
forall a. [a] -> [a] -> [a]
++ [Dec]
b [Dec] -> [Dec] -> [Dec]
forall a. [a] -> [a] -> [a]
++ [Dec]
c)
deriveRepresentable0 :: Name -> Q [Dec]
deriveRepresentable0 :: Name -> Q [Dec]
deriveRepresentable0 = Options -> Name -> Q [Dec]
deriveRepresentable0Options Options
defaultOptions
deriveRepresentable0Options :: Options -> Name -> Q [Dec]
deriveRepresentable0Options :: Options -> Name -> Q [Dec]
deriveRepresentable0Options = GenericClass -> Options -> Name -> Q [Dec]
deriveRepresentableCommon GenericClass
Generic
deriveRepresentable1 :: Name -> Q [Dec]
deriveRepresentable1 :: Name -> Q [Dec]
deriveRepresentable1 = Options -> Name -> Q [Dec]
deriveRepresentable1Options Options
defaultOptions
deriveRepresentable1Options :: Options -> Name -> Q [Dec]
deriveRepresentable1Options :: Options -> Name -> Q [Dec]
deriveRepresentable1Options = GenericClass -> Options -> Name -> Q [Dec]
deriveRepresentableCommon GenericClass
Generic1
deriveRepresentableCommon :: GenericClass -> Options -> Name -> Q [Dec]
deriveRepresentableCommon :: GenericClass -> Options -> Name -> Q [Dec]
deriveRepresentableCommon GenericClass
gClass Options
opts Name
n = do
[Dec]
rep <- if Options -> RepOptions
repOptions Options
opts RepOptions -> RepOptions -> KindSigOptions
forall a. Eq a => a -> a -> KindSigOptions
== RepOptions
InlineRep
then [Dec] -> Q [Dec]
forall (m :: * -> *) a. Monad m => a -> m a
return []
else GenericClass -> KindSigOptions -> Name -> Q [Dec]
deriveRepCommon GenericClass
gClass (Options -> KindSigOptions
kindSigOptions Options
opts) Name
n
[Dec]
inst <- GenericClass -> Options -> Name -> Q [Dec]
deriveInst GenericClass
gClass Options
opts Name
n
[Dec] -> Q [Dec]
forall (m :: * -> *) a. Monad m => a -> m a
return ([Dec]
rep [Dec] -> [Dec] -> [Dec]
forall a. [a] -> [a] -> [a]
++ [Dec]
inst)
deriveRep0 :: Name -> Q [Dec]
deriveRep0 :: Name -> Q [Dec]
deriveRep0 = KindSigOptions -> Name -> Q [Dec]
deriveRep0Options KindSigOptions
defaultKindSigOptions
deriveRep0Options :: KindSigOptions -> Name -> Q [Dec]
deriveRep0Options :: KindSigOptions -> Name -> Q [Dec]
deriveRep0Options = GenericClass -> KindSigOptions -> Name -> Q [Dec]
deriveRepCommon GenericClass
Generic
deriveRep1 :: Name -> Q [Dec]
deriveRep1 :: Name -> Q [Dec]
deriveRep1 = KindSigOptions -> Name -> Q [Dec]
deriveRep1Options KindSigOptions
defaultKindSigOptions
deriveRep1Options :: KindSigOptions -> Name -> Q [Dec]
deriveRep1Options :: KindSigOptions -> Name -> Q [Dec]
deriveRep1Options = GenericClass -> KindSigOptions -> Name -> Q [Dec]
deriveRepCommon GenericClass
Generic1
deriveRepCommon :: GenericClass -> KindSigOptions -> Name -> Q [Dec]
deriveRepCommon :: GenericClass -> KindSigOptions -> Name -> Q [Dec]
deriveRepCommon GenericClass
gClass KindSigOptions
useKindSigs Name
n = do
Either String (Name, [Type], [ConstructorInfo], DatatypeVariant_)
i <- Name
-> Q (Either
String (Name, [Type], [ConstructorInfo], DatatypeVariant_))
reifyDataInfo Name
n
let (Name
name, [Type]
instTys, [ConstructorInfo]
cons, DatatypeVariant_
dv) = (String -> (Name, [Type], [ConstructorInfo], DatatypeVariant_))
-> ((Name, [Type], [ConstructorInfo], DatatypeVariant_)
-> (Name, [Type], [ConstructorInfo], DatatypeVariant_))
-> Either
String (Name, [Type], [ConstructorInfo], DatatypeVariant_)
-> (Name, [Type], [ConstructorInfo], DatatypeVariant_)
forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either String -> (Name, [Type], [ConstructorInfo], DatatypeVariant_)
forall a. HasCallStack => String -> a
error (Name, [Type], [ConstructorInfo], DatatypeVariant_)
-> (Name, [Type], [ConstructorInfo], DatatypeVariant_)
forall a. a -> a
id Either String (Name, [Type], [ConstructorInfo], DatatypeVariant_)
i
gt :: GenericTvbs
gt = GenericClass -> [Type] -> GenericTvbs
mkGenericTvbs GenericClass
gClass [Type]
instTys
!(Type, Type)
_ <- GenericClass -> KindSigOptions -> Name -> [Type] -> Q (Type, Type)
buildTypeInstance GenericClass
gClass KindSigOptions
useKindSigs Name
name [Type]
instTys
let tySynVars :: [TyVarBndrUnit]
tySynVars = GenericTvbs -> [TyVarBndrUnit]
genericInitTvbs GenericTvbs
gt
tySynVars' :: [TyVarBndrUnit]
tySynVars' = if KindSigOptions
useKindSigs
then [TyVarBndrUnit]
tySynVars
else (TyVarBndrUnit -> TyVarBndrUnit)
-> [TyVarBndrUnit] -> [TyVarBndrUnit]
forall a b. (a -> b) -> [a] -> [b]
map TyVarBndrUnit -> TyVarBndrUnit
unKindedTV [TyVarBndrUnit]
tySynVars
(Dec -> [Dec]) -> Q Dec -> Q [Dec]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (Dec -> [Dec] -> [Dec]
forall a. a -> [a] -> [a]
:[]) (Q Dec -> Q [Dec]) -> Q Dec -> Q [Dec]
forall a b. (a -> b) -> a -> b
$ Name -> [TyVarBndrUnit] -> TypeQ -> Q Dec
tySynD (GenericClass -> DatatypeVariant_ -> Name -> Name
genRepName GenericClass
gClass DatatypeVariant_
dv Name
name)
[TyVarBndrUnit]
tySynVars'
(GenericTvbs
-> DatatypeVariant_
-> Name
-> TypeSubst
-> [ConstructorInfo]
-> TypeQ
repType GenericTvbs
gt DatatypeVariant_
dv Name
name TypeSubst
forall k a. Map k a
Map.empty [ConstructorInfo]
cons)
deriveInst :: GenericClass -> Options -> Name -> Q [Dec]
deriveInst :: GenericClass -> Options -> Name -> Q [Dec]
deriveInst GenericClass
Generic = Name
-> Name
-> GenericClass
-> Name
-> Name
-> Options
-> Name
-> Q [Dec]
deriveInstCommon Name
genericTypeName Name
repTypeName GenericClass
Generic Name
fromValName Name
toValName
deriveInst GenericClass
Generic1 = Name
-> Name
-> GenericClass
-> Name
-> Name
-> Options
-> Name
-> Q [Dec]
deriveInstCommon Name
generic1TypeName Name
rep1TypeName GenericClass
Generic1 Name
from1ValName Name
to1ValName
deriveInstCommon :: Name
-> Name
-> GenericClass
-> Name
-> Name
-> Options
-> Name
-> Q [Dec]
deriveInstCommon :: Name
-> Name
-> GenericClass
-> Name
-> Name
-> Options
-> Name
-> Q [Dec]
deriveInstCommon Name
genericName Name
repName GenericClass
gClass Name
fromName Name
toName Options
opts Name
n = do
Either String (Name, [Type], [ConstructorInfo], DatatypeVariant_)
i <- Name
-> Q (Either
String (Name, [Type], [ConstructorInfo], DatatypeVariant_))
reifyDataInfo Name
n
let (Name
name, [Type]
instTys, [ConstructorInfo]
cons, DatatypeVariant_
dv) = (String -> (Name, [Type], [ConstructorInfo], DatatypeVariant_))
-> ((Name, [Type], [ConstructorInfo], DatatypeVariant_)
-> (Name, [Type], [ConstructorInfo], DatatypeVariant_))
-> Either
String (Name, [Type], [ConstructorInfo], DatatypeVariant_)
-> (Name, [Type], [ConstructorInfo], DatatypeVariant_)
forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either String -> (Name, [Type], [ConstructorInfo], DatatypeVariant_)
forall a. HasCallStack => String -> a
error (Name, [Type], [ConstructorInfo], DatatypeVariant_)
-> (Name, [Type], [ConstructorInfo], DatatypeVariant_)
forall a. a -> a
id Either String (Name, [Type], [ConstructorInfo], DatatypeVariant_)
i
gt :: GenericTvbs
gt = GenericClass -> [Type] -> GenericTvbs
mkGenericTvbs GenericClass
gClass [Type]
instTys
useKindSigs :: KindSigOptions
useKindSigs = Options -> KindSigOptions
kindSigOptions Options
opts
!(Type
origTy, Type
origKind) <- GenericClass -> KindSigOptions -> Name -> [Type] -> Q (Type, Type)
buildTypeInstance GenericClass
gClass KindSigOptions
useKindSigs Name
name [Type]
instTys
Type
tyInsRHS <- if Options -> RepOptions
repOptions Options
opts RepOptions -> RepOptions -> KindSigOptions
forall a. Eq a => a -> a -> KindSigOptions
== RepOptions
InlineRep
then GenericTvbs
-> DatatypeVariant_
-> Name
-> TypeSubst
-> [ConstructorInfo]
-> TypeQ
repType GenericTvbs
gt DatatypeVariant_
dv Name
name TypeSubst
forall k a. Map k a
Map.empty [ConstructorInfo]
cons
else GenericClass -> DatatypeVariant_ -> Name -> Type -> TypeQ
makeRepTySynApp GenericClass
gClass DatatypeVariant_
dv Name
name Type
origTy
let origSigTy :: Type
origSigTy = if KindSigOptions
useKindSigs
then Type -> Type -> Type
SigT Type
origTy Type
origKind
else Type
origTy
Dec
tyIns <- Name -> Maybe [Q TyVarBndrUnit] -> [TypeQ] -> TypeQ -> Q Dec
tySynInstDCompat Name
repName Maybe [Q TyVarBndrUnit]
forall a. Maybe a
Nothing [Type -> TypeQ
forall (m :: * -> *) a. Monad m => a -> m a
return Type
origSigTy] (Type -> TypeQ
forall (m :: * -> *) a. Monad m => a -> m a
return Type
tyInsRHS)
let ecOptions :: KindSigOptions
ecOptions = Options -> KindSigOptions
emptyCaseOptions Options
opts
mkBody :: (GenericTvbs
-> KindSigOptions -> Name -> [ConstructorInfo] -> Q Match)
-> [ClauseQ]
mkBody GenericTvbs
-> KindSigOptions -> Name -> [ConstructorInfo] -> Q Match
maker = [[PatQ] -> BodyQ -> [Q Dec] -> ClauseQ
clause []
(ExpQ -> BodyQ
normalB (ExpQ -> BodyQ) -> ExpQ -> BodyQ
forall a b. (a -> b) -> a -> b
$
Q Match -> ExpQ
mkCaseExp (Q Match -> ExpQ) -> Q Match -> ExpQ
forall a b. (a -> b) -> a -> b
$
GenericTvbs
-> KindSigOptions -> Name -> [ConstructorInfo] -> Q Match
maker GenericTvbs
gt KindSigOptions
ecOptions Name
name [ConstructorInfo]
cons)
[]]
fcs :: [ClauseQ]
fcs = (GenericTvbs
-> KindSigOptions -> Name -> [ConstructorInfo] -> Q Match)
-> [ClauseQ]
mkBody GenericTvbs
-> KindSigOptions -> Name -> [ConstructorInfo] -> Q Match
mkFrom
tcs :: [ClauseQ]
tcs = (GenericTvbs
-> KindSigOptions -> Name -> [ConstructorInfo] -> Q Match)
-> [ClauseQ]
mkBody GenericTvbs
-> KindSigOptions -> Name -> [ConstructorInfo] -> Q Match
mkTo
(Dec -> [Dec]) -> Q Dec -> Q [Dec]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (Dec -> [Dec] -> [Dec]
forall a. a -> [a] -> [a]
:[]) (Q Dec -> Q [Dec]) -> Q Dec -> Q [Dec]
forall a b. (a -> b) -> a -> b
$
CxtQ -> TypeQ -> [Q Dec] -> Q Dec
instanceD ([TypeQ] -> CxtQ
cxt []) (Name -> TypeQ
conT Name
genericName TypeQ -> TypeQ -> TypeQ
`appT` Type -> TypeQ
forall (m :: * -> *) a. Monad m => a -> m a
return Type
origSigTy)
[Dec -> Q Dec
forall (m :: * -> *) a. Monad m => a -> m a
return Dec
tyIns, Name -> [ClauseQ] -> Q Dec
funD Name
fromName [ClauseQ]
fcs, Name -> [ClauseQ] -> Q Dec
funD Name
toName [ClauseQ]
tcs]
makeRep0Inline :: Name -> Q Type -> Q Type
makeRep0Inline :: Name -> TypeQ -> TypeQ
makeRep0Inline Name
n = GenericClass -> RepOptions -> Name -> Maybe TypeQ -> TypeQ
makeRepCommon GenericClass
Generic RepOptions
InlineRep Name
n (Maybe TypeQ -> TypeQ) -> (TypeQ -> Maybe TypeQ) -> TypeQ -> TypeQ
forall b c a. (b -> c) -> (a -> b) -> a -> c
. TypeQ -> Maybe TypeQ
forall a. a -> Maybe a
Just
makeRep1Inline :: Name -> Q Type -> Q Type
makeRep1Inline :: Name -> TypeQ -> TypeQ
makeRep1Inline Name
n = GenericClass -> RepOptions -> Name -> Maybe TypeQ -> TypeQ
makeRepCommon GenericClass
Generic1 RepOptions
InlineRep Name
n (Maybe TypeQ -> TypeQ) -> (TypeQ -> Maybe TypeQ) -> TypeQ -> TypeQ
forall b c a. (b -> c) -> (a -> b) -> a -> c
. TypeQ -> Maybe TypeQ
forall a. a -> Maybe a
Just
makeRep0 :: Name -> Q Type
makeRep0 :: Name -> TypeQ
makeRep0 Name
n = GenericClass -> RepOptions -> Name -> Maybe TypeQ -> TypeQ
makeRepCommon GenericClass
Generic RepOptions
TypeSynonymRep Name
n Maybe TypeQ
forall a. Maybe a
Nothing
makeRep1 :: Name -> Q Type
makeRep1 :: Name -> TypeQ
makeRep1 Name
n = GenericClass -> RepOptions -> Name -> Maybe TypeQ -> TypeQ
makeRepCommon GenericClass
Generic1 RepOptions
TypeSynonymRep Name
n Maybe TypeQ
forall a. Maybe a
Nothing
makeRep0FromType :: Name -> Q Type -> Q Type
makeRep0FromType :: Name -> TypeQ -> TypeQ
makeRep0FromType Name
n = GenericClass -> RepOptions -> Name -> Maybe TypeQ -> TypeQ
makeRepCommon GenericClass
Generic RepOptions
TypeSynonymRep Name
n (Maybe TypeQ -> TypeQ) -> (TypeQ -> Maybe TypeQ) -> TypeQ -> TypeQ
forall b c a. (b -> c) -> (a -> b) -> a -> c
. TypeQ -> Maybe TypeQ
forall a. a -> Maybe a
Just
makeRep1FromType :: Name -> Q Type -> Q Type
makeRep1FromType :: Name -> TypeQ -> TypeQ
makeRep1FromType Name
n = GenericClass -> RepOptions -> Name -> Maybe TypeQ -> TypeQ
makeRepCommon GenericClass
Generic1 RepOptions
TypeSynonymRep Name
n (Maybe TypeQ -> TypeQ) -> (TypeQ -> Maybe TypeQ) -> TypeQ -> TypeQ
forall b c a. (b -> c) -> (a -> b) -> a -> c
. TypeQ -> Maybe TypeQ
forall a. a -> Maybe a
Just
makeRepCommon :: GenericClass
-> RepOptions
-> Name
-> Maybe (Q Type)
-> Q Type
makeRepCommon :: GenericClass -> RepOptions -> Name -> Maybe TypeQ -> TypeQ
makeRepCommon GenericClass
gClass RepOptions
repOpts Name
n Maybe TypeQ
mbQTy = do
Either String (Name, [Type], [ConstructorInfo], DatatypeVariant_)
i <- Name
-> Q (Either
String (Name, [Type], [ConstructorInfo], DatatypeVariant_))
reifyDataInfo Name
n
let (Name
name, [Type]
instTys, [ConstructorInfo]
cons, DatatypeVariant_
dv) = (String -> (Name, [Type], [ConstructorInfo], DatatypeVariant_))
-> ((Name, [Type], [ConstructorInfo], DatatypeVariant_)
-> (Name, [Type], [ConstructorInfo], DatatypeVariant_))
-> Either
String (Name, [Type], [ConstructorInfo], DatatypeVariant_)
-> (Name, [Type], [ConstructorInfo], DatatypeVariant_)
forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either String -> (Name, [Type], [ConstructorInfo], DatatypeVariant_)
forall a. HasCallStack => String -> a
error (Name, [Type], [ConstructorInfo], DatatypeVariant_)
-> (Name, [Type], [ConstructorInfo], DatatypeVariant_)
forall a. a -> a
id Either String (Name, [Type], [ConstructorInfo], DatatypeVariant_)
i
gt :: GenericTvbs
gt = GenericClass -> [Type] -> GenericTvbs
mkGenericTvbs GenericClass
gClass [Type]
instTys
!(Type, Type)
_ <- GenericClass -> KindSigOptions -> Name -> [Type] -> Q (Type, Type)
buildTypeInstance GenericClass
gClass KindSigOptions
False Name
name [Type]
instTys
case (Maybe TypeQ
mbQTy, RepOptions
repOpts) of
(Just TypeQ
qTy, RepOptions
TypeSynonymRep) -> TypeQ
qTy TypeQ -> (Type -> TypeQ) -> TypeQ
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= GenericClass -> DatatypeVariant_ -> Name -> Type -> TypeQ
makeRepTySynApp GenericClass
gClass DatatypeVariant_
dv Name
name
(Just TypeQ
qTy, RepOptions
InlineRep) -> TypeQ
qTy TypeQ -> (Type -> TypeQ) -> TypeQ
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= GenericTvbs
-> DatatypeVariant_ -> Name -> [ConstructorInfo] -> Type -> TypeQ
makeRepInline GenericTvbs
gt DatatypeVariant_
dv Name
name [ConstructorInfo]
cons
(Maybe TypeQ
Nothing, RepOptions
TypeSynonymRep) -> Name -> TypeQ
conT (Name -> TypeQ) -> Name -> TypeQ
forall a b. (a -> b) -> a -> b
$ GenericClass -> DatatypeVariant_ -> Name -> Name
genRepName GenericClass
gClass DatatypeVariant_
dv Name
name
(Maybe TypeQ
Nothing, RepOptions
InlineRep) -> String -> TypeQ
forall (m :: * -> *) a. MonadFail m => String -> m a
fail String
"makeRepCommon"
makeRepInline :: GenericTvbs
-> DatatypeVariant_
-> Name
-> [ConstructorInfo]
-> Type
-> Q Type
makeRepInline :: GenericTvbs
-> DatatypeVariant_ -> Name -> [ConstructorInfo] -> Type -> TypeQ
makeRepInline GenericTvbs
gt DatatypeVariant_
dv Name
name [ConstructorInfo]
cons Type
ty = do
let instVars :: [TyVarBndrUnit]
instVars = [Type] -> [TyVarBndrUnit]
freeVariablesWellScoped [Type
ty]
tySynVars :: [TyVarBndrUnit]
tySynVars = GenericTvbs -> [TyVarBndrUnit]
genericInitTvbs GenericTvbs
gt
typeSubst :: TypeSubst
typeSubst :: TypeSubst
typeSubst = [(Name, Type)] -> TypeSubst
forall k a. Ord k => [(k, a)] -> Map k a
Map.fromList ([(Name, Type)] -> TypeSubst) -> [(Name, Type)] -> TypeSubst
forall a b. (a -> b) -> a -> b
$
[Name] -> [Type] -> [(Name, Type)]
forall a b. [a] -> [b] -> [(a, b)]
zip ((TyVarBndrUnit -> Name) -> [TyVarBndrUnit] -> [Name]
forall a b. (a -> b) -> [a] -> [b]
map TyVarBndrUnit -> Name
forall flag. TyVarBndrUnit -> Name
tvName [TyVarBndrUnit]
tySynVars)
((TyVarBndrUnit -> Type) -> [TyVarBndrUnit] -> [Type]
forall a b. (a -> b) -> [a] -> [b]
map (Name -> Type
VarT (Name -> Type) -> (TyVarBndrUnit -> Name) -> TyVarBndrUnit -> Type
forall b c a. (b -> c) -> (a -> b) -> a -> c
. TyVarBndrUnit -> Name
forall flag. TyVarBndrUnit -> Name
tvName) [TyVarBndrUnit]
instVars)
GenericTvbs
-> DatatypeVariant_
-> Name
-> TypeSubst
-> [ConstructorInfo]
-> TypeQ
repType GenericTvbs
gt DatatypeVariant_
dv Name
name TypeSubst
typeSubst [ConstructorInfo]
cons
makeRepTySynApp :: GenericClass -> DatatypeVariant_ -> Name
-> Type -> Q Type
makeRepTySynApp :: GenericClass -> DatatypeVariant_ -> Name -> Type -> TypeQ
makeRepTySynApp GenericClass
gClass DatatypeVariant_
dv Name
name Type
ty =
let instTvbs :: [TyVarBndrUnit]
instTvbs = (TyVarBndrUnit -> TyVarBndrUnit)
-> [TyVarBndrUnit] -> [TyVarBndrUnit]
forall a b. (a -> b) -> [a] -> [b]
map TyVarBndrUnit -> TyVarBndrUnit
unKindedTV ([TyVarBndrUnit] -> [TyVarBndrUnit])
-> [TyVarBndrUnit] -> [TyVarBndrUnit]
forall a b. (a -> b) -> a -> b
$ [Type] -> [TyVarBndrUnit]
freeVariablesWellScoped [Type
ty]
in Type -> TypeQ
forall (m :: * -> *) a. Monad m => a -> m a
return (Type -> TypeQ) -> Type -> TypeQ
forall a b. (a -> b) -> a -> b
$ Name -> [TyVarBndrUnit] -> Type
forall flag. Name -> [TyVarBndrUnit] -> Type
applyTyToTvbs (GenericClass -> DatatypeVariant_ -> Name -> Name
genRepName GenericClass
gClass DatatypeVariant_
dv Name
name) [TyVarBndrUnit]
instTvbs
makeFrom :: Name -> Q Exp
makeFrom :: Name -> ExpQ
makeFrom = Name -> ExpQ
makeFrom0
makeFrom0 :: Name -> Q Exp
makeFrom0 :: Name -> ExpQ
makeFrom0 = KindSigOptions -> Name -> ExpQ
makeFrom0Options KindSigOptions
defaultEmptyCaseOptions
makeFrom0Options :: EmptyCaseOptions -> Name -> Q Exp
makeFrom0Options :: KindSigOptions -> Name -> ExpQ
makeFrom0Options = (GenericTvbs
-> KindSigOptions -> Name -> [ConstructorInfo] -> Q Match)
-> GenericClass -> KindSigOptions -> Name -> ExpQ
makeFunCommon GenericTvbs
-> KindSigOptions -> Name -> [ConstructorInfo] -> Q Match
mkFrom GenericClass
Generic
makeTo :: Name -> Q Exp
makeTo :: Name -> ExpQ
makeTo = Name -> ExpQ
makeTo0
makeTo0 :: Name -> Q Exp
makeTo0 :: Name -> ExpQ
makeTo0 = KindSigOptions -> Name -> ExpQ
makeTo0Options KindSigOptions
defaultEmptyCaseOptions
makeTo0Options :: EmptyCaseOptions -> Name -> Q Exp
makeTo0Options :: KindSigOptions -> Name -> ExpQ
makeTo0Options = (GenericTvbs
-> KindSigOptions -> Name -> [ConstructorInfo] -> Q Match)
-> GenericClass -> KindSigOptions -> Name -> ExpQ
makeFunCommon GenericTvbs
-> KindSigOptions -> Name -> [ConstructorInfo] -> Q Match
mkTo GenericClass
Generic
makeFrom1 :: Name -> Q Exp
makeFrom1 :: Name -> ExpQ
makeFrom1 = KindSigOptions -> Name -> ExpQ
makeFrom1Options KindSigOptions
defaultEmptyCaseOptions
makeFrom1Options :: EmptyCaseOptions -> Name -> Q Exp
makeFrom1Options :: KindSigOptions -> Name -> ExpQ
makeFrom1Options = (GenericTvbs
-> KindSigOptions -> Name -> [ConstructorInfo] -> Q Match)
-> GenericClass -> KindSigOptions -> Name -> ExpQ
makeFunCommon GenericTvbs
-> KindSigOptions -> Name -> [ConstructorInfo] -> Q Match
mkFrom GenericClass
Generic1
makeTo1 :: Name -> Q Exp
makeTo1 :: Name -> ExpQ
makeTo1 = KindSigOptions -> Name -> ExpQ
makeTo1Options KindSigOptions
defaultEmptyCaseOptions
makeTo1Options :: EmptyCaseOptions -> Name -> Q Exp
makeTo1Options :: KindSigOptions -> Name -> ExpQ
makeTo1Options = (GenericTvbs
-> KindSigOptions -> Name -> [ConstructorInfo] -> Q Match)
-> GenericClass -> KindSigOptions -> Name -> ExpQ
makeFunCommon GenericTvbs
-> KindSigOptions -> Name -> [ConstructorInfo] -> Q Match
mkTo GenericClass
Generic1
makeFunCommon
:: (GenericTvbs -> EmptyCaseOptions -> Name -> [ConstructorInfo] -> Q Match)
-> GenericClass -> EmptyCaseOptions -> Name -> Q Exp
makeFunCommon :: (GenericTvbs
-> KindSigOptions -> Name -> [ConstructorInfo] -> Q Match)
-> GenericClass -> KindSigOptions -> Name -> ExpQ
makeFunCommon GenericTvbs
-> KindSigOptions -> Name -> [ConstructorInfo] -> Q Match
maker GenericClass
gClass KindSigOptions
ecOptions Name
n = do
Either String (Name, [Type], [ConstructorInfo], DatatypeVariant_)
i <- Name
-> Q (Either
String (Name, [Type], [ConstructorInfo], DatatypeVariant_))
reifyDataInfo Name
n
let (Name
name, [Type]
instTys, [ConstructorInfo]
cons, DatatypeVariant_
_) = (String -> (Name, [Type], [ConstructorInfo], DatatypeVariant_))
-> ((Name, [Type], [ConstructorInfo], DatatypeVariant_)
-> (Name, [Type], [ConstructorInfo], DatatypeVariant_))
-> Either
String (Name, [Type], [ConstructorInfo], DatatypeVariant_)
-> (Name, [Type], [ConstructorInfo], DatatypeVariant_)
forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either String -> (Name, [Type], [ConstructorInfo], DatatypeVariant_)
forall a. HasCallStack => String -> a
error (Name, [Type], [ConstructorInfo], DatatypeVariant_)
-> (Name, [Type], [ConstructorInfo], DatatypeVariant_)
forall a. a -> a
id Either String (Name, [Type], [ConstructorInfo], DatatypeVariant_)
i
gt :: GenericTvbs
gt = GenericClass -> [Type] -> GenericTvbs
mkGenericTvbs GenericClass
gClass [Type]
instTys
GenericClass -> KindSigOptions -> Name -> [Type] -> Q (Type, Type)
buildTypeInstance GenericClass
gClass KindSigOptions
False Name
name [Type]
instTys
Q (Type, Type) -> ExpQ -> ExpQ
`seq` Q Match -> ExpQ
mkCaseExp (GenericTvbs
-> KindSigOptions -> Name -> [ConstructorInfo] -> Q Match
maker GenericTvbs
gt KindSigOptions
ecOptions Name
name [ConstructorInfo]
cons)
genRepName :: GenericClass -> DatatypeVariant_
-> Name -> Name
genRepName :: GenericClass -> DatatypeVariant_ -> Name -> Name
genRepName GenericClass
gClass DatatypeVariant_
dv Name
n
= String -> Name
mkName
(String -> Name) -> ShowS -> String -> Name
forall b c a. (b -> c) -> (a -> b) -> a -> c
. DatatypeVariant_ -> ShowS
showsDatatypeVariant DatatypeVariant_
dv
ShowS -> ShowS -> ShowS
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ((String
"Rep" String -> ShowS
forall a. [a] -> [a] -> [a]
++ Int -> String
forall a. Show a => a -> String
show (GenericClass -> Int
forall a. Enum a => a -> Int
fromEnum GenericClass
gClass)) String -> ShowS
forall a. [a] -> [a] -> [a]
++)
ShowS -> ShowS -> ShowS
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ((Name -> String
showNameQual Name
n String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
"_") String -> ShowS
forall a. [a] -> [a] -> [a]
++)
ShowS -> ShowS -> ShowS
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ShowS
sanitizeName
(String -> Name) -> String -> Name
forall a b. (a -> b) -> a -> b
$ Name -> String
nameBase Name
n
repType :: GenericTvbs
-> DatatypeVariant_
-> Name
-> TypeSubst
-> [ConstructorInfo]
-> Q Type
repType :: GenericTvbs
-> DatatypeVariant_
-> Name
-> TypeSubst
-> [ConstructorInfo]
-> TypeQ
repType GenericTvbs
gt DatatypeVariant_
dv Name
dt TypeSubst
typeSubst [ConstructorInfo]
cs =
Name -> TypeQ
conT Name
d1TypeName TypeQ -> TypeQ -> TypeQ
`appT` DatatypeVariant_ -> Name -> TypeQ
mkMetaDataType DatatypeVariant_
dv Name
dt TypeQ -> TypeQ -> TypeQ
`appT`
(TypeQ -> TypeQ -> TypeQ) -> TypeQ -> [TypeQ] -> TypeQ
forall a. (a -> a -> a) -> a -> [a] -> a
foldBal TypeQ -> TypeQ -> TypeQ
sum' (Name -> TypeQ
conT Name
v1TypeName) ((ConstructorInfo -> TypeQ) -> [ConstructorInfo] -> [TypeQ]
forall a b. (a -> b) -> [a] -> [b]
map (GenericTvbs
-> DatatypeVariant_
-> Name
-> TypeSubst
-> ConstructorInfo
-> TypeQ
repCon GenericTvbs
gt DatatypeVariant_
dv Name
dt TypeSubst
typeSubst) [ConstructorInfo]
cs)
where
sum' :: Q Type -> Q Type -> Q Type
sum' :: TypeQ -> TypeQ -> TypeQ
sum' TypeQ
a TypeQ
b = Name -> TypeQ
conT Name
sumTypeName TypeQ -> TypeQ -> TypeQ
`appT` TypeQ
a TypeQ -> TypeQ -> TypeQ
`appT` TypeQ
b
repCon :: GenericTvbs
-> DatatypeVariant_
-> Name
-> TypeSubst
-> ConstructorInfo
-> Q Type
repCon :: GenericTvbs
-> DatatypeVariant_
-> Name
-> TypeSubst
-> ConstructorInfo
-> TypeQ
repCon GenericTvbs
gt DatatypeVariant_
dv Name
dt TypeSubst
typeSubst
(ConstructorInfo { constructorName :: ConstructorInfo -> Name
constructorName = Name
n
, constructorVars :: ConstructorInfo -> [TyVarBndrUnit]
constructorVars = [TyVarBndrUnit]
vars
, constructorContext :: ConstructorInfo -> [Type]
constructorContext = [Type]
ctxt
, constructorStrictness :: ConstructorInfo -> [FieldStrictness]
constructorStrictness = [FieldStrictness]
bangs
, constructorFields :: ConstructorInfo -> [Type]
constructorFields = [Type]
ts
, constructorVariant :: ConstructorInfo -> ConstructorVariant
constructorVariant = ConstructorVariant
cv
}) = do
Name -> [TyVarBndrUnit] -> [Type] -> Q ()
checkExistentialContext Name
n [TyVarBndrUnit]
vars [Type]
ctxt
let mbSelNames :: Maybe [Name]
mbSelNames = case ConstructorVariant
cv of
ConstructorVariant
NormalConstructor -> Maybe [Name]
forall a. Maybe a
Nothing
ConstructorVariant
InfixConstructor -> Maybe [Name]
forall a. Maybe a
Nothing
RecordConstructor [Name]
selNames -> [Name] -> Maybe [Name]
forall a. a -> Maybe a
Just [Name]
selNames
isRecord :: KindSigOptions
isRecord = case ConstructorVariant
cv of
ConstructorVariant
NormalConstructor -> KindSigOptions
False
ConstructorVariant
InfixConstructor -> KindSigOptions
False
RecordConstructor [Name]
_ -> KindSigOptions
True
isInfix :: KindSigOptions
isInfix = case ConstructorVariant
cv of
ConstructorVariant
NormalConstructor -> KindSigOptions
False
ConstructorVariant
InfixConstructor -> KindSigOptions
True
RecordConstructor [Name]
_ -> KindSigOptions
False
[SelStrictInfo]
ssis <- Name -> [FieldStrictness] -> Q [SelStrictInfo]
reifySelStrictInfo Name
n [FieldStrictness]
bangs
GenericTvbs
-> DatatypeVariant_
-> Name
-> Name
-> TypeSubst
-> Maybe [Name]
-> [SelStrictInfo]
-> [Type]
-> KindSigOptions
-> KindSigOptions
-> TypeQ
repConWith GenericTvbs
gt DatatypeVariant_
dv Name
dt Name
n TypeSubst
typeSubst Maybe [Name]
mbSelNames [SelStrictInfo]
ssis [Type]
ts KindSigOptions
isRecord KindSigOptions
isInfix
repConWith :: GenericTvbs
-> DatatypeVariant_
-> Name
-> Name
-> TypeSubst
-> Maybe [Name]
-> [SelStrictInfo]
-> [Type]
-> Bool
-> Bool
-> Q Type
repConWith :: GenericTvbs
-> DatatypeVariant_
-> Name
-> Name
-> TypeSubst
-> Maybe [Name]
-> [SelStrictInfo]
-> [Type]
-> KindSigOptions
-> KindSigOptions
-> TypeQ
repConWith GenericTvbs
gt DatatypeVariant_
dv Name
dt Name
n TypeSubst
typeSubst Maybe [Name]
mbSelNames [SelStrictInfo]
ssis [Type]
ts KindSigOptions
isRecord KindSigOptions
isInfix = do
let structureType :: Q Type
structureType :: TypeQ
structureType = (TypeQ -> TypeQ -> TypeQ) -> TypeQ -> [TypeQ] -> TypeQ
forall a. (a -> a -> a) -> a -> [a] -> a
foldBal TypeQ -> TypeQ -> TypeQ
prodT (Name -> TypeQ
conT Name
u1TypeName) [TypeQ]
f
f :: [Q Type]
f :: [TypeQ]
f = case Maybe [Name]
mbSelNames of
Just [Name]
selNames -> (Name -> SelStrictInfo -> Type -> TypeQ)
-> [Name] -> [SelStrictInfo] -> [Type] -> [TypeQ]
forall a b c d. (a -> b -> c -> d) -> [a] -> [b] -> [c] -> [d]
zipWith3 (GenericTvbs
-> DatatypeVariant_
-> Name
-> Name
-> TypeSubst
-> Maybe Name
-> SelStrictInfo
-> Type
-> TypeQ
repField GenericTvbs
gt DatatypeVariant_
dv Name
dt Name
n TypeSubst
typeSubst (Maybe Name -> SelStrictInfo -> Type -> TypeQ)
-> (Name -> Maybe Name) -> Name -> SelStrictInfo -> Type -> TypeQ
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Name -> Maybe Name
forall a. a -> Maybe a
Just)
[Name]
selNames [SelStrictInfo]
ssis [Type]
ts
Maybe [Name]
Nothing -> (SelStrictInfo -> Type -> TypeQ)
-> [SelStrictInfo] -> [Type] -> [TypeQ]
forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith (GenericTvbs
-> DatatypeVariant_
-> Name
-> Name
-> TypeSubst
-> Maybe Name
-> SelStrictInfo
-> Type
-> TypeQ
repField GenericTvbs
gt DatatypeVariant_
dv Name
dt Name
n TypeSubst
typeSubst Maybe Name
forall a. Maybe a
Nothing)
[SelStrictInfo]
ssis [Type]
ts
Name -> TypeQ
conT Name
c1TypeName
TypeQ -> TypeQ -> TypeQ
`appT` DatatypeVariant_
-> Name -> Name -> KindSigOptions -> KindSigOptions -> TypeQ
mkMetaConsType DatatypeVariant_
dv Name
dt Name
n KindSigOptions
isRecord KindSigOptions
isInfix
TypeQ -> TypeQ -> TypeQ
`appT` TypeQ
structureType
prodT :: Q Type -> Q Type -> Q Type
prodT :: TypeQ -> TypeQ -> TypeQ
prodT TypeQ
a TypeQ
b = Name -> TypeQ
conT Name
productTypeName TypeQ -> TypeQ -> TypeQ
`appT` TypeQ
a TypeQ -> TypeQ -> TypeQ
`appT` TypeQ
b
repField :: GenericTvbs
-> DatatypeVariant_
-> Name
-> Name
-> TypeSubst
-> Maybe Name
-> SelStrictInfo
-> Type
-> Q Type
repField :: GenericTvbs
-> DatatypeVariant_
-> Name
-> Name
-> TypeSubst
-> Maybe Name
-> SelStrictInfo
-> Type
-> TypeQ
repField GenericTvbs
gt DatatypeVariant_
dv Name
dt Name
ns TypeSubst
typeSubst Maybe Name
mbF SelStrictInfo
ssi Type
t =
Name -> TypeQ
conT Name
s1TypeName
TypeQ -> TypeQ -> TypeQ
`appT` DatatypeVariant_
-> Name -> Name -> Maybe Name -> SelStrictInfo -> TypeQ
mkMetaSelType DatatypeVariant_
dv Name
dt Name
ns Maybe Name
mbF SelStrictInfo
ssi
TypeQ -> TypeQ -> TypeQ
`appT` (GenericTvbs -> Type -> TypeQ
repFieldArg GenericTvbs
gt (Type -> TypeQ) -> TypeQ -> TypeQ
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< Type -> TypeQ
resolveTypeSynonyms Type
t'')
where
t', t'' :: Type
t' :: Type
t' = case GenericTvbs
gt of
Gen1{gen1LastTvbKindVar :: GenericTvbs -> Maybe Name
gen1LastTvbKindVar = Just Name
_kvName} ->
#if MIN_VERSION_base(4,10,0)
Type
t
#else
substNameWithKind _kvName starK t
#endif
GenericTvbs
_ -> Type
t
t'' :: Type
t'' = TypeSubst -> Type -> Type
forall a. TypeSubstitution a => TypeSubst -> a -> a
applySubstitution TypeSubst
typeSubst Type
t'
repFieldArg :: GenericTvbs -> Type -> Q Type
repFieldArg :: GenericTvbs -> Type -> TypeQ
repFieldArg Gen0{} Type
t = Type -> TypeQ
boxT Type
t
repFieldArg (Gen1{gen1LastTvbName :: GenericTvbs -> Name
gen1LastTvbName = Name
name}) (Type -> Type
dustOff -> Type
t0) =
Type -> Q (ArgRes Type)
go Type
t0 Q (ArgRes Type) -> (ArgRes Type -> TypeQ) -> TypeQ
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \ArgRes Type
res -> case ArgRes Type
res of
ArgRes Type
NoPar -> Type -> TypeQ
boxT Type
t0
ArgRes KindSigOptions
_ Type
r -> Type -> TypeQ
forall (m :: * -> *) a. Monad m => a -> m a
return Type
r
where
go :: Type -> Q (ArgRes Type)
go :: Type -> Q (ArgRes Type)
go ForallT{} = Q (ArgRes Type)
forall a. Q a
rankNError
#if MIN_VERSION_template_haskell(2,16,0)
go ForallVisT{} = Q (ArgRes Type)
forall a. Q a
rankNError
#endif
go (VarT Name
t) | Name
t Name -> Name -> KindSigOptions
forall a. Eq a => a -> a -> KindSigOptions
== Name
name = KindSigOptions -> Type -> ArgRes Type
forall a. KindSigOptions -> a -> ArgRes a
ArgRes KindSigOptions
True (Type -> ArgRes Type) -> TypeQ -> Q (ArgRes Type)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
`fmap` Name -> TypeQ
conT Name
par1TypeName
go (AppT Type
f Type
x) = do
KindSigOptions -> Q () -> Q ()
forall (f :: * -> *).
Applicative f =>
KindSigOptions -> f () -> f ()
when (KindSigOptions -> KindSigOptions
not (Type
f Type -> Name -> KindSigOptions
`ground` Name
name)) Q ()
forall a. Q a
outOfPlaceTyVarError
ArgRes Type
mxr <- Type -> Q (ArgRes Type)
go (Type -> Type
dustOff Type
x)
case ArgRes Type
mxr of
ArgRes Type
NoPar -> ArgRes Type -> Q (ArgRes Type)
forall (m :: * -> *) a. Monad m => a -> m a
return ArgRes Type
forall a. ArgRes a
NoPar
ArgRes KindSigOptions
arg_is_param Type
xr -> do
KindSigOptions
itf <- Type -> Q KindSigOptions
isUnsaturatedType Type
f
KindSigOptions -> Q () -> Q ()
forall (f :: * -> *).
Applicative f =>
KindSigOptions -> f () -> f ()
when KindSigOptions
itf Q ()
forall a. Q a
typeFamilyApplicationError
KindSigOptions -> Type -> ArgRes Type
forall a. KindSigOptions -> a -> ArgRes a
ArgRes KindSigOptions
False (Type -> ArgRes Type) -> TypeQ -> Q (ArgRes Type)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
`fmap`
if KindSigOptions
arg_is_param
then
Name -> TypeQ
conT Name
rec1TypeName TypeQ -> TypeQ -> TypeQ
`appT` Type -> TypeQ
forall (m :: * -> *) a. Monad m => a -> m a
return Type
f
else
Name -> TypeQ
conT Name
composeTypeName TypeQ -> TypeQ -> TypeQ
`appT` Type -> TypeQ
forall (m :: * -> *) a. Monad m => a -> m a
return Type
f TypeQ -> TypeQ -> TypeQ
`appT` Type -> TypeQ
forall (m :: * -> *) a. Monad m => a -> m a
return Type
xr
go Type
_ = ArgRes Type -> Q (ArgRes Type)
forall (m :: * -> *) a. Monad m => a -> m a
return ArgRes Type
forall a. ArgRes a
NoPar
data ArgRes a = NoPar | ArgRes !Bool a
boxT :: Type -> Q Type
boxT :: Type -> TypeQ
boxT Type
ty = case Type -> Maybe (Name, Name, Name)
unboxedRepNames Type
ty of
Just (Name
boxTyName, Name
_, Name
_) -> Name -> TypeQ
conT Name
boxTyName
Maybe (Name, Name, Name)
Nothing -> Name -> TypeQ
conT Name
rec0TypeName TypeQ -> TypeQ -> TypeQ
`appT` Type -> TypeQ
forall (m :: * -> *) a. Monad m => a -> m a
return Type
ty
mkCaseExp :: Q Match -> Q Exp
mkCaseExp :: Q Match -> ExpQ
mkCaseExp Q Match
qMatch = do
Name
val <- String -> Q Name
newName String
"val"
PatQ -> ExpQ -> ExpQ
lam1E (Name -> PatQ
varP Name
val) (ExpQ -> ExpQ) -> ExpQ -> ExpQ
forall a b. (a -> b) -> a -> b
$ ExpQ -> [Q Match] -> ExpQ
caseE (Name -> ExpQ
varE Name
val) [Q Match
qMatch]
mkFrom :: GenericTvbs -> EmptyCaseOptions -> Name
-> [ConstructorInfo] -> Q Match
mkFrom :: GenericTvbs
-> KindSigOptions -> Name -> [ConstructorInfo] -> Q Match
mkFrom GenericTvbs
gt KindSigOptions
ecOptions Name
dt [ConstructorInfo]
cs = do
Name
y <- String -> Q Name
newName String
"y"
PatQ -> BodyQ -> [Q Dec] -> Q Match
match (Name -> PatQ
varP Name
y)
(ExpQ -> BodyQ
normalB (ExpQ -> BodyQ) -> ExpQ -> BodyQ
forall a b. (a -> b) -> a -> b
$ Name -> ExpQ
conE Name
m1DataName ExpQ -> ExpQ -> ExpQ
`appE` ExpQ -> [Q Match] -> ExpQ
caseE (Name -> ExpQ
varE Name
y) [Q Match]
cases)
[]
where
cases :: [Q Match]
cases = case [ConstructorInfo]
cs of
[] -> KindSigOptions -> Name -> [Q Match]
errorFrom KindSigOptions
ecOptions Name
dt
[ConstructorInfo]
_ -> (Int -> ConstructorInfo -> Q Match)
-> [Int] -> [ConstructorInfo] -> [Q Match]
forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith (GenericTvbs
-> (ExpQ -> ExpQ) -> Int -> Int -> ConstructorInfo -> Q Match
fromCon GenericTvbs
gt ExpQ -> ExpQ
forall a. a -> a
id ([ConstructorInfo] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [ConstructorInfo]
cs)) [Int
1..] [ConstructorInfo]
cs
errorFrom :: EmptyCaseOptions -> Name -> [Q Match]
errorFrom :: KindSigOptions -> Name -> [Q Match]
errorFrom KindSigOptions
useEmptyCase Name
dt
| KindSigOptions
useEmptyCase KindSigOptions -> KindSigOptions -> KindSigOptions
&& KindSigOptions
ghc7'8OrLater
= []
| KindSigOptions
otherwise
= [do Name
z <- String -> Q Name
newName String
"z"
PatQ -> BodyQ -> [Q Dec] -> Q Match
match
(Name -> PatQ
varP Name
z)
(ExpQ -> BodyQ
normalB (ExpQ -> BodyQ) -> ExpQ -> BodyQ
forall a b. (a -> b) -> a -> b
$
ExpQ -> ExpQ -> ExpQ
appE (Name -> ExpQ
varE Name
seqValName) (Name -> ExpQ
varE Name
z) ExpQ -> ExpQ -> ExpQ
`appE`
ExpQ -> ExpQ -> ExpQ
appE (Name -> ExpQ
varE Name
errorValName)
(String -> ExpQ
stringE (String -> ExpQ) -> String -> ExpQ
forall a b. (a -> b) -> a -> b
$ String
"No generic representation for empty datatype "
String -> ShowS
forall a. [a] -> [a] -> [a]
++ Name -> String
nameBase Name
dt))
[]]
mkTo :: GenericTvbs -> EmptyCaseOptions -> Name
-> [ConstructorInfo] -> Q Match
mkTo :: GenericTvbs
-> KindSigOptions -> Name -> [ConstructorInfo] -> Q Match
mkTo GenericTvbs
gt KindSigOptions
ecOptions Name
dt [ConstructorInfo]
cs = do
Name
y <- String -> Q Name
newName String
"y"
PatQ -> BodyQ -> [Q Dec] -> Q Match
match (Name -> [PatQ] -> PatQ
conP Name
m1DataName [Name -> PatQ
varP Name
y])
(ExpQ -> BodyQ
normalB (ExpQ -> BodyQ) -> ExpQ -> BodyQ
forall a b. (a -> b) -> a -> b
$ ExpQ -> [Q Match] -> ExpQ
caseE (Name -> ExpQ
varE Name
y) [Q Match]
cases)
[]
where
cases :: [Q Match]
cases = case [ConstructorInfo]
cs of
[] -> KindSigOptions -> Name -> [Q Match]
errorTo KindSigOptions
ecOptions Name
dt
[ConstructorInfo]
_ -> (Int -> ConstructorInfo -> Q Match)
-> [Int] -> [ConstructorInfo] -> [Q Match]
forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith (GenericTvbs
-> (PatQ -> PatQ) -> Int -> Int -> ConstructorInfo -> Q Match
toCon GenericTvbs
gt PatQ -> PatQ
forall a. a -> a
id ([ConstructorInfo] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [ConstructorInfo]
cs)) [Int
1..] [ConstructorInfo]
cs
errorTo :: EmptyCaseOptions -> Name -> [Q Match]
errorTo :: KindSigOptions -> Name -> [Q Match]
errorTo KindSigOptions
useEmptyCase Name
dt
| KindSigOptions
useEmptyCase KindSigOptions -> KindSigOptions -> KindSigOptions
&& KindSigOptions
ghc7'8OrLater
= []
| KindSigOptions
otherwise
= [do Name
z <- String -> Q Name
newName String
"z"
PatQ -> BodyQ -> [Q Dec] -> Q Match
match
(Name -> PatQ
varP Name
z)
(ExpQ -> BodyQ
normalB (ExpQ -> BodyQ) -> ExpQ -> BodyQ
forall a b. (a -> b) -> a -> b
$
ExpQ -> ExpQ -> ExpQ
appE (Name -> ExpQ
varE Name
seqValName) (Name -> ExpQ
varE Name
z) ExpQ -> ExpQ -> ExpQ
`appE`
ExpQ -> ExpQ -> ExpQ
appE (Name -> ExpQ
varE Name
errorValName)
(String -> ExpQ
stringE (String -> ExpQ) -> String -> ExpQ
forall a b. (a -> b) -> a -> b
$ String
"No values for empty datatype " String -> ShowS
forall a. [a] -> [a] -> [a]
++ Name -> String
nameBase Name
dt))
[]]
ghc7'8OrLater :: Bool
#if __GLASGOW_HASKELL__ >= 708
ghc7'8OrLater :: KindSigOptions
ghc7'8OrLater = KindSigOptions
True
#else
ghc7'8OrLater = False
#endif
fromCon :: GenericTvbs -> (Q Exp -> Q Exp) -> Int -> Int
-> ConstructorInfo -> Q Match
fromCon :: GenericTvbs
-> (ExpQ -> ExpQ) -> Int -> Int -> ConstructorInfo -> Q Match
fromCon GenericTvbs
gt ExpQ -> ExpQ
wrap Int
m Int
i
(ConstructorInfo { constructorName :: ConstructorInfo -> Name
constructorName = Name
cn
, constructorVars :: ConstructorInfo -> [TyVarBndrUnit]
constructorVars = [TyVarBndrUnit]
vars
, constructorContext :: ConstructorInfo -> [Type]
constructorContext = [Type]
ctxt
, constructorFields :: ConstructorInfo -> [Type]
constructorFields = [Type]
ts
}) = do
Name -> [TyVarBndrUnit] -> [Type] -> Q ()
checkExistentialContext Name
cn [TyVarBndrUnit]
vars [Type]
ctxt
[Name]
fNames <- String -> Int -> Q [Name]
newNameList String
"f" (Int -> Q [Name]) -> Int -> Q [Name]
forall a b. (a -> b) -> a -> b
$ [Type] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [Type]
ts
PatQ -> BodyQ -> [Q Dec] -> Q Match
match (Name -> [PatQ] -> PatQ
conP Name
cn ((Name -> PatQ) -> [Name] -> [PatQ]
forall a b. (a -> b) -> [a] -> [b]
map Name -> PatQ
varP [Name]
fNames))
(ExpQ -> BodyQ
normalB (ExpQ -> BodyQ) -> ExpQ -> BodyQ
forall a b. (a -> b) -> a -> b
$ ExpQ -> ExpQ
wrap (ExpQ -> ExpQ) -> ExpQ -> ExpQ
forall a b. (a -> b) -> a -> b
$ Int -> Int -> ExpQ -> ExpQ
lrE Int
i Int
m (ExpQ -> ExpQ) -> ExpQ -> ExpQ
forall a b. (a -> b) -> a -> b
$ Name -> ExpQ
conE Name
m1DataName ExpQ -> ExpQ -> ExpQ
`appE`
(ExpQ -> ExpQ -> ExpQ) -> ExpQ -> [ExpQ] -> ExpQ
forall a. (a -> a -> a) -> a -> [a] -> a
foldBal ExpQ -> ExpQ -> ExpQ
prodE (Name -> ExpQ
conE Name
u1DataName) ((Name -> Type -> ExpQ) -> [Name] -> [Type] -> [ExpQ]
forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith (GenericTvbs -> Name -> Type -> ExpQ
fromField GenericTvbs
gt) [Name]
fNames [Type]
ts)) []
prodE :: Q Exp -> Q Exp -> Q Exp
prodE :: ExpQ -> ExpQ -> ExpQ
prodE ExpQ
x ExpQ
y = Name -> ExpQ
conE Name
productDataName ExpQ -> ExpQ -> ExpQ
`appE` ExpQ
x ExpQ -> ExpQ -> ExpQ
`appE` ExpQ
y
fromField :: GenericTvbs -> Name -> Type -> Q Exp
fromField :: GenericTvbs -> Name -> Type -> ExpQ
fromField GenericTvbs
gt Name
nr Type
t = Name -> ExpQ
conE Name
m1DataName ExpQ -> ExpQ -> ExpQ
`appE` (GenericTvbs -> Name -> Type -> ExpQ
fromFieldWrap GenericTvbs
gt Name
nr (Type -> ExpQ) -> TypeQ -> ExpQ
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< Type -> TypeQ
resolveTypeSynonyms Type
t)
fromFieldWrap :: GenericTvbs -> Name -> Type -> Q Exp
fromFieldWrap :: GenericTvbs -> Name -> Type -> ExpQ
fromFieldWrap GenericTvbs
_ Name
_ ForallT{} = ExpQ
forall a. Q a
rankNError
fromFieldWrap GenericTvbs
gt Name
nr (SigT Type
t Type
_) = GenericTvbs -> Name -> Type -> ExpQ
fromFieldWrap GenericTvbs
gt Name
nr Type
t
fromFieldWrap Gen0{} Name
nr Type
t = Name -> ExpQ
conE (Type -> Name
boxRepName Type
t) ExpQ -> ExpQ -> ExpQ
`appE` Name -> ExpQ
varE Name
nr
fromFieldWrap (Gen1{gen1LastTvbName :: GenericTvbs -> Name
gen1LastTvbName = Name
name}) Name
nr Type
t = Type -> Name -> ExpQ
wC Type
t Name
name ExpQ -> ExpQ -> ExpQ
`appE` Name -> ExpQ
varE Name
nr
wC :: Type -> Name -> Q Exp
wC :: Type -> Name -> ExpQ
wC (Type -> Type
dustOff -> Type
t0) Name
name =
Type -> Q (ArgRes Exp)
go Type
t0 Q (ArgRes Exp) -> (ArgRes Exp -> ExpQ) -> ExpQ
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \ArgRes Exp
res -> case ArgRes Exp
res of
ArgRes Exp
NoPar -> Name -> ExpQ
conE (Name -> ExpQ) -> Name -> ExpQ
forall a b. (a -> b) -> a -> b
$ Type -> Name
boxRepName Type
t0
ArgRes KindSigOptions
_ Exp
r -> Exp -> ExpQ
forall (m :: * -> *) a. Monad m => a -> m a
return Exp
r
where
go :: Type -> Q (ArgRes Exp)
go :: Type -> Q (ArgRes Exp)
go ForallT{} = Q (ArgRes Exp)
forall a. Q a
rankNError
#if MIN_VERSION_template_haskell(2,16,0)
go ForallVisT{} = Q (ArgRes Exp)
forall a. Q a
rankNError
#endif
go (VarT Name
t) | Name
t Name -> Name -> KindSigOptions
forall a. Eq a => a -> a -> KindSigOptions
== Name
name = KindSigOptions -> Exp -> ArgRes Exp
forall a. KindSigOptions -> a -> ArgRes a
ArgRes KindSigOptions
True (Exp -> ArgRes Exp) -> ExpQ -> Q (ArgRes Exp)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
`fmap` Name -> ExpQ
conE Name
par1DataName
go (AppT Type
f Type
x) = do
KindSigOptions -> Q () -> Q ()
forall (f :: * -> *).
Applicative f =>
KindSigOptions -> f () -> f ()
when (KindSigOptions -> KindSigOptions
not (Type
f Type -> Name -> KindSigOptions
`ground` Name
name)) Q ()
forall a. Q a
outOfPlaceTyVarError
ArgRes Exp
mxr <- Type -> Q (ArgRes Exp)
go (Type -> Type
dustOff Type
x)
case ArgRes Exp
mxr of
ArgRes Exp
NoPar -> ArgRes Exp -> Q (ArgRes Exp)
forall (m :: * -> *) a. Monad m => a -> m a
return ArgRes Exp
forall a. ArgRes a
NoPar
ArgRes KindSigOptions
arg_is_param Exp
xr -> do
KindSigOptions
itf <- Type -> Q KindSigOptions
isUnsaturatedType Type
f
KindSigOptions -> Q () -> Q ()
forall (f :: * -> *).
Applicative f =>
KindSigOptions -> f () -> f ()
when KindSigOptions
itf Q ()
forall a. Q a
typeFamilyApplicationError
KindSigOptions -> Exp -> ArgRes Exp
forall a. KindSigOptions -> a -> ArgRes a
ArgRes KindSigOptions
False (Exp -> ArgRes Exp) -> ExpQ -> Q (ArgRes Exp)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
`fmap`
if KindSigOptions
arg_is_param
then
Name -> ExpQ
conE Name
rec1DataName
else
ExpQ -> ExpQ -> ExpQ -> ExpQ
infixApp (Name -> ExpQ
conE Name
comp1DataName) (Name -> ExpQ
varE Name
composeValName) (Name -> ExpQ
varE Name
fmapValName ExpQ -> ExpQ -> ExpQ
`appE` Exp -> ExpQ
forall (m :: * -> *) a. Monad m => a -> m a
return Exp
xr)
go Type
_ = ArgRes Exp -> Q (ArgRes Exp)
forall (m :: * -> *) a. Monad m => a -> m a
return ArgRes Exp
forall a. ArgRes a
NoPar
boxRepName :: Type -> Name
boxRepName :: Type -> Name
boxRepName = Name
-> ((Name, Name, Name) -> Name) -> Maybe (Name, Name, Name) -> Name
forall b a. b -> (a -> b) -> Maybe a -> b
maybe Name
k1DataName (Name, Name, Name) -> Name
forall a b c. (a, b, c) -> b
snd3 (Maybe (Name, Name, Name) -> Name)
-> (Type -> Maybe (Name, Name, Name)) -> Type -> Name
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Type -> Maybe (Name, Name, Name)
unboxedRepNames
toCon :: GenericTvbs -> (Q Pat -> Q Pat) -> Int -> Int
-> ConstructorInfo -> Q Match
toCon :: GenericTvbs
-> (PatQ -> PatQ) -> Int -> Int -> ConstructorInfo -> Q Match
toCon GenericTvbs
gt PatQ -> PatQ
wrap Int
m Int
i
(ConstructorInfo { constructorName :: ConstructorInfo -> Name
constructorName = Name
cn
, constructorVars :: ConstructorInfo -> [TyVarBndrUnit]
constructorVars = [TyVarBndrUnit]
vars
, constructorContext :: ConstructorInfo -> [Type]
constructorContext = [Type]
ctxt
, constructorFields :: ConstructorInfo -> [Type]
constructorFields = [Type]
ts
}) = do
Name -> [TyVarBndrUnit] -> [Type] -> Q ()
checkExistentialContext Name
cn [TyVarBndrUnit]
vars [Type]
ctxt
[Name]
fNames <- String -> Int -> Q [Name]
newNameList String
"f" (Int -> Q [Name]) -> Int -> Q [Name]
forall a b. (a -> b) -> a -> b
$ [Type] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [Type]
ts
PatQ -> BodyQ -> [Q Dec] -> Q Match
match (PatQ -> PatQ
wrap (PatQ -> PatQ) -> PatQ -> PatQ
forall a b. (a -> b) -> a -> b
$ Int -> Int -> PatQ -> PatQ
lrP Int
i Int
m (PatQ -> PatQ) -> PatQ -> PatQ
forall a b. (a -> b) -> a -> b
$ Name -> [PatQ] -> PatQ
conP Name
m1DataName
[(PatQ -> PatQ -> PatQ) -> PatQ -> [PatQ] -> PatQ
forall a. (a -> a -> a) -> a -> [a] -> a
foldBal PatQ -> PatQ -> PatQ
prod (Name -> [PatQ] -> PatQ
conP Name
u1DataName []) ((Name -> Type -> PatQ) -> [Name] -> [Type] -> [PatQ]
forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith (GenericTvbs -> Name -> Type -> PatQ
toField GenericTvbs
gt) [Name]
fNames [Type]
ts)])
(ExpQ -> BodyQ
normalB (ExpQ -> BodyQ) -> ExpQ -> BodyQ
forall a b. (a -> b) -> a -> b
$ (ExpQ -> ExpQ -> ExpQ) -> ExpQ -> [ExpQ] -> ExpQ
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl ExpQ -> ExpQ -> ExpQ
appE (Name -> ExpQ
conE Name
cn)
((Name -> Type -> ExpQ) -> [Name] -> [Type] -> [ExpQ]
forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith (\Name
nr -> Type -> TypeQ
resolveTypeSynonyms (Type -> TypeQ) -> (Type -> ExpQ) -> Type -> ExpQ
forall (m :: * -> *) a b c.
Monad m =>
(a -> m b) -> (b -> m c) -> a -> m c
>=> GenericTvbs -> Name -> Type -> ExpQ
toConUnwC GenericTvbs
gt Name
nr)
[Name]
fNames [Type]
ts)) []
where prod :: PatQ -> PatQ -> PatQ
prod PatQ
x PatQ
y = Name -> [PatQ] -> PatQ
conP Name
productDataName [PatQ
x,PatQ
y]
toConUnwC :: GenericTvbs -> Name -> Type -> Q Exp
toConUnwC :: GenericTvbs -> Name -> Type -> ExpQ
toConUnwC Gen0{} Name
nr Type
_ = Name -> ExpQ
varE Name
nr
toConUnwC (Gen1{gen1LastTvbName :: GenericTvbs -> Name
gen1LastTvbName = Name
name}) Name
nr Type
t = Type -> Name -> ExpQ
unwC Type
t Name
name ExpQ -> ExpQ -> ExpQ
`appE` Name -> ExpQ
varE Name
nr
toField :: GenericTvbs -> Name -> Type -> Q Pat
toField :: GenericTvbs -> Name -> Type -> PatQ
toField GenericTvbs
gt Name
nr Type
t = Name -> [PatQ] -> PatQ
conP Name
m1DataName [GenericTvbs -> Name -> Type -> PatQ
toFieldWrap GenericTvbs
gt Name
nr Type
t]
toFieldWrap :: GenericTvbs -> Name -> Type -> Q Pat
toFieldWrap :: GenericTvbs -> Name -> Type -> PatQ
toFieldWrap Gen0{} Name
nr Type
t = Name -> [PatQ] -> PatQ
conP (Type -> Name
boxRepName Type
t) [Name -> PatQ
varP Name
nr]
toFieldWrap Gen1{} Name
nr Type
_ = Name -> PatQ
varP Name
nr
unwC :: Type -> Name -> Q Exp
unwC :: Type -> Name -> ExpQ
unwC (Type -> Type
dustOff -> Type
t0) Name
name =
Type -> Q (ArgRes Exp)
go Type
t0 Q (ArgRes Exp) -> (ArgRes Exp -> ExpQ) -> ExpQ
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \ArgRes Exp
res -> case ArgRes Exp
res of
ArgRes Exp
NoPar -> Name -> ExpQ
varE (Name -> ExpQ) -> Name -> ExpQ
forall a b. (a -> b) -> a -> b
$ Type -> Name
unboxRepName Type
t0
ArgRes KindSigOptions
_ Exp
r -> Exp -> ExpQ
forall (m :: * -> *) a. Monad m => a -> m a
return Exp
r
where
go :: Type -> Q (ArgRes Exp)
go :: Type -> Q (ArgRes Exp)
go ForallT{} = Q (ArgRes Exp)
forall a. Q a
rankNError
#if MIN_VERSION_template_haskell(2,16,0)
go ForallVisT{} = Q (ArgRes Exp)
forall a. Q a
rankNError
#endif
go (VarT Name
t) | Name
t Name -> Name -> KindSigOptions
forall a. Eq a => a -> a -> KindSigOptions
== Name
name = KindSigOptions -> Exp -> ArgRes Exp
forall a. KindSigOptions -> a -> ArgRes a
ArgRes KindSigOptions
True (Exp -> ArgRes Exp) -> ExpQ -> Q (ArgRes Exp)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
`fmap` Name -> ExpQ
varE Name
unPar1ValName
go (AppT Type
f Type
x) = do
KindSigOptions -> Q () -> Q ()
forall (f :: * -> *).
Applicative f =>
KindSigOptions -> f () -> f ()
when (KindSigOptions -> KindSigOptions
not (Type
f Type -> Name -> KindSigOptions
`ground` Name
name)) Q ()
forall a. Q a
outOfPlaceTyVarError
ArgRes Exp
mxr <- Type -> Q (ArgRes Exp)
go (Type -> Type
dustOff Type
x)
case ArgRes Exp
mxr of
ArgRes Exp
NoPar -> ArgRes Exp -> Q (ArgRes Exp)
forall (m :: * -> *) a. Monad m => a -> m a
return ArgRes Exp
forall a. ArgRes a
NoPar
ArgRes KindSigOptions
arg_is_param Exp
xr -> do
KindSigOptions
itf <- Type -> Q KindSigOptions
isUnsaturatedType Type
f
KindSigOptions -> Q () -> Q ()
forall (f :: * -> *).
Applicative f =>
KindSigOptions -> f () -> f ()
when KindSigOptions
itf Q ()
forall a. Q a
typeFamilyApplicationError
KindSigOptions -> Exp -> ArgRes Exp
forall a. KindSigOptions -> a -> ArgRes a
ArgRes KindSigOptions
False (Exp -> ArgRes Exp) -> ExpQ -> Q (ArgRes Exp)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
`fmap`
if KindSigOptions
arg_is_param
then
Name -> ExpQ
varE Name
unRec1ValName
else
ExpQ -> ExpQ -> ExpQ -> ExpQ
infixApp (Name -> ExpQ
varE Name
fmapValName ExpQ -> ExpQ -> ExpQ
`appE` Exp -> ExpQ
forall (m :: * -> *) a. Monad m => a -> m a
return Exp
xr)
(Name -> ExpQ
varE Name
composeValName)
(Name -> ExpQ
varE Name
unComp1ValName)
go Type
_ = ArgRes Exp -> Q (ArgRes Exp)
forall (m :: * -> *) a. Monad m => a -> m a
return ArgRes Exp
forall a. ArgRes a
NoPar
unboxRepName :: Type -> Name
unboxRepName :: Type -> Name
unboxRepName = Name
-> ((Name, Name, Name) -> Name) -> Maybe (Name, Name, Name) -> Name
forall b a. b -> (a -> b) -> Maybe a -> b
maybe Name
unK1ValName (Name, Name, Name) -> Name
forall a b c. (a, b, c) -> c
trd3 (Maybe (Name, Name, Name) -> Name)
-> (Type -> Maybe (Name, Name, Name)) -> Type -> Name
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Type -> Maybe (Name, Name, Name)
unboxedRepNames
lrP :: Int -> Int -> (Q Pat -> Q Pat)
lrP :: Int -> Int -> PatQ -> PatQ
lrP Int
i Int
n PatQ
p
| Int
n Int -> Int -> KindSigOptions
forall a. Eq a => a -> a -> KindSigOptions
== Int
0 = String -> PatQ
forall (m :: * -> *) a. MonadFail m => String -> m a
fail String
"lrP: impossible"
| Int
n Int -> Int -> KindSigOptions
forall a. Eq a => a -> a -> KindSigOptions
== Int
1 = PatQ
p
| Int
i Int -> Int -> KindSigOptions
forall a. Ord a => a -> a -> KindSigOptions
<= Int -> Int -> Int
forall a. Integral a => a -> a -> a
div Int
n Int
2 = Name -> [PatQ] -> PatQ
conP Name
l1DataName [Int -> Int -> PatQ -> PatQ
lrP Int
i (Int -> Int -> Int
forall a. Integral a => a -> a -> a
div Int
n Int
2) PatQ
p]
| KindSigOptions
otherwise = Name -> [PatQ] -> PatQ
conP Name
r1DataName [Int -> Int -> PatQ -> PatQ
lrP (Int
iInt -> Int -> Int
forall a. Num a => a -> a -> a
-Int
m) (Int
nInt -> Int -> Int
forall a. Num a => a -> a -> a
-Int
m) PatQ
p]
where m :: Int
m = Int -> Int -> Int
forall a. Integral a => a -> a -> a
div Int
n Int
2
lrE :: Int -> Int -> (Q Exp -> Q Exp)
lrE :: Int -> Int -> ExpQ -> ExpQ
lrE Int
i Int
n ExpQ
e
| Int
n Int -> Int -> KindSigOptions
forall a. Eq a => a -> a -> KindSigOptions
== Int
0 = String -> ExpQ
forall (m :: * -> *) a. MonadFail m => String -> m a
fail String
"lrE: impossible"
| Int
n Int -> Int -> KindSigOptions
forall a. Eq a => a -> a -> KindSigOptions
== Int
1 = ExpQ
e
| Int
i Int -> Int -> KindSigOptions
forall a. Ord a => a -> a -> KindSigOptions
<= Int -> Int -> Int
forall a. Integral a => a -> a -> a
div Int
n Int
2 = Name -> ExpQ
conE Name
l1DataName ExpQ -> ExpQ -> ExpQ
`appE` Int -> Int -> ExpQ -> ExpQ
lrE Int
i (Int -> Int -> Int
forall a. Integral a => a -> a -> a
div Int
n Int
2) ExpQ
e
| KindSigOptions
otherwise = Name -> ExpQ
conE Name
r1DataName ExpQ -> ExpQ -> ExpQ
`appE` Int -> Int -> ExpQ -> ExpQ
lrE (Int
iInt -> Int -> Int
forall a. Num a => a -> a -> a
-Int
m) (Int
nInt -> Int -> Int
forall a. Num a => a -> a -> a
-Int
m) ExpQ
e
where m :: Int
m = Int -> Int -> Int
forall a. Integral a => a -> a -> a
div Int
n Int
2
unboxedRepNames :: Type -> Maybe (Name, Name, Name)
unboxedRepNames :: Type -> Maybe (Name, Name, Name)
unboxedRepNames Type
ty
| Type
ty Type -> Type -> KindSigOptions
forall a. Eq a => a -> a -> KindSigOptions
== Name -> Type
ConT Name
addrHashTypeName = (Name, Name, Name) -> Maybe (Name, Name, Name)
forall a. a -> Maybe a
Just (Name
uAddrTypeName, Name
uAddrDataName, Name
uAddrHashValName)
| Type
ty Type -> Type -> KindSigOptions
forall a. Eq a => a -> a -> KindSigOptions
== Name -> Type
ConT Name
charHashTypeName = (Name, Name, Name) -> Maybe (Name, Name, Name)
forall a. a -> Maybe a
Just (Name
uCharTypeName, Name
uCharDataName, Name
uCharHashValName)
| Type
ty Type -> Type -> KindSigOptions
forall a. Eq a => a -> a -> KindSigOptions
== Name -> Type
ConT Name
doubleHashTypeName = (Name, Name, Name) -> Maybe (Name, Name, Name)
forall a. a -> Maybe a
Just (Name
uDoubleTypeName, Name
uDoubleDataName, Name
uDoubleHashValName)
| Type
ty Type -> Type -> KindSigOptions
forall a. Eq a => a -> a -> KindSigOptions
== Name -> Type
ConT Name
floatHashTypeName = (Name, Name, Name) -> Maybe (Name, Name, Name)
forall a. a -> Maybe a
Just (Name
uFloatTypeName, Name
uFloatDataName, Name
uFloatHashValName)
| Type
ty Type -> Type -> KindSigOptions
forall a. Eq a => a -> a -> KindSigOptions
== Name -> Type
ConT Name
intHashTypeName = (Name, Name, Name) -> Maybe (Name, Name, Name)
forall a. a -> Maybe a
Just (Name
uIntTypeName, Name
uIntDataName, Name
uIntHashValName)
| Type
ty Type -> Type -> KindSigOptions
forall a. Eq a => a -> a -> KindSigOptions
== Name -> Type
ConT Name
wordHashTypeName = (Name, Name, Name) -> Maybe (Name, Name, Name)
forall a. a -> Maybe a
Just (Name
uWordTypeName, Name
uWordDataName, Name
uWordHashValName)
| KindSigOptions
otherwise = Maybe (Name, Name, Name)
forall a. Maybe a
Nothing
buildTypeInstance :: GenericClass
-> KindSigOptions
-> Name
-> [Type]
-> Q (Type, Kind)
buildTypeInstance :: GenericClass -> KindSigOptions -> Name -> [Type] -> Q (Type, Type)
buildTypeInstance GenericClass
gClass KindSigOptions
useKindSigs Name
tyConName [Type]
varTysOrig = do
[Type]
varTysExp <- (Type -> TypeQ) -> [Type] -> CxtQ
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM Type -> TypeQ
resolveTypeSynonyms [Type]
varTysOrig
let remainingLength :: Int
remainingLength :: Int
remainingLength = [Type] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [Type]
varTysOrig Int -> Int -> Int
forall a. Num a => a -> a -> a
- GenericClass -> Int
forall a. Enum a => a -> Int
fromEnum GenericClass
gClass
#if !(MIN_VERSION_base(4,10,0))
droppedTysExp :: [Type]
droppedTysExp = drop remainingLength varTysExp
droppedStarKindStati :: [StarKindStatus]
droppedStarKindStati = map canRealizeKindStar droppedTysExp
#endif
KindSigOptions -> Q () -> Q ()
forall (f :: * -> *).
Applicative f =>
KindSigOptions -> f () -> f ()
when (Int
remainingLength Int -> Int -> KindSigOptions
forall a. Ord a => a -> a -> KindSigOptions
< Int
0
#if !(MIN_VERSION_base(4,10,0))
|| any (== OtherKind) droppedStarKindStati
#endif
) (Q () -> Q ()) -> Q () -> Q ()
forall a b. (a -> b) -> a -> b
$
Name -> Q ()
forall a. Name -> Q a
derivingKindError Name
tyConName
let varTysExpSubst :: [Type]
#if MIN_VERSION_base(4,10,0)
varTysExpSubst :: [Type]
varTysExpSubst = [Type]
varTysExp
#else
varTysExpSubst = map (substNamesWithKindStar droppedKindVarNames) varTysExp
droppedKindVarNames :: [Name]
droppedKindVarNames = catKindVarNames droppedStarKindStati
#endif
let remainingTysExpSubst, droppedTysExpSubst :: [Type]
([Type]
remainingTysExpSubst, [Type]
droppedTysExpSubst) =
Int -> [Type] -> ([Type], [Type])
forall a. Int -> [a] -> ([a], [a])
splitAt Int
remainingLength [Type]
varTysExpSubst
#if !(MIN_VERSION_base(4,10,0))
unless (all hasKindStar droppedTysExpSubst) $
derivingKindError tyConName
#endif
let varTysOrigSubst :: [Type]
varTysOrigSubst :: [Type]
varTysOrigSubst =
#if MIN_VERSION_base(4,10,0)
[Type] -> [Type]
forall a. a -> a
id
#else
map (substNamesWithKindStar droppedKindVarNames)
#endif
([Type] -> [Type]) -> [Type] -> [Type]
forall a b. (a -> b) -> a -> b
$ [Type]
varTysOrig
remainingTysOrigSubst, droppedTysOrigSubst :: [Type]
([Type]
remainingTysOrigSubst, [Type]
droppedTysOrigSubst) =
Int -> [Type] -> ([Type], [Type])
forall a. Int -> [a] -> ([a], [a])
splitAt Int
remainingLength [Type]
varTysOrigSubst
remainingTysOrigSubst' :: [Type]
remainingTysOrigSubst' :: [Type]
remainingTysOrigSubst' =
if KindSigOptions
useKindSigs
then [Type]
remainingTysOrigSubst
else (Type -> Type) -> [Type] -> [Type]
forall a b. (a -> b) -> [a] -> [b]
map Type -> Type
unSigT [Type]
remainingTysOrigSubst
instanceType :: Type
instanceType :: Type
instanceType = Type -> [Type] -> Type
applyTyToTys (Name -> Type
ConT Name
tyConName) [Type]
remainingTysOrigSubst'
instanceKind :: Kind
instanceKind :: Type
instanceKind = [Type] -> Type -> Type
makeFunKind ((Type -> Type) -> [Type] -> [Type]
forall a b. (a -> b) -> [a] -> [b]
map Type -> Type
typeKind [Type]
droppedTysOrigSubst) Type
starK
KindSigOptions -> Q () -> Q ()
forall (f :: * -> *).
Applicative f =>
KindSigOptions -> f () -> f ()
unless ([Type] -> [Type] -> KindSigOptions
canEtaReduce [Type]
remainingTysExpSubst [Type]
droppedTysExpSubst) (Q () -> Q ()) -> Q () -> Q ()
forall a b. (a -> b) -> a -> b
$
Type -> Q ()
forall a. Type -> Q a
etaReductionError Type
instanceType
(Type, Type) -> Q (Type, Type)
forall (m :: * -> *) a. Monad m => a -> m a
return (Type
instanceType, Type
instanceKind)