{-# LANGUAGE CPP, MultiParamTypeClasses, FunctionalDependencies,
TypeSynonymInstances, FlexibleInstances, LambdaCase,
ScopedTypeVariables, PatternSynonyms #-}
module Language.Haskell.TH.Desugar (
DExp(..), DLetDec(..), NamespaceSpecifier(..), DPat(..),
DType(..), DForallTelescope(..), DKind, DCxt, DPred,
DTyVarBndr(..), DTyVarBndrSpec, DTyVarBndrUnit, Specificity(..),
DTyVarBndrVis,
#if __GLASGOW_HASKELL__ >= 907
BndrVis(..),
#else
BndrVis,
pattern BndrReq,
pattern BndrInvis,
#endif
DMatch(..), DClause(..), DDec(..),
DDerivClause(..), DDerivStrategy(..), DPatSynDir(..), DPatSynType,
Overlap(..), PatSynArgs(..), DataFlavor(..),
DTypeFamilyHead(..), DFamilyResultSig(..), InjectivityAnn(..),
DCon(..), DConFields(..), DDeclaredInfix, DBangType, DVarBangType,
Bang(..), SourceUnpackedness(..), SourceStrictness(..),
DForeign(..),
DPragma(..), DRuleBndr(..), DTySynEqn(..), DInfo(..), DInstanceDec,
Role(..), AnnTarget(..),
Desugar(..),
dsExp, dsDecs, dsType, dsInfo,
dsPatOverExp, dsPatsOverExp, dsPatX,
dsLetDecs, dsTvb, dsTvbSpec, dsTvbUnit, dsTvbVis, dsCxt,
dsCon, dsForeign, dsPragma, dsRuleBndr,
PatM, dsPred, dsPat, dsDec, dsDataDec, dsDataInstDec,
DerivingClause, dsDerivClause, dsLetDec,
dsMatches, dsBody, dsGuards, dsDoStmts, dsComp, dsClauses,
dsBangType, dsVarBangType,
dsTypeFamilyHead, dsFamilyResultSig,
#if __GLASGOW_HASKELL__ >= 801
dsPatSynDir,
#endif
dsTypeArg,
module Language.Haskell.TH.Desugar.Sweeten,
expand, expandType,
reifyWithWarning,
withLocalDeclarations, dsReify, dsReifyType,
reifyWithLocals_maybe, reifyWithLocals, reifyFixityWithLocals,
reifyTypeWithLocals_maybe, reifyTypeWithLocals,
lookupValueNameWithLocals, lookupTypeNameWithLocals,
mkDataNameWithLocals, mkTypeNameWithLocals,
reifyNameSpace,
DsMonad(..), DsM,
scExp, scLetDec,
module Language.Haskell.TH.Desugar.Subst,
module Language.Haskell.TH.Desugar.FV,
applyDExp,
dPatToDExp, removeWilds,
getDataD, dataConNameToDataName, dataConNameToCon,
nameOccursIn, allNamesIn, flattenDValD, getRecordSelectors,
mkTypeName, mkDataName, newUniqueName,
mkTupleDExp, mkTupleDPat, maybeDLetE, maybeDCaseE, mkDLamEFromDPats,
tupleNameDegree_maybe,
unboxedSumNameDegree_maybe, unboxedTupleNameDegree_maybe,
isTypeKindName, typeKindName, bindIP,
mkExtraDKindBinders, dTyVarBndrToDType, changeDTVFlags,
toposortTyVarsOf, toposortKindVarsOfTvbs,
FunArgs(..), ForallTelescope(..), VisFunArg(..),
filterVisFunArgs, ravelType, unravelType,
DFunArgs(..), DVisFunArg(..),
filterDVisFunArgs, ravelDType, unravelDType,
TypeArg(..), applyType, filterTANormals,
tyVarBndrVisToTypeArg, tyVarBndrVisToTypeArgWithSig,
unfoldType,
DTypeArg(..), applyDType, filterDTANormals,
dTyVarBndrVisToDTypeArg, dTyVarBndrVisToDTypeArgWithSig,
unfoldDType,
extractBoundNamesStmt, extractBoundNamesDec, extractBoundNamesPat
) where
import Language.Haskell.TH.Datatype.TyVarBndr
import Language.Haskell.TH.Desugar.AST
import Language.Haskell.TH.Desugar.Core
import Language.Haskell.TH.Desugar.Expand
import Language.Haskell.TH.Desugar.FV
import Language.Haskell.TH.Desugar.Match
import Language.Haskell.TH.Desugar.Reify
import Language.Haskell.TH.Desugar.Subst
import Language.Haskell.TH.Desugar.Sweeten
import Language.Haskell.TH.Desugar.Util
import Language.Haskell.TH.Syntax
import Control.Monad
import qualified Data.Foldable as F
import Data.Function
import qualified Data.Map as M
import qualified Data.Set as S
import Prelude hiding ( exp )
class Desugar th ds | ds -> th where
desugar :: DsMonad q => th -> q ds
sweeten :: ds -> th
instance Desugar Exp DExp where
desugar :: forall (q :: * -> *). DsMonad q => Exp -> q DExp
desugar = Exp -> q DExp
forall (q :: * -> *). DsMonad q => Exp -> q DExp
dsExp
sweeten :: DExp -> Exp
sweeten = DExp -> Exp
expToTH
instance Desugar Type DType where
desugar :: forall (q :: * -> *). DsMonad q => Type -> q DType
desugar = Type -> q DType
forall (q :: * -> *). DsMonad q => Type -> q DType
dsType
sweeten :: DType -> Type
sweeten = DType -> Type
typeToTH
instance Desugar Cxt DCxt where
desugar :: forall (q :: * -> *). DsMonad q => Cxt -> q DCxt
desugar = Cxt -> q DCxt
forall (q :: * -> *). DsMonad q => Cxt -> q DCxt
dsCxt
sweeten :: DCxt -> Cxt
sweeten = DCxt -> Cxt
cxtToTH
#if __GLASGOW_HASKELL__ >= 900
instance Desugar (TyVarBndr flag) (DTyVarBndr flag) where
desugar :: forall (q :: * -> *).
DsMonad q =>
TyVarBndr flag -> q (DTyVarBndr flag)
desugar = TyVarBndr flag -> q (DTyVarBndr flag)
forall (q :: * -> *) flag.
DsMonad q =>
TyVarBndr_ flag -> q (DTyVarBndr flag)
dsTvb
sweeten :: DTyVarBndr flag -> TyVarBndr flag
sweeten = DTyVarBndr flag -> TyVarBndr flag
forall flag. DTyVarBndr flag -> TyVarBndr flag
tvbToTH
#else
instance Desugar TyVarBndrSpec DTyVarBndrSpec where
desugar = dsTvbSpec
sweeten = tvbToTH
instance Desugar TyVarBndrUnit DTyVarBndrUnit where
desugar = dsTvbUnit
sweeten = tvbToTH
#endif
instance Desugar [Dec] [DDec] where
desugar :: forall (q :: * -> *). DsMonad q => [Dec] -> q [DDec]
desugar = [Dec] -> q [DDec]
forall (q :: * -> *). DsMonad q => [Dec] -> q [DDec]
dsDecs
sweeten :: [DDec] -> [Dec]
sweeten = [DDec] -> [Dec]
decsToTH
instance Desugar TypeArg DTypeArg where
desugar :: forall (q :: * -> *). DsMonad q => TypeArg -> q DTypeArg
desugar = TypeArg -> q DTypeArg
forall (q :: * -> *). DsMonad q => TypeArg -> q DTypeArg
dsTypeArg
sweeten :: DTypeArg -> TypeArg
sweeten = DTypeArg -> TypeArg
typeArgToTH
flattenDValD :: Quasi q => DLetDec -> q [DLetDec]
flattenDValD :: forall (q :: * -> *). Quasi q => DLetDec -> q [DLetDec]
flattenDValD dec :: DLetDec
dec@(DValD (DVarP Name
_) DExp
_) = [DLetDec] -> q [DLetDec]
forall a. a -> q a
forall (m :: * -> *) a. Monad m => a -> m a
return [DLetDec
dec]
flattenDValD (DValD DPat
pat DExp
exp) = do
x <- String -> q Name
forall (q :: * -> *). Quasi q => String -> q Name
newUniqueName String
"x"
let top_val_d = DPat -> DExp -> DLetDec
DValD (Name -> DPat
DVarP Name
x) DExp
exp
bound_names = OSet Name -> [Name]
forall a. OSet a -> [a]
forall (t :: * -> *) a. Foldable t => t a -> [a]
F.toList (OSet Name -> [Name]) -> OSet Name -> [Name]
forall a b. (a -> b) -> a -> b
$ DPat -> OSet Name
extractBoundNamesDPat DPat
pat
other_val_ds <- mapM (mk_val_d x) bound_names
return $ top_val_d : other_val_ds
where
mk_val_d :: Name -> Name -> m DLetDec
mk_val_d Name
x Name
name = do
y <- String -> m Name
forall (q :: * -> *). Quasi q => String -> q Name
newUniqueName String
"y"
let pat' = Name -> Name -> DPat -> DPat
wildify Name
name Name
y DPat
pat
match = DPat -> DExp -> DMatch
DMatch DPat
pat' (Name -> DExp
DVarE Name
y)
cas = DExp -> [DMatch] -> DExp
DCaseE (Name -> DExp
DVarE Name
x) [DMatch
match]
return $ DValD (DVarP name) cas
wildify :: Name -> Name -> DPat -> DPat
wildify Name
name Name
y DPat
p =
case DPat
p of
DLitP Lit
lit -> Lit -> DPat
DLitP Lit
lit
DVarP Name
n
| Name
n Name -> Name -> Bool
forall a. Eq a => a -> a -> Bool
== Name
name -> Name -> DPat
DVarP Name
y
| Bool
otherwise -> DPat
DWildP
DConP Name
con DCxt
ts [DPat]
ps -> Name -> DCxt -> [DPat] -> DPat
DConP Name
con DCxt
ts ((DPat -> DPat) -> [DPat] -> [DPat]
forall a b. (a -> b) -> [a] -> [b]
map (Name -> Name -> DPat -> DPat
wildify Name
name Name
y) [DPat]
ps)
DTildeP DPat
pa -> DPat -> DPat
DTildeP (Name -> Name -> DPat -> DPat
wildify Name
name Name
y DPat
pa)
DBangP DPat
pa -> DPat -> DPat
DBangP (Name -> Name -> DPat -> DPat
wildify Name
name Name
y DPat
pa)
DSigP DPat
pa DType
ty -> DPat -> DType -> DPat
DSigP (Name -> Name -> DPat -> DPat
wildify Name
name Name
y DPat
pa) DType
ty
DPat
DWildP -> DPat
DWildP
DTypeP DType
ty -> DType -> DPat
DTypeP DType
ty
DInvisP DType
ty -> DType -> DPat
DInvisP DType
ty
flattenDValD DLetDec
other_dec = [DLetDec] -> q [DLetDec]
forall a. a -> q a
forall (m :: * -> *) a. Monad m => a -> m a
return [DLetDec
other_dec]
getRecordSelectors :: DsMonad q => [DCon] -> q [DLetDec]
getRecordSelectors :: forall (q :: * -> *). DsMonad q => [DCon] -> q [DLetDec]
getRecordSelectors [DCon]
cons = [DLetDec] -> [DLetDec]
merge_let_decs ([DLetDec] -> [DLetDec]) -> q [DLetDec] -> q [DLetDec]
forall a b. (a -> b) -> q a -> q b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
`fmap` (DCon -> q [DLetDec]) -> [DCon] -> q [DLetDec]
forall (monad :: * -> *) monoid (t :: * -> *) a.
(Monad monad, Monoid monoid, Traversable t) =>
(a -> monad monoid) -> t a -> monad monoid
concatMapM DCon -> q [DLetDec]
forall {m :: * -> *}. Quasi m => DCon -> m [DLetDec]
get_record_sels [DCon]
cons
where
get_record_sels :: DCon -> m [DLetDec]
get_record_sels (DCon [DTyVarBndrSpec]
con_tvbs DCxt
_ Name
con_name DConFields
con_fields DType
con_ret_ty) =
case DConFields
con_fields of
DRecC [DVarBangType]
fields -> [DVarBangType] -> m [DLetDec]
forall {m :: * -> *} {b}.
Quasi m =>
[(Name, b, DType)] -> m [DLetDec]
go [DVarBangType]
fields
DNormalC{} -> [DLetDec] -> m [DLetDec]
forall a. a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return []
where
go :: [(Name, b, DType)] -> m [DLetDec]
go [(Name, b, DType)]
fields = do
varName <- String -> m Name
forall (q :: * -> *). Quasi q => String -> q Name
qNewName String
"field"
return $ concat
[ [ DSigD name $ DForallT (DForallInvis con_tvbs)
$ DArrowT `DAppT` con_ret_ty `DAppT` field_ty
, DFunD name [DClause [DConP con_name []
(mk_field_pats n (length fields) varName)]
(DVarE varName)] ]
| ((name, _strict, field_ty), n) <- zip fields [0..]
]
mk_field_pats :: Int -> Int -> Name -> [DPat]
mk_field_pats :: Int -> Int -> Name -> [DPat]
mk_field_pats Int
0 Int
total Name
name = Name -> DPat
DVarP Name
name DPat -> [DPat] -> [DPat]
forall a. a -> [a] -> [a]
: (Int -> DPat -> [DPat]
forall a. Int -> a -> [a]
replicate (Int
totalInt -> Int -> Int
forall a. Num a => a -> a -> a
-Int
1) DPat
DWildP)
mk_field_pats Int
n Int
total Name
name = DPat
DWildP DPat -> [DPat] -> [DPat]
forall a. a -> [a] -> [a]
: Int -> Int -> Name -> [DPat]
mk_field_pats (Int
nInt -> Int -> Int
forall a. Num a => a -> a -> a
-Int
1) (Int
totalInt -> Int -> Int
forall a. Num a => a -> a -> a
-Int
1) Name
name
merge_let_decs :: [DLetDec] -> [DLetDec]
merge_let_decs :: [DLetDec] -> [DLetDec]
merge_let_decs [DLetDec]
decs =
let (Map Name [DClause]
name_clause_map, [DLetDec]
decs') = Map Name [DClause]
-> Set Name -> [DLetDec] -> (Map Name [DClause], [DLetDec])
gather_decs Map Name [DClause]
forall k a. Map k a
M.empty Set Name
forall a. Set a
S.empty [DLetDec]
decs
in Map Name [DClause] -> [DLetDec] -> [DLetDec]
augment_clauses Map Name [DClause]
name_clause_map [DLetDec]
decs'
where
gather_decs :: M.Map Name [DClause] -> S.Set Name -> [DLetDec]
-> (M.Map Name [DClause], [DLetDec])
gather_decs :: Map Name [DClause]
-> Set Name -> [DLetDec] -> (Map Name [DClause], [DLetDec])
gather_decs Map Name [DClause]
name_clause_map Set Name
_ [] = (Map Name [DClause]
name_clause_map, [])
gather_decs Map Name [DClause]
name_clause_map Set Name
type_sig_names (DLetDec
x:[DLetDec]
xs)
| DFunD Name
n [DClause]
clauses <- DLetDec
x
= let name_clause_map' :: Map Name [DClause]
name_clause_map' = ([DClause] -> [DClause] -> [DClause])
-> Name -> [DClause] -> Map Name [DClause] -> Map Name [DClause]
forall k a. Ord k => (a -> a -> a) -> k -> a -> Map k a -> Map k a
M.insertWith (\[DClause]
new [DClause]
old -> [DClause]
old [DClause] -> [DClause] -> [DClause]
forall a. [a] -> [a] -> [a]
++ [DClause]
new)
Name
n [DClause]
clauses Map Name [DClause]
name_clause_map
in if Name
n Name -> Map Name [DClause] -> Bool
forall k a. Ord k => k -> Map k a -> Bool
`M.member` Map Name [DClause]
name_clause_map
then Map Name [DClause]
-> Set Name -> [DLetDec] -> (Map Name [DClause], [DLetDec])
gather_decs Map Name [DClause]
name_clause_map' Set Name
type_sig_names [DLetDec]
xs
else let (Map Name [DClause]
map', [DLetDec]
decs') = Map Name [DClause]
-> Set Name -> [DLetDec] -> (Map Name [DClause], [DLetDec])
gather_decs Map Name [DClause]
name_clause_map'
Set Name
type_sig_names [DLetDec]
xs
in (Map Name [DClause]
map', DLetDec
xDLetDec -> [DLetDec] -> [DLetDec]
forall a. a -> [a] -> [a]
:[DLetDec]
decs')
| DSigD Name
n DType
_ <- DLetDec
x
= if Name
n Name -> Set Name -> Bool
forall a. Ord a => a -> Set a -> Bool
`S.member` Set Name
type_sig_names
then Map Name [DClause]
-> Set Name -> [DLetDec] -> (Map Name [DClause], [DLetDec])
gather_decs Map Name [DClause]
name_clause_map Set Name
type_sig_names [DLetDec]
xs
else let (Map Name [DClause]
map', [DLetDec]
decs') = Map Name [DClause]
-> Set Name -> [DLetDec] -> (Map Name [DClause], [DLetDec])
gather_decs Map Name [DClause]
name_clause_map
(Name
n Name -> Set Name -> Set Name
forall a. Ord a => a -> Set a -> Set a
`S.insert` Set Name
type_sig_names) [DLetDec]
xs
in (Map Name [DClause]
map', DLetDec
xDLetDec -> [DLetDec] -> [DLetDec]
forall a. a -> [a] -> [a]
:[DLetDec]
decs')
| Bool
otherwise =
let (Map Name [DClause]
map', [DLetDec]
decs') = Map Name [DClause]
-> Set Name -> [DLetDec] -> (Map Name [DClause], [DLetDec])
gather_decs Map Name [DClause]
name_clause_map Set Name
type_sig_names [DLetDec]
xs
in (Map Name [DClause]
map', DLetDec
xDLetDec -> [DLetDec] -> [DLetDec]
forall a. a -> [a] -> [a]
:[DLetDec]
decs')
augment_clauses :: M.Map Name [DClause] -> [DLetDec] -> [DLetDec]
augment_clauses :: Map Name [DClause] -> [DLetDec] -> [DLetDec]
augment_clauses Map Name [DClause]
_ [] = []
augment_clauses Map Name [DClause]
name_clause_map (DLetDec
x:[DLetDec]
xs)
| DFunD Name
n [DClause]
_ <- DLetDec
x, Just [DClause]
merged_clauses <- Name
n Name -> Map Name [DClause] -> Maybe [DClause]
forall k a. Ord k => k -> Map k a -> Maybe a
`M.lookup` Map Name [DClause]
name_clause_map
= Name -> [DClause] -> DLetDec
DFunD Name
n [DClause]
merged_clausesDLetDec -> [DLetDec] -> [DLetDec]
forall a. a -> [a] -> [a]
:Map Name [DClause] -> [DLetDec] -> [DLetDec]
augment_clauses Map Name [DClause]
name_clause_map [DLetDec]
xs
| Bool
otherwise = DLetDec
xDLetDec -> [DLetDec] -> [DLetDec]
forall a. a -> [a] -> [a]
:Map Name [DClause] -> [DLetDec] -> [DLetDec]
augment_clauses Map Name [DClause]
name_clause_map [DLetDec]
xs
mkExtraDKindBinders :: forall q. DsMonad q => DKind -> q [DTyVarBndrVis]
DType
k = do
k' <- DType -> q DType
forall (q :: * -> *). DsMonad q => DType -> q DType
expandType DType
k
let (fun_args, _) = unravelDType k'
vis_fun_args = DFunArgs -> [DVisFunArg]
filterDVisFunArgs DFunArgs
fun_args
mapM mk_tvb vis_fun_args
where
mk_tvb :: DVisFunArg -> q (DTyVarBndrVis)
mk_tvb :: DVisFunArg -> q DTyVarBndrVis
mk_tvb (DVisFADep DTyVarBndrUnit
tvb) = DTyVarBndrVis -> q DTyVarBndrVis
forall a. a -> q a
forall (m :: * -> *) a. Monad m => a -> m a
return (BndrVis
BndrReq BndrVis -> DTyVarBndrUnit -> DTyVarBndrVis
forall a b. a -> DTyVarBndr b -> DTyVarBndr a
forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ DTyVarBndrUnit
tvb)
mk_tvb (DVisFAAnon DType
ki) = do
name <- String -> q Name
forall (q :: * -> *). Quasi q => String -> q Name
qNewName String
"a"
pure $ DKindedTV name BndrReq ki