{-# LANGUAGE CPP #-}
{-# LANGUAGE DoAndIfThenElse #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE TemplateHaskell #-}
{-# LANGUAGE TypeOperators #-}
{-# LANGUAGE EmptyCase #-}
module Data.Parameterized.TH.GADT
(
structuralEquality
, structuralTypeEquality
, structuralTypeOrd
, structuralTraversal
, structuralShowsPrec
, structuralHash
, structuralHashWithSalt
, PolyEq(..)
, mkRepr
, mkKnownReprs
, DataD
, lookupDataType'
, asTypeCon
, conPat
, TypePat(..)
, dataParamTypes
, assocTypePats
) where
import Control.Monad
import Data.Maybe
import Data.Set (Set)
import qualified Data.Set as Set
import Language.Haskell.TH
import Language.Haskell.TH.Datatype
import Data.Parameterized.Classes
type DataD = DatatypeInfo
lookupDataType' :: Name -> Q DatatypeInfo
lookupDataType' :: Name -> Q DatatypeInfo
lookupDataType' = Name -> Q DatatypeInfo
reifyDatatype
conPat ::
ConstructorInfo ->
String ->
Q (Pat, [Name])
conPat :: ConstructorInfo -> String -> Q (Pat, [Name])
conPat ConstructorInfo
con String
pre = do
[Name]
nms <- String -> Int -> Q [Name]
newNames String
pre (forall (t :: * -> *) a. Foldable t => t a -> Int
length (ConstructorInfo -> [Type]
constructorFields ConstructorInfo
con))
forall (m :: * -> *) a. Monad m => a -> m a
return (Name -> [Pat] -> Pat
conPCompat (ConstructorInfo -> Name
constructorName ConstructorInfo
con) (Name -> Pat
VarP forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [Name]
nms), [Name]
nms)
conExpr :: ConstructorInfo -> Exp
conExpr :: ConstructorInfo -> Exp
conExpr = Name -> Exp
ConE forall b c a. (b -> c) -> (a -> b) -> a -> c
. ConstructorInfo -> Name
constructorName
data TypePat
= TypeApp TypePat TypePat
| AnyType
| DataArg Int
| ConType TypeQ
matchTypePat :: [Type] -> TypePat -> Type -> Q Bool
matchTypePat :: [Type] -> TypePat -> Type -> Q Bool
matchTypePat [Type]
d (TypeApp TypePat
p TypePat
q) (AppT Type
x Type
y) = do
Bool
r <- [Type] -> TypePat -> Type -> Q Bool
matchTypePat [Type]
d TypePat
p Type
x
case Bool
r of
Bool
True -> [Type] -> TypePat -> Type -> Q Bool
matchTypePat [Type]
d TypePat
q Type
y
Bool
False -> forall (m :: * -> *) a. Monad m => a -> m a
return Bool
False
matchTypePat [Type]
_ TypePat
AnyType Type
_ = forall (m :: * -> *) a. Monad m => a -> m a
return Bool
True
matchTypePat [Type]
tps (DataArg Int
i) Type
tp
| Int
i forall a. Ord a => a -> a -> Bool
< Int
0 Bool -> Bool -> Bool
|| Int
i forall a. Ord a => a -> a -> Bool
>= forall (t :: * -> *) a. Foldable t => t a -> Int
length [Type]
tps = forall a. HasCallStack => String -> a
error (String
"Type pattern index " forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> String
show Int
i forall a. [a] -> [a] -> [a]
++ String
" out of bounds")
| Bool
otherwise = forall (m :: * -> *) a. Monad m => a -> m a
return (Type -> Type
stripSigT ([Type]
tps forall a. [a] -> Int -> a
!! Int
i) forall a. Eq a => a -> a -> Bool
== Type
tp)
where
stripSigT :: Type -> Type
stripSigT (SigT Type
t Type
_) = Type
t
stripSigT Type
t = Type
t
matchTypePat [Type]
_ (ConType TypeQ
tpq) Type
tp = do
Type
tp' <- TypeQ
tpq
forall (m :: * -> *) a. Monad m => a -> m a
return (Type
tp' forall a. Eq a => a -> a -> Bool
== Type
tp)
matchTypePat [Type]
_ TypePat
_ Type
_ = forall (m :: * -> *) a. Monad m => a -> m a
return Bool
False
dataParamTypes :: DatatypeInfo -> [Type]
dataParamTypes :: DatatypeInfo -> [Type]
dataParamTypes = DatatypeInfo -> [Type]
datatypeInstTypes
assocTypePats :: [Type] -> [(TypePat, v)] -> Type -> Q (Maybe v)
assocTypePats :: forall v. [Type] -> [(TypePat, v)] -> Type -> Q (Maybe v)
assocTypePats [Type]
_ [] Type
_ = forall (m :: * -> *) a. Monad m => a -> m a
return forall a. Maybe a
Nothing
assocTypePats [Type]
dTypes ((TypePat
p,v
v):[(TypePat, v)]
pats) Type
tp = do
Bool
r <- [Type] -> TypePat -> Type -> Q Bool
matchTypePat [Type]
dTypes TypePat
p Type
tp
case Bool
r of
Bool
True -> forall (m :: * -> *) a. Monad m => a -> m a
return (forall a. a -> Maybe a
Just v
v)
Bool
False -> forall v. [Type] -> [(TypePat, v)] -> Type -> Q (Maybe v)
assocTypePats [Type]
dTypes [(TypePat, v)]
pats Type
tp
typeVars :: TypeSubstitution a => a -> Set Name
typeVars :: forall a. TypeSubstitution a => a -> Set Name
typeVars = forall a. Ord a => [a] -> Set a
Set.fromList forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. TypeSubstitution a => a -> [Name]
freeVariables
structuralEquality :: TypeQ -> [(TypePat,ExpQ)] -> ExpQ
structuralEquality :: TypeQ -> [(TypePat, ExpQ)] -> ExpQ
structuralEquality TypeQ
tpq [(TypePat, ExpQ)]
pats =
[| \x y -> isJust ($(structuralTypeEquality tpq pats) x y) |]
joinEqMaybe :: Name -> Name -> ExpQ -> ExpQ
joinEqMaybe :: Name -> Name -> ExpQ -> ExpQ
joinEqMaybe Name
x Name
y ExpQ
r = do
[| if $(varE x) == $(varE y) then $(r) else Nothing |]
joinTestEquality :: ExpQ -> Name -> Name -> ExpQ -> ExpQ
joinTestEquality :: ExpQ -> Name -> Name -> ExpQ -> ExpQ
joinTestEquality ExpQ
f Name
x Name
y ExpQ
r =
[| case $(f) $(varE x) $(varE y) of
Nothing -> Nothing
Just Refl -> $(r)
|]
matchEqArguments :: [Type]
-> [(TypePat,ExpQ)]
-> Name
-> Set Name
-> [Type]
-> [Name]
-> [Name]
-> ExpQ
matchEqArguments :: [Type]
-> [(TypePat, ExpQ)]
-> Name
-> Set Name
-> [Type]
-> [Name]
-> [Name]
-> ExpQ
matchEqArguments [Type]
dTypes [(TypePat, ExpQ)]
pats Name
cnm Set Name
bnd (Type
tp:[Type]
tpl) (Name
x:[Name]
xl) (Name
y:[Name]
yl) = do
Maybe ExpQ
doesMatch <- forall v. [Type] -> [(TypePat, v)] -> Type -> Q (Maybe v)
assocTypePats [Type]
dTypes [(TypePat, ExpQ)]
pats Type
tp
case Maybe ExpQ
doesMatch of
Just ExpQ
q -> do
let bnd' :: Set Name
bnd' =
case Type
tp of
AppT Type
_ (VarT Name
nm) -> forall a. Ord a => a -> Set a -> Set a
Set.insert Name
nm Set Name
bnd
Type
_ -> Set Name
bnd
ExpQ -> Name -> Name -> ExpQ -> ExpQ
joinTestEquality ExpQ
q Name
x Name
y ([Type]
-> [(TypePat, ExpQ)]
-> Name
-> Set Name
-> [Type]
-> [Name]
-> [Name]
-> ExpQ
matchEqArguments [Type]
dTypes [(TypePat, ExpQ)]
pats Name
cnm Set Name
bnd' [Type]
tpl [Name]
xl [Name]
yl)
Maybe ExpQ
Nothing | forall a. TypeSubstitution a => a -> Set Name
typeVars Type
tp forall a. Ord a => Set a -> Set a -> Bool
`Set.isSubsetOf` Set Name
bnd -> do
Name -> Name -> ExpQ -> ExpQ
joinEqMaybe Name
x Name
y ([Type]
-> [(TypePat, ExpQ)]
-> Name
-> Set Name
-> [Type]
-> [Name]
-> [Name]
-> ExpQ
matchEqArguments [Type]
dTypes [(TypePat, ExpQ)]
pats Name
cnm Set Name
bnd [Type]
tpl [Name]
xl [Name]
yl)
Maybe ExpQ
Nothing -> do
forall (m :: * -> *) a. MonadFail m => String -> m a
fail forall a b. (a -> b) -> a -> b
$ String
"Unsupported argument type " forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> String
show Type
tp
forall a. [a] -> [a] -> [a]
++ String
" in " forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> String
show (forall a. Ppr a => a -> Doc
ppr Name
cnm) forall a. [a] -> [a] -> [a]
++ String
"."
matchEqArguments [Type]
_ [(TypePat, ExpQ)]
_ Name
_ Set Name
_ [] [] [] = [| Just Refl |]
matchEqArguments [Type]
_ [(TypePat, ExpQ)]
_ Name
_ Set Name
_ [] [Name]
_ [Name]
_ = forall a. HasCallStack => String -> a
error String
"Unexpected end of types."
matchEqArguments [Type]
_ [(TypePat, ExpQ)]
_ Name
_ Set Name
_ [Type]
_ [] [Name]
_ = forall a. HasCallStack => String -> a
error String
"Unexpected end of names."
matchEqArguments [Type]
_ [(TypePat, ExpQ)]
_ Name
_ Set Name
_ [Type]
_ [Name]
_ [] = forall a. HasCallStack => String -> a
error String
"Unexpected end of names."
mkSimpleEqF :: [Type]
-> Set Name
-> [(TypePat,ExpQ)]
-> ConstructorInfo
-> [Name]
-> ExpQ
-> Bool
-> ExpQ
mkSimpleEqF :: [Type]
-> Set Name
-> [(TypePat, ExpQ)]
-> ConstructorInfo
-> [Name]
-> ExpQ
-> Bool
-> ExpQ
mkSimpleEqF [Type]
dTypes Set Name
bnd [(TypePat, ExpQ)]
pats ConstructorInfo
con [Name]
xv ExpQ
yQ Bool
multipleCases = do
let nm :: Name
nm = ConstructorInfo -> Name
constructorName ConstructorInfo
con
(Pat
yp,[Name]
yv) <- ConstructorInfo -> String -> Q (Pat, [Name])
conPat ConstructorInfo
con String
"y"
let rv :: ExpQ
rv = [Type]
-> [(TypePat, ExpQ)]
-> Name
-> Set Name
-> [Type]
-> [Name]
-> [Name]
-> ExpQ
matchEqArguments [Type]
dTypes [(TypePat, ExpQ)]
pats Name
nm Set Name
bnd (ConstructorInfo -> [Type]
constructorFields ConstructorInfo
con) [Name]
xv [Name]
yv
forall (m :: * -> *). Quote m => m Exp -> [m Match] -> m Exp
caseE ExpQ
yQ forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *).
Quote m =>
m Pat -> m Body -> [m Dec] -> m Match
match (forall (f :: * -> *) a. Applicative f => a -> f a
pure Pat
yp) (forall (m :: * -> *). Quote m => m Exp -> m Body
normalB ExpQ
rv) []
forall a. a -> [a] -> [a]
: [ forall (m :: * -> *).
Quote m =>
m Pat -> m Body -> [m Dec] -> m Match
match forall (m :: * -> *). Quote m => m Pat
wildP (forall (m :: * -> *). Quote m => m Exp -> m Body
normalB [| Nothing |]) [] | Bool
multipleCases ]
mkEqF :: DatatypeInfo
-> [(TypePat,ExpQ)]
-> ConstructorInfo
-> [Name]
-> ExpQ
-> Bool
-> ExpQ
mkEqF :: DatatypeInfo
-> [(TypePat, ExpQ)]
-> ConstructorInfo
-> [Name]
-> ExpQ
-> Bool
-> ExpQ
mkEqF DatatypeInfo
d [(TypePat, ExpQ)]
pats ConstructorInfo
con =
let dVars :: [Type]
dVars = DatatypeInfo -> [Type]
dataParamTypes DatatypeInfo
d
bnd :: Set Name
bnd | forall (t :: * -> *) a. Foldable t => t a -> Bool
null [Type]
dVars = forall a. Set a
Set.empty
| Bool
otherwise = forall a. TypeSubstitution a => a -> Set Name
typeVars (forall a. [a] -> [a]
init [Type]
dVars)
in [Type]
-> Set Name
-> [(TypePat, ExpQ)]
-> ConstructorInfo
-> [Name]
-> ExpQ
-> Bool
-> ExpQ
mkSimpleEqF [Type]
dVars Set Name
bnd [(TypePat, ExpQ)]
pats ConstructorInfo
con
structuralTypeEquality :: TypeQ -> [(TypePat,ExpQ)] -> ExpQ
structuralTypeEquality :: TypeQ -> [(TypePat, ExpQ)] -> ExpQ
structuralTypeEquality TypeQ
tpq [(TypePat, ExpQ)]
pats = do
DatatypeInfo
d <- Name -> Q DatatypeInfo
reifyDatatype forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< String -> Type -> Q Name
asTypeCon String
"structuralTypeEquality" forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< TypeQ
tpq
let multipleCons :: Bool
multipleCons = Bool -> Bool
not (forall (t :: * -> *) a. Foldable t => t a -> Bool
null (forall a. Int -> [a] -> [a]
drop Int
1 (DatatypeInfo -> [ConstructorInfo]
datatypeCons DatatypeInfo
d)))
trueEqs :: ExpQ -> [Q Match]
trueEqs ExpQ
yQ = [ do (Pat
xp,[Name]
xv) <- ConstructorInfo -> String -> Q (Pat, [Name])
conPat ConstructorInfo
con String
"x"
forall (m :: * -> *).
Quote m =>
m Pat -> m Body -> [m Dec] -> m Match
match (forall (f :: * -> *) a. Applicative f => a -> f a
pure Pat
xp) (forall (m :: * -> *). Quote m => m Exp -> m Body
normalB (DatatypeInfo
-> [(TypePat, ExpQ)]
-> ConstructorInfo
-> [Name]
-> ExpQ
-> Bool
-> ExpQ
mkEqF DatatypeInfo
d [(TypePat, ExpQ)]
pats ConstructorInfo
con [Name]
xv ExpQ
yQ Bool
multipleCons)) []
| ConstructorInfo
con <- DatatypeInfo -> [ConstructorInfo]
datatypeCons DatatypeInfo
d
]
if forall (t :: * -> *) a. Foldable t => t a -> Bool
null (DatatypeInfo -> [ConstructorInfo]
datatypeCons DatatypeInfo
d)
then [| \x -> case x of {} |]
else [| \x y -> $(caseE [| x |] (trueEqs [| y |])) |]
structuralTypeOrd ::
TypeQ ->
[(TypePat,ExpQ)] ->
ExpQ
structuralTypeOrd :: TypeQ -> [(TypePat, ExpQ)] -> ExpQ
structuralTypeOrd TypeQ
tpq [(TypePat, ExpQ)]
l = do
DatatypeInfo
d <- Name -> Q DatatypeInfo
reifyDatatype forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< String -> Type -> Q Name
asTypeCon String
"structuralTypeEquality" forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< TypeQ
tpq
let withNumber :: ExpQ -> (Maybe ExpQ -> ExpQ) -> ExpQ
withNumber :: ExpQ -> (Maybe ExpQ -> ExpQ) -> ExpQ
withNumber ExpQ
yQ Maybe ExpQ -> ExpQ
k
| forall (t :: * -> *) a. Foldable t => t a -> Bool
null (forall a. Int -> [a] -> [a]
drop Int
1 (DatatypeInfo -> [ConstructorInfo]
datatypeCons DatatypeInfo
d)) = Maybe ExpQ -> ExpQ
k forall a. Maybe a
Nothing
| Bool
otherwise = [| let yn :: Int
yn = $(caseE yQ (constructorNumberMatches (datatypeCons d)))
in $(k (Just [| yn |])) |]
if forall (t :: * -> *) a. Foldable t => t a -> Bool
null (DatatypeInfo -> [ConstructorInfo]
datatypeCons DatatypeInfo
d)
then [| \x -> case x of {} |]
else [| \x y -> $(withNumber [|y|] $ \mbYn -> caseE [| x |] (outerOrdMatches d [|y|] mbYn)) |]
where
constructorNumberMatches :: [ConstructorInfo] -> [MatchQ]
constructorNumberMatches :: [ConstructorInfo] -> [Q Match]
constructorNumberMatches [ConstructorInfo]
cons =
[ forall (m :: * -> *).
Quote m =>
m Pat -> m Body -> [m Dec] -> m Match
match (forall (m :: * -> *). Quote m => Name -> [m FieldPat] -> m Pat
recP (ConstructorInfo -> Name
constructorName ConstructorInfo
con) [])
(forall (m :: * -> *). Quote m => m Exp -> m Body
normalB (forall (m :: * -> *). Quote m => Lit -> m Exp
litE (Integer -> Lit
integerL Integer
i)))
[]
| (Integer
i,ConstructorInfo
con) <- forall a b. [a] -> [b] -> [(a, b)]
zip [Integer
0..] [ConstructorInfo]
cons ]
outerOrdMatches :: DatatypeInfo -> ExpQ -> Maybe ExpQ -> [MatchQ]
outerOrdMatches :: DatatypeInfo -> ExpQ -> Maybe ExpQ -> [Q Match]
outerOrdMatches DatatypeInfo
d ExpQ
yExp Maybe ExpQ
mbYn =
[ do (Pat
pat,[Name]
xv) <- ConstructorInfo -> String -> Q (Pat, [Name])
conPat ConstructorInfo
con String
"x"
forall (m :: * -> *).
Quote m =>
m Pat -> m Body -> [m Dec] -> m Match
match (forall (f :: * -> *) a. Applicative f => a -> f a
pure Pat
pat)
(forall (m :: * -> *). Quote m => m Exp -> m Body
normalB (do [Q Match]
xs <- DatatypeInfo
-> [(TypePat, ExpQ)]
-> ConstructorInfo
-> Integer
-> Maybe ExpQ
-> [Name]
-> Q [Q Match]
mkOrdF DatatypeInfo
d [(TypePat, ExpQ)]
l ConstructorInfo
con Integer
i Maybe ExpQ
mbYn [Name]
xv
forall (m :: * -> *). Quote m => m Exp -> [m Match] -> m Exp
caseE ExpQ
yExp [Q Match]
xs))
[]
| (Integer
i,ConstructorInfo
con) <- forall a b. [a] -> [b] -> [(a, b)]
zip [Integer
0..] (DatatypeInfo -> [ConstructorInfo]
datatypeCons DatatypeInfo
d) ]
newNames ::
String ->
Int ->
Q [Name]
newNames :: String -> Int -> Q [Name]
newNames String
base Int
n = forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
traverse (\Int
i -> forall (m :: * -> *). Quote m => String -> m Name
newName (String
base forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> String
show Int
i)) [Int
1..Int
n]
joinCompareF :: ExpQ -> Name -> Name -> ExpQ -> ExpQ
joinCompareF :: ExpQ -> Name -> Name -> ExpQ -> ExpQ
joinCompareF ExpQ
f Name
x Name
y ExpQ
r = do
[| case $(f) $(varE x) $(varE y) of
LTF -> LTF
GTF -> GTF
EQF -> $(r)
|]
joinCompareToOrdF :: Name -> Name -> ExpQ -> ExpQ
joinCompareToOrdF :: Name -> Name -> ExpQ -> ExpQ
joinCompareToOrdF Name
x Name
y ExpQ
r =
[| case compare $(varE x) $(varE y) of
LT -> LTF
GT -> GTF
EQ -> $(r)
|]
matchOrdArguments :: [Type]
-> [(TypePat,ExpQ)]
-> Name
-> Set Name
-> [Type]
-> [Name]
-> [Name]
-> ExpQ
matchOrdArguments :: [Type]
-> [(TypePat, ExpQ)]
-> Name
-> Set Name
-> [Type]
-> [Name]
-> [Name]
-> ExpQ
matchOrdArguments [Type]
dTypes [(TypePat, ExpQ)]
pats Name
cnm Set Name
bnd (Type
tp : [Type]
tpl) (Name
x:[Name]
xl) (Name
y:[Name]
yl) = do
Maybe ExpQ
doesMatch <- forall v. [Type] -> [(TypePat, v)] -> Type -> Q (Maybe v)
assocTypePats [Type]
dTypes [(TypePat, ExpQ)]
pats Type
tp
case Maybe ExpQ
doesMatch of
Just ExpQ
f -> do
let bnd' :: Set Name
bnd' = case Type
tp of
AppT Type
_ (VarT Name
nm) -> forall a. Ord a => a -> Set a -> Set a
Set.insert Name
nm Set Name
bnd
Type
_ -> Set Name
bnd
ExpQ -> Name -> Name -> ExpQ -> ExpQ
joinCompareF ExpQ
f Name
x Name
y ([Type]
-> [(TypePat, ExpQ)]
-> Name
-> Set Name
-> [Type]
-> [Name]
-> [Name]
-> ExpQ
matchOrdArguments [Type]
dTypes [(TypePat, ExpQ)]
pats Name
cnm Set Name
bnd' [Type]
tpl [Name]
xl [Name]
yl)
Maybe ExpQ
Nothing | forall a. TypeSubstitution a => a -> Set Name
typeVars Type
tp forall a. Ord a => Set a -> Set a -> Bool
`Set.isSubsetOf` Set Name
bnd -> do
Name -> Name -> ExpQ -> ExpQ
joinCompareToOrdF Name
x Name
y ([Type]
-> [(TypePat, ExpQ)]
-> Name
-> Set Name
-> [Type]
-> [Name]
-> [Name]
-> ExpQ
matchOrdArguments [Type]
dTypes [(TypePat, ExpQ)]
pats Name
cnm Set Name
bnd [Type]
tpl [Name]
xl [Name]
yl)
Maybe ExpQ
Nothing ->
forall (m :: * -> *) a. MonadFail m => String -> m a
fail forall a b. (a -> b) -> a -> b
$ String
"Unsupported argument type " forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> String
show (forall a. Ppr a => a -> Doc
ppr Type
tp)
forall a. [a] -> [a] -> [a]
++ String
" in " forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> String
show (forall a. Ppr a => a -> Doc
ppr Name
cnm) forall a. [a] -> [a] -> [a]
++ String
"."
matchOrdArguments [Type]
_ [(TypePat, ExpQ)]
_ Name
_ Set Name
_ [] [] [] = [| EQF |]
matchOrdArguments [Type]
_ [(TypePat, ExpQ)]
_ Name
_ Set Name
_ [] [Name]
_ [Name]
_ = forall a. HasCallStack => String -> a
error String
"Unexpected end of types."
matchOrdArguments [Type]
_ [(TypePat, ExpQ)]
_ Name
_ Set Name
_ [Type]
_ [] [Name]
_ = forall a. HasCallStack => String -> a
error String
"Unexpected end of names."
matchOrdArguments [Type]
_ [(TypePat, ExpQ)]
_ Name
_ Set Name
_ [Type]
_ [Name]
_ [] = forall a. HasCallStack => String -> a
error String
"Unexpected end of names."
mkSimpleOrdF :: [Type]
-> [(TypePat,ExpQ)]
-> ConstructorInfo
-> Integer
-> Maybe ExpQ
-> [Name]
-> Q [MatchQ]
mkSimpleOrdF :: [Type]
-> [(TypePat, ExpQ)]
-> ConstructorInfo
-> Integer
-> Maybe ExpQ
-> [Name]
-> Q [Q Match]
mkSimpleOrdF [Type]
dTypes [(TypePat, ExpQ)]
pats ConstructorInfo
con Integer
xnum Maybe ExpQ
mbYn [Name]
xv = do
(Pat
yp,[Name]
yv) <- ConstructorInfo -> String -> Q (Pat, [Name])
conPat ConstructorInfo
con String
"y"
let rv :: ExpQ
rv = [Type]
-> [(TypePat, ExpQ)]
-> Name
-> Set Name
-> [Type]
-> [Name]
-> [Name]
-> ExpQ
matchOrdArguments [Type]
dTypes [(TypePat, ExpQ)]
pats (ConstructorInfo -> Name
constructorName ConstructorInfo
con) forall a. Set a
Set.empty (ConstructorInfo -> [Type]
constructorFields ConstructorInfo
con) [Name]
xv [Name]
yv
forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *).
Quote m =>
m Pat -> m Body -> [m Dec] -> m Match
match (forall (f :: * -> *) a. Applicative f => a -> f a
pure Pat
yp) (forall (m :: * -> *). Quote m => m Exp -> m Body
normalB ExpQ
rv) []
forall a. a -> [a] -> [a]
: case Maybe ExpQ
mbYn of
Maybe ExpQ
Nothing -> []
Just ExpQ
yn -> [forall (m :: * -> *).
Quote m =>
m Pat -> m Body -> [m Dec] -> m Match
match forall (m :: * -> *). Quote m => m Pat
wildP (forall (m :: * -> *). Quote m => m Exp -> m Body
normalB [| if xnum < $yn then LTF else GTF |]) []]
mkOrdF :: DatatypeInfo
-> [(TypePat,ExpQ)]
-> ConstructorInfo
-> Integer
-> Maybe ExpQ
-> [Name]
-> Q [MatchQ]
mkOrdF :: DatatypeInfo
-> [(TypePat, ExpQ)]
-> ConstructorInfo
-> Integer
-> Maybe ExpQ
-> [Name]
-> Q [Q Match]
mkOrdF DatatypeInfo
d [(TypePat, ExpQ)]
pats = [Type]
-> [(TypePat, ExpQ)]
-> ConstructorInfo
-> Integer
-> Maybe ExpQ
-> [Name]
-> Q [Q Match]
mkSimpleOrdF (DatatypeInfo -> [Type]
datatypeInstTypes DatatypeInfo
d) [(TypePat, ExpQ)]
pats
genTraverseOfType :: [Type]
-> [(TypePat, ExpQ)]
-> ExpQ
-> ExpQ
-> Type
-> Q (Maybe Exp)
genTraverseOfType :: [Type]
-> [(TypePat, ExpQ)] -> ExpQ -> ExpQ -> Type -> Q (Maybe Exp)
genTraverseOfType [Type]
dataArgs [(TypePat, ExpQ)]
pats ExpQ
f ExpQ
v Type
tp = do
Maybe ExpQ
mr <- forall v. [Type] -> [(TypePat, v)] -> Type -> Q (Maybe v)
assocTypePats [Type]
dataArgs [(TypePat, ExpQ)]
pats Type
tp
case Maybe ExpQ
mr of
Just ExpQ
g -> forall a. a -> Maybe a
Just forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [| $(g) $(f) $(v) |]
Maybe ExpQ
Nothing ->
case Type
tp of
AppT (ConT Name
_) (AppT (VarT Name
_) Type
_) -> forall a. a -> Maybe a
Just forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [| traverse $(f) $(v) |]
AppT (VarT Name
_) Type
_ -> forall a. a -> Maybe a
Just forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [| $(f) $(v) |]
Type
_ -> forall (m :: * -> *) a. Monad m => a -> m a
return forall a. Maybe a
Nothing
traverseAppMatch :: [Type]
-> [(TypePat, ExpQ)]
-> ExpQ
-> ConstructorInfo
-> MatchQ
traverseAppMatch :: [Type] -> [(TypePat, ExpQ)] -> ExpQ -> ConstructorInfo -> Q Match
traverseAppMatch [Type]
dataArgs [(TypePat, ExpQ)]
pats ExpQ
fv ConstructorInfo
c0 = do
(Pat
pat,[Name]
patArgs) <- ConstructorInfo -> String -> Q (Pat, [Name])
conPat ConstructorInfo
c0 String
"p"
[Maybe Exp]
exprs <- forall (m :: * -> *) a b c.
Applicative m =>
(a -> b -> m c) -> [a] -> [b] -> m [c]
zipWithM ([Type]
-> [(TypePat, ExpQ)] -> ExpQ -> ExpQ -> Type -> Q (Maybe Exp)
genTraverseOfType [Type]
dataArgs [(TypePat, ExpQ)]
pats ExpQ
fv) (forall (m :: * -> *). Quote m => Name -> m Exp
varE forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [Name]
patArgs) (ConstructorInfo -> [Type]
constructorFields ConstructorInfo
c0)
let mkRes :: ExpQ -> [(Name, Maybe Exp)] -> ExpQ
mkRes :: ExpQ -> [(Name, Maybe Exp)] -> ExpQ
mkRes ExpQ
e [] = ExpQ
e
mkRes ExpQ
e ((Name
v,Maybe Exp
Nothing):[(Name, Maybe Exp)]
r) =
ExpQ -> [(Name, Maybe Exp)] -> ExpQ
mkRes (forall (m :: * -> *). Quote m => m Exp -> m Exp -> m Exp
appE ExpQ
e (forall (m :: * -> *). Quote m => Name -> m Exp
varE Name
v)) [(Name, Maybe Exp)]
r
mkRes ExpQ
e ((Name
_,Just{}):[(Name, Maybe Exp)]
r) = do
Name
v <- forall (m :: * -> *). Quote m => String -> m Name
newName String
"r"
forall (m :: * -> *). Quote m => [m Pat] -> m Exp -> m Exp
lamE [forall (m :: * -> *). Quote m => Name -> m Pat
varP Name
v] (ExpQ -> [(Name, Maybe Exp)] -> ExpQ
mkRes (forall (m :: * -> *). Quote m => m Exp -> m Exp -> m Exp
appE ExpQ
e (forall (m :: * -> *). Quote m => Name -> m Exp
varE Name
v)) [(Name, Maybe Exp)]
r)
let applyRest :: ExpQ -> [Exp] -> ExpQ
applyRest :: ExpQ -> [Exp] -> ExpQ
applyRest ExpQ
e [] = ExpQ
e
applyRest ExpQ
e (Exp
a:[Exp]
r) = ExpQ -> [Exp] -> ExpQ
applyRest [| $(e) <*> $(pure a) |] [Exp]
r
let applyFirst :: ExpQ -> [Exp] -> ExpQ
applyFirst :: ExpQ -> [Exp] -> ExpQ
applyFirst ExpQ
e [] = [| pure $(e) |]
applyFirst ExpQ
e (Exp
a:[Exp]
r) = ExpQ -> [Exp] -> ExpQ
applyRest [| $(e) <$> $(pure a) |] [Exp]
r
let pargs :: [(Name, Maybe Exp)]
pargs = [Name]
patArgs forall a b. [a] -> [b] -> [(a, b)]
`zip` [Maybe Exp]
exprs
let rhs :: ExpQ
rhs = ExpQ -> [Exp] -> ExpQ
applyFirst (ExpQ -> [(Name, Maybe Exp)] -> ExpQ
mkRes (forall (f :: * -> *) a. Applicative f => a -> f a
pure (ConstructorInfo -> Exp
conExpr ConstructorInfo
c0)) [(Name, Maybe Exp)]
pargs) (forall a. [Maybe a] -> [a]
catMaybes [Maybe Exp]
exprs)
forall (m :: * -> *).
Quote m =>
m Pat -> m Body -> [m Dec] -> m Match
match (forall (f :: * -> *) a. Applicative f => a -> f a
pure Pat
pat) (forall (m :: * -> *). Quote m => m Exp -> m Body
normalB ExpQ
rhs) []
structuralTraversal :: TypeQ -> [(TypePat, ExpQ)] -> ExpQ
structuralTraversal :: TypeQ -> [(TypePat, ExpQ)] -> ExpQ
structuralTraversal TypeQ
tpq [(TypePat, ExpQ)]
pats0 = do
DatatypeInfo
d <- Name -> Q DatatypeInfo
reifyDatatype forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< String -> Type -> Q Name
asTypeCon String
"structuralTraversal" forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< TypeQ
tpq
Name
f <- forall (m :: * -> *). Quote m => String -> m Name
newName String
"f"
Name
a <- forall (m :: * -> *). Quote m => String -> m Name
newName String
"a"
forall (m :: * -> *). Quote m => [m Pat] -> m Exp -> m Exp
lamE [forall (m :: * -> *). Quote m => Name -> m Pat
varP Name
f, forall (m :: * -> *). Quote m => Name -> m Pat
varP Name
a] forall a b. (a -> b) -> a -> b
$
forall (m :: * -> *). Quote m => m Exp -> [m Match] -> m Exp
caseE (forall (m :: * -> *). Quote m => Name -> m Exp
varE Name
a)
([Type] -> [(TypePat, ExpQ)] -> ExpQ -> ConstructorInfo -> Q Match
traverseAppMatch (DatatypeInfo -> [Type]
datatypeInstTypes DatatypeInfo
d) [(TypePat, ExpQ)]
pats0 (forall (m :: * -> *). Quote m => Name -> m Exp
varE Name
f) forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> DatatypeInfo -> [ConstructorInfo]
datatypeCons DatatypeInfo
d)
asTypeCon :: String -> Type -> Q Name
asTypeCon :: String -> Type -> Q Name
asTypeCon String
_ (ConT Name
nm) = forall (m :: * -> *) a. Monad m => a -> m a
return Name
nm
asTypeCon String
fn Type
_ = forall (m :: * -> *) a. MonadFail m => String -> m a
fail (String
fn forall a. [a] -> [a] -> [a]
++ String
" expected type constructor.")
structuralHash :: TypeQ -> ExpQ
structuralHash :: TypeQ -> ExpQ
structuralHash TypeQ
tpq = TypeQ -> [(TypePat, ExpQ)] -> ExpQ
structuralHashWithSalt TypeQ
tpq []
{-# DEPRECATED structuralHash "Use structuralHashWithSalt" #-}
structuralHashWithSalt :: TypeQ -> [(TypePat, ExpQ)] -> ExpQ
structuralHashWithSalt :: TypeQ -> [(TypePat, ExpQ)] -> ExpQ
structuralHashWithSalt TypeQ
tpq [(TypePat, ExpQ)]
pats = do
DatatypeInfo
d <- Name -> Q DatatypeInfo
reifyDatatype forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< String -> Type -> Q Name
asTypeCon String
"structuralHash" forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< TypeQ
tpq
Name
s <- forall (m :: * -> *). Quote m => String -> m Name
newName String
"s"
Name
a <- forall (m :: * -> *). Quote m => String -> m Name
newName String
"a"
forall (m :: * -> *). Quote m => [m Pat] -> m Exp -> m Exp
lamE [forall (m :: * -> *). Quote m => Name -> m Pat
varP Name
s, forall (m :: * -> *). Quote m => Name -> m Pat
varP Name
a] forall a b. (a -> b) -> a -> b
$
forall (m :: * -> *). Quote m => m Exp -> [m Match] -> m Exp
caseE (forall (m :: * -> *). Quote m => Name -> m Exp
varE Name
a) (forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith (DatatypeInfo
-> [(TypePat, ExpQ)]
-> ExpQ
-> Integer
-> ConstructorInfo
-> Q Match
matchHashCtor DatatypeInfo
d [(TypePat, ExpQ)]
pats (forall (m :: * -> *). Quote m => Name -> m Exp
varE Name
s)) [Integer
0..] (DatatypeInfo -> [ConstructorInfo]
datatypeCons DatatypeInfo
d))
matchHashCtor :: DatatypeInfo
-> [(TypePat, ExpQ)]
-> ExpQ
-> Integer
-> ConstructorInfo
-> MatchQ
matchHashCtor :: DatatypeInfo
-> [(TypePat, ExpQ)]
-> ExpQ
-> Integer
-> ConstructorInfo
-> Q Match
matchHashCtor DatatypeInfo
d [(TypePat, ExpQ)]
pats ExpQ
s0 Integer
i ConstructorInfo
c = do
(Pat
pat,[Name]
vars) <- ConstructorInfo -> String -> Q (Pat, [Name])
conPat ConstructorInfo
c String
"x"
let go :: ExpQ -> (ExpQ, Type) -> ExpQ
go ExpQ
s (ExpQ
e, Type
tp) = do
Maybe ExpQ
mr <- forall v. [Type] -> [(TypePat, v)] -> Type -> Q (Maybe v)
assocTypePats (DatatypeInfo -> [Type]
datatypeInstTypes DatatypeInfo
d) [(TypePat, ExpQ)]
pats Type
tp
case Maybe ExpQ
mr of
Just ExpQ
f -> do
[| $(f) $(s) $(e) |]
Maybe ExpQ
Nothing ->
[| hashWithSalt $(s) $(e) |]
let s1 :: ExpQ
s1 = [| hashWithSalt $(s0) ($(litE (IntegerL i)) :: Int) |]
let rhs :: ExpQ
rhs = forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl ExpQ -> (ExpQ, Type) -> ExpQ
go ExpQ
s1 (forall a b. [a] -> [b] -> [(a, b)]
zip (forall (m :: * -> *). Quote m => Name -> m Exp
varE forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [Name]
vars) (ConstructorInfo -> [Type]
constructorFields ConstructorInfo
c))
forall (m :: * -> *).
Quote m =>
m Pat -> m Body -> [m Dec] -> m Match
match (forall (f :: * -> *) a. Applicative f => a -> f a
pure Pat
pat) (forall (m :: * -> *). Quote m => m Exp -> m Body
normalB ExpQ
rhs) []
structuralShowsPrec :: TypeQ -> ExpQ
structuralShowsPrec :: TypeQ -> ExpQ
structuralShowsPrec TypeQ
tpq = do
DatatypeInfo
d <- Name -> Q DatatypeInfo
reifyDatatype forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< String -> Type -> Q Name
asTypeCon String
"structuralShowPrec" forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< TypeQ
tpq
Name
p <- forall (m :: * -> *). Quote m => String -> m Name
newName String
"_p"
Name
a <- forall (m :: * -> *). Quote m => String -> m Name
newName String
"a"
forall (m :: * -> *). Quote m => [m Pat] -> m Exp -> m Exp
lamE [forall (m :: * -> *). Quote m => Name -> m Pat
varP Name
p, forall (m :: * -> *). Quote m => Name -> m Pat
varP Name
a] forall a b. (a -> b) -> a -> b
$
forall (m :: * -> *). Quote m => m Exp -> [m Match] -> m Exp
caseE (forall (m :: * -> *). Quote m => Name -> m Exp
varE Name
a) (ExpQ -> ConstructorInfo -> Q Match
matchShowCtor (forall (m :: * -> *). Quote m => Name -> m Exp
varE Name
p) forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> DatatypeInfo -> [ConstructorInfo]
datatypeCons DatatypeInfo
d)
showCon :: ExpQ -> Name -> Int -> MatchQ
showCon :: ExpQ -> Name -> Int -> Q Match
showCon ExpQ
p Name
nm Int
n = do
[Name]
vars <- String -> Int -> Q [Name]
newNames String
"x" Int
n
let pat :: Pat
pat = Name -> [Pat] -> Pat
conPCompat Name
nm (Name -> Pat
VarP forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [Name]
vars)
let go :: m Exp -> Name -> m Exp
go m Exp
s Name
e = [| $(s) . showChar ' ' . showsPrec 11 $(varE e) |]
let ctor :: ExpQ
ctor = [| showString $(return (LitE (StringL (nameBase nm)))) |]
let rhs :: ExpQ
rhs | forall (t :: * -> *) a. Foldable t => t a -> Bool
null [Name]
vars = ExpQ
ctor
| Bool
otherwise = [| showParen ($(p) >= 11) $(foldl go ctor vars) |]
forall (m :: * -> *).
Quote m =>
m Pat -> m Body -> [m Dec] -> m Match
match (forall (f :: * -> *) a. Applicative f => a -> f a
pure Pat
pat) (forall (m :: * -> *). Quote m => m Exp -> m Body
normalB ExpQ
rhs) []
matchShowCtor :: ExpQ -> ConstructorInfo -> MatchQ
matchShowCtor :: ExpQ -> ConstructorInfo -> Q Match
matchShowCtor ExpQ
p ConstructorInfo
con = ExpQ -> Name -> Int -> Q Match
showCon ExpQ
p (ConstructorInfo -> Name
constructorName ConstructorInfo
con) (forall (t :: * -> *) a. Foldable t => t a -> Int
length (ConstructorInfo -> [Type]
constructorFields ConstructorInfo
con))
mkRepr :: Name -> DecsQ
mkRepr :: Name -> DecsQ
mkRepr Name
typeName = do
let reprTypeName :: Name
reprTypeName = Name -> Name
mkReprName Name
typeName
varName :: Name
varName = String -> Name
mkName String
"tp"
DatatypeInfo
info <- Name -> Q DatatypeInfo
lookupDataType' Name
typeName
let gc :: ConstructorInfo -> Q Con
gc ConstructorInfo
ci = do
let ctorName :: Name
ctorName = ConstructorInfo -> Name
constructorName ConstructorInfo
ci
reprCtorName :: Name
reprCtorName = Name -> Name
mkReprName Name
ctorName
ctorFieldTypeNames :: [Name]
ctorFieldTypeNames = Type -> Name
getCtorName forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ConstructorInfo -> [Type]
constructorFields ConstructorInfo
ci
ctorFieldReprNames :: [Name]
ctorFieldReprNames = Name -> Name
mkReprName forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [Name]
ctorFieldTypeNames
[Name]
tvars <- forall (m :: * -> *) a. Applicative m => Int -> m a -> m [a]
replicateM (forall (t :: * -> *) a. Foldable t => t a -> Int
length (ConstructorInfo -> [Type]
constructorFields ConstructorInfo
ci)) (forall (m :: * -> *). Quote m => String -> m Name
newName String
"tp")
let appliedType :: Type
appliedType =
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl Type -> Type -> Type
AppT (Name -> Type
PromotedT (ConstructorInfo -> Name
constructorName ConstructorInfo
ci)) (Name -> Type
VarT forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [Name]
tvars)
ctorType :: Type
ctorType = Type -> Type -> Type
AppT (Name -> Type
ConT Name
reprTypeName) Type
appliedType
ctorArgTypes :: [(Bang, Type)]
ctorArgTypes =
forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith (\Name
n Name
v -> (SourceUnpackedness -> SourceStrictness -> Bang
Bang SourceUnpackedness
NoSourceUnpackedness SourceStrictness
NoSourceStrictness, Type -> Type -> Type
AppT (Name -> Type
ConT Name
n) (Name -> Type
VarT Name
v))) [Name]
ctorFieldReprNames [Name]
tvars
forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ [Name] -> [(Bang, Type)] -> Type -> Con
GadtC
[Name
reprCtorName]
[(Bang, Type)]
ctorArgTypes
Type
ctorType
[Con]
ctors <- forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM ConstructorInfo -> Q Con
gc (DatatypeInfo -> [ConstructorInfo]
datatypeCons DatatypeInfo
info)
forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ [ [Type]
-> Name
-> [TyVarBndr ()]
-> Maybe Type
-> [Con]
-> [DerivClause]
-> Dec
DataD [] Name
reprTypeName
[Name -> Type -> TyVarBndr ()
kindedTV Name
varName (Name -> Type
ConT Name
typeName)]
forall a. Maybe a
Nothing
[Con]
ctors
[]
]
where getCtorName :: Type -> Name
getCtorName :: Type -> Name
getCtorName Type
c = case Type
c of
ConT Name
nm -> Name
nm
VarT Name
_ -> forall a. HasCallStack => String -> a
error forall a b. (a -> b) -> a -> b
$ String
"mkRepr cannot be used on polymorphic data kinds."
Type
_ -> forall a. HasCallStack => String -> a
error forall a b. (a -> b) -> a -> b
$ String
"mkRepr cannot be used on this data kind."
mkKnownReprs :: Name -> DecsQ
mkKnownReprs :: Name -> DecsQ
mkKnownReprs Name
typeName = do
Type
kr <- [t|KnownRepr|]
let krFName :: Name
krFName = String -> Name
mkName String
"knownRepr"
reprTypeName :: Name
reprTypeName = Name -> Name
mkReprName Name
typeName
DatatypeInfo
typeInfo <- Name -> Q DatatypeInfo
lookupDataType' Name
typeName
DatatypeInfo
reprInfo <- Name -> Q DatatypeInfo
lookupDataType' Name
reprTypeName
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
t a -> (a -> m b) -> m (t b)
forM (forall a b. [a] -> [b] -> [(a, b)]
zip (DatatypeInfo -> [ConstructorInfo]
datatypeCons DatatypeInfo
typeInfo) (DatatypeInfo -> [ConstructorInfo]
datatypeCons DatatypeInfo
reprInfo)) forall a b. (a -> b) -> a -> b
$ \(ConstructorInfo
tci, ConstructorInfo
rci) -> do
[Name]
vars <- forall (m :: * -> *) a. Applicative m => Int -> m a -> m [a]
replicateM (forall (t :: * -> *) a. Foldable t => t a -> Int
length (ConstructorInfo -> [Type]
constructorFields ConstructorInfo
tci)) (forall (m :: * -> *). Quote m => String -> m Name
newName String
"tp")
[Type]
krReqs <- forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
t a -> (a -> m b) -> m (t b)
forM (forall a b. [a] -> [b] -> [(a, b)]
zip (ConstructorInfo -> [Type]
constructorFields ConstructorInfo
tci) [Name]
vars) forall a b. (a -> b) -> a -> b
$ \(Type
tfld, Name
v) -> do
let fldReprName :: Name
fldReprName = Name -> Name
mkReprName (Type -> Name
getCtorName Type
tfld)
forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ Type -> Type -> Type
AppT (Type -> Type -> Type
AppT Type
kr (Name -> Type
ConT Name
fldReprName)) (Name -> Type
VarT Name
v)
let appliedType :: Type
appliedType =
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl Type -> Type -> Type
AppT (Name -> Type
PromotedT (ConstructorInfo -> Name
constructorName ConstructorInfo
tci)) (Name -> Type
VarT forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [Name]
vars)
krConstraint :: Type
krConstraint = Type -> Type -> Type
AppT (Type -> Type -> Type
AppT Type
kr (Name -> Type
ConT Name
reprTypeName)) Type
appliedType
krExp :: Exp
krExp = forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl Exp -> Exp -> Exp
AppE (Name -> Exp
ConE (ConstructorInfo -> Name
constructorName ConstructorInfo
rci)) forall a b. (a -> b) -> a -> b
$
forall a b. (a -> b) -> [a] -> [b]
map (forall a b. a -> b -> a
const (Name -> Exp
VarE Name
krFName)) [Name]
vars
krDec :: Dec
krDec = Name -> [Clause] -> Dec
FunD Name
krFName [[Pat] -> Body -> [Dec] -> Clause
Clause [] (Exp -> Body
NormalB Exp
krExp) []]
forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ Maybe Overlap -> [Type] -> Type -> [Dec] -> Dec
InstanceD forall a. Maybe a
Nothing [Type]
krReqs Type
krConstraint [Dec
krDec]
where getCtorName :: Type -> Name
getCtorName :: Type -> Name
getCtorName Type
c = case Type
c of
ConT Name
nm -> Name
nm
VarT Name
_ -> forall a. HasCallStack => String -> a
error forall a b. (a -> b) -> a -> b
$ String
"mkKnownReprs cannot be used on polymorphic data kinds."
Type
_ -> forall a. HasCallStack => String -> a
error forall a b. (a -> b) -> a -> b
$ String
"mkKnownReprs cannot be used on this data kind."
mkReprName :: Name -> Name
mkReprName :: Name -> Name
mkReprName Name
nm = String -> Name
mkName (Name -> String
nameBase Name
nm forall a. [a] -> [a] -> [a]
++ String
"Repr")
conPCompat :: Name -> [Pat] -> Pat
conPCompat :: Name -> [Pat] -> Pat
conPCompat Name
n [Pat]
pats = Name -> [Type] -> [Pat] -> Pat
ConP Name
n
#if MIN_VERSION_template_haskell(2,18,0)
[]
#endif
[Pat]
pats