{-# LANGUAGE CPP, TemplateHaskell #-}
module Language.Haskell.TH.Extras where
import Control.Monad
import Data.Generics
import Data.Maybe
import Data.Set (Set)
import qualified Data.Set as Set
import Language.Haskell.TH
import Language.Haskell.TH.Syntax
import Language.Haskell.TH.Datatype.TyVarBndr
intIs64 :: Bool
intIs64 :: Bool
intIs64 = forall a. Integral a => a -> Integer
toInteger (forall a. Bounded a => a
maxBound :: Int) forall a. Ord a => a -> a -> Bool
> Integer
2forall a b. (Num a, Integral b) => a -> b -> a
^(Integer
32 :: Integer)
replace :: (a -> Maybe a) -> (a -> a)
replace :: forall a. (a -> Maybe a) -> a -> a
replace = forall (m :: * -> *) a b. Monad m => m (a -> b) -> m a -> m b
ap forall a. a -> Maybe a -> a
fromMaybe
composeExprs :: [ExpQ] -> ExpQ
composeExprs :: [ExpQ] -> ExpQ
composeExprs [] = [| id |]
composeExprs [ExpQ
f] = ExpQ
f
composeExprs (ExpQ
f:[ExpQ]
fs) = [| $f . $(composeExprs fs) |]
nameOfCon :: Con -> Name
nameOfCon :: Con -> Name
nameOfCon (NormalC Name
name [BangType]
_) = Name
name
nameOfCon (RecC Name
name [VarBangType]
_) = Name
name
nameOfCon (InfixC BangType
_ Name
name BangType
_) = Name
name
nameOfCon (ForallC [TyVarBndr Specificity]
_ Cxt
_ Con
con) = Con -> Name
nameOfCon Con
con
#if defined(__GLASGOW_HASKELL__) && __GLASGOW_HASKELL__ >= 800
nameOfCon (GadtC [Name
name] [BangType]
_ Type
_) = Name
name
nameOfCon (GadtC [Name]
_ [BangType]
_ Type
_) = forall a. HasCallStack => [Char] -> a
error forall a b. (a -> b) -> a -> b
$ [Char]
"nameOfCon: GadtC: only single constructor names are supported"
nameOfCon (RecGadtC [Name
name] [VarBangType]
_ Type
_) = Name
name
nameOfCon (RecGadtC [Name]
_ [VarBangType]
_ Type
_) = forall a. HasCallStack => [Char] -> a
error forall a b. (a -> b) -> a -> b
$ [Char]
"nameOfCon: RecGadtC: only single constructor names are supported"
#endif
argTypesOfCon :: Con -> [Type]
argTypesOfCon :: Con -> Cxt
argTypesOfCon (NormalC Name
_ [BangType]
args) = forall a b. (a -> b) -> [a] -> [b]
map forall a b. (a, b) -> b
snd [BangType]
args
argTypesOfCon (RecC Name
_ [VarBangType]
args) = [Type
t | (Name
_,Bang
_,Type
t) <- [VarBangType]
args]
argTypesOfCon (InfixC BangType
x Name
_ BangType
y) = forall a b. (a -> b) -> [a] -> [b]
map forall a b. (a, b) -> b
snd [BangType
x,BangType
y]
argTypesOfCon (ForallC [TyVarBndr Specificity]
_ Cxt
_ Con
con) = Con -> Cxt
argTypesOfCon Con
con
#if defined(__GLASGOW_HASKELL__) && __GLASGOW_HASKELL__ >= 800
argTypesOfCon (GadtC [Name]
_ [BangType]
args Type
_) = forall a b. (a -> b) -> [a] -> [b]
map forall a b. (a, b) -> b
snd [BangType]
args
argTypesOfCon (RecGadtC [Name]
_ [VarBangType]
args Type
_) = [Type
t | (Name
_,Bang
_,Type
t) <- [VarBangType]
args]
#endif
nameOfBinder :: TyVarBndr_ a -> Name
nameOfBinder :: forall a. TyVarBndr_ a -> Name
nameOfBinder = forall a. TyVarBndr_ a -> Name
tvName
varsBoundInCon :: Con -> [TyVarBndrSpec]
varsBoundInCon :: Con -> [TyVarBndr Specificity]
varsBoundInCon (ForallC [TyVarBndr Specificity]
bndrs Cxt
_ Con
con) = [TyVarBndr Specificity]
bndrs forall a. [a] -> [a] -> [a]
++ Con -> [TyVarBndr Specificity]
varsBoundInCon Con
con
varsBoundInCon Con
_ = []
namesBoundInPat :: Pat -> [Name]
namesBoundInPat :: Pat -> [Name]
namesBoundInPat (VarP Name
name) = [Name
name]
namesBoundInPat (TupP [Pat]
pats) = [Pat]
pats forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= Pat -> [Name]
namesBoundInPat
#if MIN_VERSION_template_haskell(2,18,0)
namesBoundInPat (ConP Name
_ Cxt
_ [Pat]
pats) = [Pat]
pats forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= Pat -> [Name]
namesBoundInPat
#else
namesBoundInPat (ConP _ pats) = pats >>= namesBoundInPat
#endif
namesBoundInPat (InfixP Pat
p1 Name
_ Pat
p2) = Pat -> [Name]
namesBoundInPat Pat
p1 forall a. [a] -> [a] -> [a]
++ Pat -> [Name]
namesBoundInPat Pat
p2
namesBoundInPat (TildeP Pat
pat) = Pat -> [Name]
namesBoundInPat Pat
pat
namesBoundInPat (AsP Name
name Pat
pat) = Name
name forall a. a -> [a] -> [a]
: Pat -> [Name]
namesBoundInPat Pat
pat
namesBoundInPat (RecP Name
_ [FieldPat]
fieldPats) = forall a b. (a -> b) -> [a] -> [b]
map forall a b. (a, b) -> b
snd [FieldPat]
fieldPats forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= Pat -> [Name]
namesBoundInPat
namesBoundInPat (ListP [Pat]
pats) = [Pat]
pats forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= Pat -> [Name]
namesBoundInPat
namesBoundInPat (SigP Pat
pat Type
_) = Pat -> [Name]
namesBoundInPat Pat
pat
#if defined(__GLASGOW_HASKELL__) && __GLASGOW_HASKELL__ >= 612
namesBoundInPat (BangP Pat
pat) = Pat -> [Name]
namesBoundInPat Pat
pat
#endif
#if defined(__GLASGOW_HASKELL__) && __GLASGOW_HASKELL__ >= 700
namesBoundInPat (ViewP Exp
_ Pat
pat) = Pat -> [Name]
namesBoundInPat Pat
pat
#endif
#if defined(__GLASGOW_HASKELL__) && __GLASGOW_HASKELL__ >= 702
namesBoundInPat (UnboxedTupP [Pat]
pats) = [Pat]
pats forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= Pat -> [Name]
namesBoundInPat
#endif
namesBoundInPat Pat
_ = []
namesBoundInDec :: Dec -> [Name]
namesBoundInDec :: Dec -> [Name]
namesBoundInDec (FunD Name
name [Clause]
_) = [Name
name]
namesBoundInDec (ValD Pat
pat Body
_ [Dec]
_) = Pat -> [Name]
namesBoundInPat Pat
pat
#if defined(__GLASGOW_HASKELL__) && __GLASGOW_HASKELL__ >= 800
namesBoundInDec (DataD Cxt
_ Name
name [TyVarBndr ()]
_ Maybe Type
_ [Con]
_ [DerivClause]
_) = [Name
name]
namesBoundInDec (NewtypeD Cxt
_ Name
name [TyVarBndr ()]
_ Maybe Type
_ Con
_ [DerivClause]
_) = [Name
name]
#else
namesBoundInDec (DataD _ name _ _ _) = [name]
namesBoundInDec (NewtypeD _ name _ _ _) = [name]
#endif
namesBoundInDec (TySynD Name
name [TyVarBndr ()]
_ Type
_) = [Name
name]
namesBoundInDec (ClassD Cxt
_ Name
name [TyVarBndr ()]
_ [FunDep]
_ [Dec]
_) = [Name
name]
namesBoundInDec (ForeignD (ImportF Callconv
_ Safety
_ [Char]
_ Name
name Type
_)) = [Name
name]
#if defined(__GLASGOW_HASKELL__)
#if __GLASGOW_HASKELL__ >= 800
namesBoundInDec (OpenTypeFamilyD (TypeFamilyHead Name
name [TyVarBndr ()]
_ FamilyResultSig
_ Maybe InjectivityAnn
_)) = [Name
name]
namesBoundInDec (ClosedTypeFamilyD (TypeFamilyHead Name
name [TyVarBndr ()]
_ FamilyResultSig
_ Maybe InjectivityAnn
_) [TySynEqn]
_) = [Name
name]
#elif __GLASGOW_HASKELL__ >= 612
namesBoundInDec (FamilyD _ name _ _) = [name]
#endif
#endif
namesBoundInDec Dec
_ = []
genericalizeName :: Name -> Name
genericalizeName :: Name -> Name
genericalizeName = [Char] -> Name
mkName forall b c a. (b -> c) -> (a -> b) -> a -> c
. Name -> [Char]
nameBase
genericalizeDecs :: [Dec] -> [Dec]
genericalizeDecs :: [Dec] -> [Dec]
genericalizeDecs [Dec]
decs = (forall a. Data a => a -> a) -> forall a. Data a => a -> a
everywhere (forall a b. (Typeable a, Typeable b) => (b -> b) -> a -> a
mkT Name -> Name
fixName) [Dec]
decs
where
names :: [Name]
names = [Dec]
decs forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= Dec -> [Name]
namesBoundInDec
genericalizedNames :: [(Name, Name)]
genericalizedNames = [ (Name
n, Name -> Name
genericalizeName Name
n) | Name
n <- [Name]
names]
fixName :: Name -> Name
fixName = forall a. (a -> Maybe a) -> a -> a
replace (forall a b. Eq a => a -> [(a, b)] -> Maybe b
`lookup` [(Name, Name)]
genericalizedNames)
headOfType :: Type -> Name
headOfType :: Type -> Name
headOfType (ForallT [TyVarBndr Specificity]
_ Cxt
_ Type
ty) = Type -> Name
headOfType Type
ty
headOfType (VarT Name
name) = Name
name
headOfType (ConT Name
name) = Name
name
headOfType (TupleT Int
n) = Int -> Name
tupleTypeName Int
n
headOfType Type
ArrowT = ''(->)
headOfType Type
ListT = ''[]
headOfType (AppT Type
t Type
_) = Type -> Name
headOfType Type
t
#if defined(__GLASGOW_HASKELL__) && __GLASGOW_HASKELL__ >= 612
headOfType (SigT Type
t Type
_) = Type -> Name
headOfType Type
t
#endif
#if defined(__GLASGOW_HASKELL__) && __GLASGOW_HASKELL__ >= 702
headOfType (UnboxedTupleT Int
n) = Int -> Name
unboxedTupleTypeName Int
n
#endif
#if defined (__GLASGOW_HASKELL__) && __GLASGOW_HASKELL__ >= 704
headOfType Type
ty = forall a. HasCallStack => [Char] -> a
error forall a b. (a -> b) -> a -> b
$ [Char]
"headOfType: Unhandled type: " forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> [Char]
show Type
ty
#endif
occursInType :: Name -> Type -> Bool
occursInType :: Name -> Type -> Bool
occursInType Name
var Type
ty = case Type
ty of
ForallT [TyVarBndr Specificity]
bndrs Cxt
_ Type
ty'
| forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
any (Name
var forall a. Eq a => a -> a -> Bool
==) (forall a b. (a -> b) -> [a] -> [b]
map forall a. TyVarBndr_ a -> Name
tvName [TyVarBndr Specificity]
bndrs)
-> Bool
False
| Bool
otherwise
-> Name -> Type -> Bool
occursInType Name
var Type
ty'
VarT Name
name
| Name
name forall a. Eq a => a -> a -> Bool
== Name
var -> Bool
True
| Bool
otherwise -> Bool
False
AppT Type
ty1 Type
ty2 -> Name -> Type -> Bool
occursInType Name
var Type
ty1 Bool -> Bool -> Bool
|| Name -> Type -> Bool
occursInType Name
var Type
ty2
#if defined(__GLASGOW_HASKELL__) && __GLASGOW_HASKELL__ >= 612
SigT Type
ty' Type
_ -> Name -> Type -> Bool
occursInType Name
var Type
ty'
#endif
Type
_ -> Bool
False
substVarsWith
:: [Name]
-> Type
-> Type
-> Type
substVarsWith :: [Name] -> Type -> Type -> Type
substVarsWith [Name]
topVars Type
resultType Type
argType = Set Name -> Type -> Type
subst forall a. Set a
Set.empty Type
argType
where
topVars' :: [Name]
topVars' = forall a. [a] -> [a]
reverse [Name]
topVars
AppT Type
resultType' Type
_indexType = Type
resultType
subst :: Set Name -> Type -> Type
subst :: Set Name -> Type -> Type
subst Set Name
bs Type
ty = case Type
ty of
#if defined(__GLASGOW_HASKELL__) && __GLASGOW_HASKELL__ >= 710
ForallT [TyVarBndr Specificity]
bndrs Cxt
cxt Type
t ->
let bs' :: Set Name
bs' = forall a. Ord a => Set a -> Set a -> Set a
Set.union Set Name
bs (forall a. Ord a => [a] -> Set a
Set.fromList (forall a b. (a -> b) -> [a] -> [b]
map forall a. TyVarBndr_ a -> Name
tvName [TyVarBndr Specificity]
bndrs))
in [TyVarBndr Specificity] -> Cxt -> Type -> Type
ForallT [TyVarBndr Specificity]
bndrs (forall a b. (a -> b) -> [a] -> [b]
map (Set Name -> Type -> Type
subst Set Name
bs') Cxt
cxt) (Set Name -> Type -> Type
subst Set Name
bs' Type
t)
#else
ForallT {} -> error "substVarsWith: ForallT substitutions have not been implemented for GHCs prior to 7.10"
#endif
AppT Type
f Type
x -> Type -> Type -> Type
AppT (Set Name -> Type -> Type
subst Set Name
bs Type
f) (Set Name -> Type -> Type
subst Set Name
bs Type
x)
SigT Type
t Type
k -> Type -> Type -> Type
SigT (Set Name -> Type -> Type
subst Set Name
bs Type
t) Type
k
VarT Name
v -> if forall a. Ord a => a -> Set a -> Bool
Set.member Name
v Set Name
bs
then Name -> Type
VarT Name
v
else Name -> Type
VarT (forall {a}. Name -> [a] -> Type -> a
findVar Name
v [Name]
topVars' Type
resultType')
ConT Name
n -> Name -> Type
ConT Name
n
TupleT Int
k -> Int -> Type
TupleT Int
k
Type
ArrowT -> Type
ArrowT
Type
ListT -> Type
ListT
#if defined(__GLASGOW_HASKELL__) && __GLASGOW_HASKELL__ >= 800
InfixT Type
t1 Name
x Type
t2 -> Type -> Name -> Type -> Type
InfixT (Set Name -> Type -> Type
subst Set Name
bs Type
t1) Name
x (Set Name -> Type -> Type
subst Set Name
bs Type
t2)
ParensT Type
t -> Type -> Type
ParensT (Set Name -> Type -> Type
subst Set Name
bs Type
t)
UInfixT Type
t1 Name
x Type
t2 -> Type -> Name -> Type -> Type
UInfixT (Set Name -> Type -> Type
subst Set Name
bs Type
t1) Name
x (Set Name -> Type -> Type
subst Set Name
bs Type
t2)
Type
WildCardT -> Type
WildCardT
#endif
#if defined(__GLASGOW_HASKELL__) && __GLASGOW_HASKELL__ >= 802
UnboxedSumT Int
k -> Int -> Type
UnboxedSumT Int
k
#endif
#if defined (__GLASGOW_HASKELL__) && __GLASGOW_HASKELL__ >= 710
Type
EqualityT -> Type
EqualityT
#endif
#if defined (__GLASGOW_HASKELL__) && __GLASGOW_HASKELL__ >= 706
Type
ConstraintT -> Type
ConstraintT
LitT TyLit
l -> TyLit -> Type
LitT TyLit
l
Type
PromotedConsT -> Type
PromotedConsT
Type
PromotedNilT -> Type
PromotedNilT
PromotedT Name
n -> Name -> Type
PromotedT Name
n
PromotedTupleT Int
k -> Int -> Type
PromotedTupleT Int
k
Type
StarT -> Type
StarT
#endif
#if defined (__GLASGOW_HASKELL__) && __GLASGOW_HASKELL__ > 700
UnboxedTupleT Int
k -> Int -> Type
UnboxedTupleT Int
k
#endif
findVar :: Name -> [a] -> Type -> a
findVar Name
v (a
tv:[a]
_) (AppT Type
_ (VarT Name
v')) | Name
v forall a. Eq a => a -> a -> Bool
== Name
v' = a
tv
findVar Name
v (a
_:[a]
tvs) (AppT Type
t (VarT Name
_)) = Name -> [a] -> Type -> a
findVar Name
v [a]
tvs Type
t
findVar Name
v [a]
_ Type
_ = forall a. HasCallStack => [Char] -> a
error forall a b. (a -> b) -> a -> b
$ [Char]
"substVarsWith: couldn't look up variable substitution for " forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> [Char]
show Name
v
forall a. [a] -> [a] -> [a]
++ [Char]
" with topVars: " forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> [Char]
show [Name]
topVars forall a. [a] -> [a] -> [a]
++ [Char]
" resultType: " forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> [Char]
show Type
resultType forall a. [a] -> [a] -> [a]
++ [Char]
" argType: " forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> [Char]
show Type
argType
kindArity :: Kind -> Int
#if defined (__GLASGOW_HASKELL__) && __GLASGOW_HASKELL__ < 706
kindArity k = case k of
StarK -> 0
ArrowK _ k2 -> 1 + kindArity k2
#else
kindArity :: Type -> Int
kindArity Type
k = case Type
k of
ForallT [TyVarBndr Specificity]
_ Cxt
_ Type
t -> Type -> Int
kindArity Type
t
AppT (AppT Type
ArrowT Type
_) Type
t -> Int
1 forall a. Num a => a -> a -> a
+ Type -> Int
kindArity Type
t
SigT Type
t Type
_ -> Type -> Int
kindArity Type
t
#if defined (__GLASGOW_HASKELL__) && __GLASGOW_HASKELL__ >= 800
ParensT Type
t -> Type -> Int
kindArity Type
t
#endif
Type
_ -> Int
0
#endif
tyConArity :: Name -> Q Int
tyConArity :: Name -> Q Int
tyConArity Name
n = do
([TyVarBndr ()]
ts, Int
ka) <- Name -> Q ([TyVarBndr ()], Int)
tyConArity' Name
n
forall (m :: * -> *) a. Monad m => a -> m a
return (forall (t :: * -> *) a. Foldable t => t a -> Int
length [TyVarBndr ()]
ts forall a. Num a => a -> a -> a
+ Int
ka)
#if defined(__GLASGOW_HASKELL__) && __GLASGOW_HASKELL__ < 908
tyConArity' :: Name -> Q ([TyVarBndrUnit], Int)
#else
tyConArity' :: Name -> Q ([TyVarBndr BndrVis], Int)
#endif
tyConArity' :: Name -> Q ([TyVarBndr ()], Int)
tyConArity' Name
n = do
Info
r <- Name -> Q Info
reify Name
n
forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ case Info
r of
#if defined(__GLASGOW_HASKELL__) && __GLASGOW_HASKELL__ >= 800
TyConI (DataD Cxt
_ Name
_ [TyVarBndr ()]
ts Maybe Type
mk [Con]
_ [DerivClause]
_) -> ([TyVarBndr ()]
ts, forall a. a -> Maybe a -> a
fromMaybe Int
0 (forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Type -> Int
kindArity Maybe Type
mk))
TyConI (NewtypeD Cxt
_ Name
_ [TyVarBndr ()]
ts Maybe Type
mk Con
_ [DerivClause]
_) -> ([TyVarBndr ()]
ts, forall a. a -> Maybe a -> a
fromMaybe Int
0 (forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Type -> Int
kindArity Maybe Type
mk))
#else
TyConI (DataD _ _ ts _ _) -> (ts, 0)
TyConI (NewtypeD _ _ ts _ _) -> (ts, 0)
#endif
Info
_ -> forall a. HasCallStack => [Char] -> a
error forall a b. (a -> b) -> a -> b
$ [Char]
"tyConArity': Supplied name reified to something other than a data declaration: " forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> [Char]
show Name
n
decCons :: Dec -> [Con]
decCons :: Dec -> [Con]
decCons Dec
d = case Dec
d of
#if defined(__GLASGOW_HASKELL__) && __GLASGOW_HASKELL__ >= 800
DataD Cxt
_ Name
_ [TyVarBndr ()]
_ Maybe Type
_ [Con]
cs [DerivClause]
_ -> [Con]
cs
NewtypeD Cxt
_ Name
_ [TyVarBndr ()]
_ Maybe Type
_ Con
c [DerivClause]
_ -> [Con
c]
#else
DataD _ _ _ cs _ -> cs
NewtypeD _ _ _ c _ -> [c]
#endif
Dec
_ -> forall a. HasCallStack => [Char] -> a
error [Char]
"decCons: Declaration found was not a data or newtype declaration."
conArity :: Con -> Int
conArity :: Con -> Int
conArity Con
c = case Con
c of
NormalC Name
_ [BangType]
ts -> forall (t :: * -> *) a. Foldable t => t a -> Int
length [BangType]
ts
RecC Name
_ [VarBangType]
ts -> forall (t :: * -> *) a. Foldable t => t a -> Int
length [VarBangType]
ts
InfixC BangType
_ Name
_ BangType
_ -> Int
2
ForallC [TyVarBndr Specificity]
_ Cxt
_ Con
c' -> Con -> Int
conArity Con
c'
#if defined(__GLASGOW_HASKELL__) && __GLASGOW_HASKELL__ >= 800
GadtC [Name]
_ [BangType]
ts Type
_ -> forall (t :: * -> *) a. Foldable t => t a -> Int
length [BangType]
ts
RecGadtC [Name]
_ [VarBangType]
ts Type
_ -> forall (t :: * -> *) a. Foldable t => t a -> Int
length [VarBangType]
ts
#endif