haskell-src-meta 0.1.1 → 0.2
raw patch · 7 files changed
+294/−46 lines, 7 filesdep ~basedep ~containersdep ~template-haskellPVP ok
version bump matches the API change (PVP)
Dependency ranges changed: base, containers, template-haskell
API changes (from Hackage documentation)
+ Language.Haskell.Meta.QQ.ADo: ado :: QuasiQuoter
+ Language.Haskell.Meta.QQ.ADo: ado' :: QuasiQuoter
+ Language.Haskell.Meta.Syntax.Translate: toBody :: GuardedAlts -> Body
+ Language.Haskell.Meta.Syntax.Translate: toMatch :: Alt -> Match
Files
- haskell-src-meta.cabal +4/−3
- src/Language/Haskell/Meta/QQ/ADo.hs +149/−0
- src/Language/Haskell/Meta/QQ/HsHere.hs +8/−0
- src/Language/Haskell/Meta/Syntax/Translate.hs +47/−8
- src/Language/Haskell/Meta/Syntax/Vars.hs +8/−2
- src/Language/Haskell/Meta/Utils.hs +39/−23
- src/Language/Haskell/TH/Instances/Lift.hs +39/−10
haskell-src-meta.cabal view
@@ -1,5 +1,5 @@ name: haskell-src-meta-version: 0.1.1+version: 0.2 cabal-version: >= 1.6 build-type: Simple license: BSD3@@ -14,9 +14,9 @@ to template-haskell abstract syntax isn't 100% complete yet. library- build-depends: base == 4.2.*, containers == 0.3.*,+ build-depends: base >= 4.1 && < 4.3, containers >= 0.2 && < 0.4, haskell-src-exts >= 1.6 && < 1.10,- template-haskell == 2.4.*,+ template-haskell >= 2.3 && < 2.5, pretty == 1.0.*, syb >= 0.1 && < 0.2, th-lift == 0.5.* hs-source-dirs: src exposed-modules: Language.Haskell.Meta,@@ -26,6 +26,7 @@ Language.Haskell.Meta.Syntax.Translate, Language.Haskell.TH.Instances.Lift, Language.Haskell.Meta.Utils,+ Language.Haskell.Meta.QQ.ADo, Language.Haskell.Meta.QQ.Hs, Language.Haskell.Meta.QQ.Here, Language.Haskell.Meta.QQ.HsHere,
+ src/Language/Haskell/Meta/QQ/ADo.hs view
@@ -0,0 +1,149 @@+{-# LANGUAGE PatternGuards, TemplateHaskell, QuasiQuotes #-}++-- | Applicative do. Phillipa Cowderoy's idea, some explanations due Edward+-- Kmett+--+-- Pointful version of "Language.Haskell.Meta.QQ.Idiom". Note the only+-- expression which has the bound variables in scope is the last one.+--+-- This lets you work with applicatives without the order of fields in an data+-- constructor becoming such a burden.+--+-- In a similar role as 'fail' in do notation, if match failures can be+-- expected, the result is an @Applicative f => f (Maybe a)@, rather than+-- @Applicative f => f a@, where @a@ may be partially defined.+module Language.Haskell.Meta.QQ.ADo (++ ado,+ ado'++ -- * Desugaring+ -- $desugaring+ ) where++import Control.Applicative+import Language.Haskell.Meta+import Language.Haskell.TH.Lib+import Language.Haskell.TH.Quote+import Language.Haskell.TH.Syntax+import Control.Monad+import qualified Data.Set as S++import Language.Haskell.Meta.Utils (cleanNames)++import Data.Generics++-- $desugaring+--+-- If you use patterns that may fail:+--+-- > foo :: Applicative f => f (Maybe T)+-- > foo = [$ado|+-- > x:xs <- foo bar baz+-- > Just y <- quux quaffle+-- > T x y |]+--+-- 'ado' desugars to:+--+-- > foo = (\x y -> case (x,y) of+-- > (x:xs,Just y) -> Just $ T x y+-- > _ -> Nothing+-- > ) <$> foo bar baz <*> quux quaffle+--+-- While 'ado'' desugars to the less safe:+--+-- > foo = (\(x:xs) (Just y) -> T x y) <$> foo bar baz <*> quux quaffle+--+-- If the simple patterns cannot fail, there is no 'Maybe' for the 'ado' quote,+-- just like 'ado'':+--+-- > newtype A = A Int+-- > foo :: Applicative f => f T+-- > foo = [$ado|+-- > ~(x:xs) <- foo bar baz+-- > A y <- quux quaffle+-- > T x y |]+--+-- Becomes:+--+-- > foo = (\ ~(x:xs) (A y) -> T x y) <$> foo bar baz <*> quux quaffle++-- | Usage:+--+-- > ghci> [$ado| a <- "foo"; b <- "bar"; (a,b) |]+-- > [('f','b'),('f','a'),('f','r'),('o','b'),('o','a'),('o','r'),('o','b'),('o','a'),('o','r')]+--+-- > ghci> [$ado| Just a <- [Just 1,Nothing,Just 2]; b <- "fo"; (a,b) |]+-- > [Just (1,'f'),Just (1,'o'),Nothing,Nothing,Just (2,'f'),Just (2,'o')]+ado :: QuasiQuoter+ado = ado'' False++-- | Variant of 'ado' that does not implicitly add a Maybe when patterns may fail:+--+-- > ghci> [$ado'| Just a <- [Just 1,Nothing,Just 2]; b <- "fo"; (a,b) |]+-- > [(1,'f'),(1,'o'),*** Exception: <interactive>:...+--+ado' :: QuasiQuoter+ado' = ado'' True++ado'' :: Bool -> QuasiQuoter+ado'' b = QuasiQuoter+ (\str -> fmap cleanNames $ applicate b =<< parseDo str)+ (either fail return . parsePat)++parseDo :: (Monad m) => String -> m [Stmt]+parseDo str =+ let prefix = "do\n" in+ case parseExp $ prefix ++ str of+ Right (DoE stmts) -> return stmts+ Right a -> fail $ "ado can't handle:\n" ++ show a+ Left a -> fail a++applicate :: Bool -> [Stmt] -> ExpQ+applicate rawPatterns stmt = do+ (_:ps,f:es) <- fmap (unzip . reverse) $+ flip mapM stmt $ \s ->+ case s of+ BindS p e -> return (p,e)+ NoBindS e -> return (WildP,e)+ LetS _ -> fail $ "LetS not supported"+ ParS _ -> fail $ "ParS not supported"++ fps <- failingPatterns ps+ f' <- case filter (not . snd) $ zip ps fps of+ [] -> return $ LamE ps f+ _ | rawPatterns -> return $ LamE ps f+ | otherwise -> do+ xs <- mapM (const $ newName "x") ps+ return $ LamE (map VarP xs) $ CaseE (TupE (map VarE xs))+ [Match (TupP ps) (NormalB $ ConE 'Just `AppE` f) []+ ,Match WildP (NormalB $ ConE 'Nothing) []+ ]++ return $ foldl (\g e -> VarE '(<**>) `AppE` e `AppE` g)+ (VarE 'pure `AppE` f')+ es++failingPatterns :: (Data a) => [a] -> Q [Bool]+failingPatterns ps = flip mapM ps $ \p ->+ let couldFail x = liftM not (singleCon x)++ constrs :: Data a => a -> S.Set Name+ constrs = S.fromList . map (\(ConP n _) -> n)+ . listify (\x -> case x of ConP {} -> True; _ -> False)+ irrefutables = constrs+ . listify (\x -> case x of TildeP {} -> True; _ -> False)++ in liftM null $ filterM couldFail $ S.elems $+ constrs p S.\\ irrefutables p++singleCon :: Name -> Q Bool+singleCon n = do+ DataConI _ _ tn _ <- reify n+ TyConI dec <- reify tn+ case dec of+ DataD _ _ _ [_] _ -> return True+ NewtypeD {} -> return True+ DataD _ _ _ (_:_) _ -> return False+ _ -> fail $ "Bad dec: "++show dec+
src/Language/Haskell/Meta/QQ/HsHere.hs view
@@ -18,6 +18,14 @@ | ManyH [Here] deriving (Eq,Show,Data,Typeable) +-- | Example:+--+-- > a x = [$here| random "text" $(x + 1)+-- > something else|]+--+-- Is like:+--+-- > a x = " random \"text\" "++ show (x + 1) ++"\n something else" here :: QuasiQuoter here = QuasiQuoter {quoteExp = hereExpQ
src/Language/Haskell/Meta/Syntax/Translate.hs view
@@ -1,4 +1,4 @@-{-# LANGUAGE TemplateHaskell, TypeSynonymInstances #-}+{-# LANGUAGE CPP, TemplateHaskell, TypeSynonymInstances #-} {- | Module : Language.Haskell.Meta.Syntax.Translate@@ -135,9 +135,11 @@ toLit (Hs.PrimChar a) = CharL a -- XXX toLit (Hs.PrimString a) = StringL a -- XXX toLit (Hs.PrimInt a) = IntPrimL a- toLit (Hs.PrimWord a) = WordPrimL a toLit (Hs.PrimFloat a) = FloatPrimL a toLit (Hs.PrimDouble a) = DoublePrimL a+#if MIN_VERSION_template_haskell(2,4,0)+ toLit (Hs.PrimWord a) = WordPrimL a+#endif /* MIN_VERSION_template_haskell(2,4,0) */ -----------------------------------------------------------------------------@@ -171,7 +173,9 @@ toPat (Hs.PXETag _ _ _ pM) = error "toPat: HsPXETag not supported" toPat (Hs.PXPcdata _) = error "toPat: HsPXPcdata not supported" toPat (Hs.PXPatTag p) = error "toPat: HsPXPatTag not supported"+#if MIN_VERSION_template_haskell(2,4,0) toPat (Hs.PBangPat p) = BangP (toPat p)+#endif /* MIN_VERSION_template_haskell(2,4,0) */ ----------------------------------------------------------------------------- @@ -214,8 +218,7 @@ toExp (Hs.Let bs e) = LetE (hsBindsToDecs bs) (toExp e) -- toExp (HsWith e bs toExp (Hs.If a b c) = CondE (toExp a) (toExp b) (toExp c)- -- toExp (HsCase e xs)- -- toExp (HsDo ss)+ toExp (Hs.Do ss) = DoE (map toStmt ss) -- toExp (HsMDo ss) toExp (Hs.Tuple xs) = TupE (fmap toExp xs) toExp (Hs.List xs) = ListE (fmap toExp xs)@@ -228,7 +231,7 @@ toExp (Hs.EnumFromThenTo e f g) = ArithSeqE $ FromThenToR (toExp e) (toExp f) (toExp g) toExp (Hs.ExpTypeSig _ e t) = SigE (toExp e) (toType t) -- HsListComp HsExp [HsStmt]- -- toExp (HsListComp e ss) = CompE + -- toExp (HsListComp e ss) = CompE -- NEED: a way to go e -> Stmt toExp a@(Hs.ListComp e ss) = error $ errorMsg "toExp" a {- HsVarQuote HsQName@@ -250,9 +253,19 @@ toExp (Hs.IdSplice s) = VarE (toName s) toExp (Hs.ParenSplice e) = toExp e +toMatch :: Hs.Alt -> Match toMatch (Hs.Alt _ p galts ds) = Match (toPat p) (toBody galts) (toDecs ds)++toBody :: Hs.GuardedAlts -> Body toBody (Hs.UnGuardedAlt e) = NormalB $ toExp e-toBody (Hs.GuardedAlts alts) = GuardedB $ map toGuard alts+toBody (Hs.GuardedAlts alts) = GuardedB $ do+ Hs.GuardedAlt _ stmts e <- alts+ let+ g = case map toStmt stmts of+ [NoBindS x] -> NormalG x+ xs -> PatG xs+ return (g, toExp e)+ toGuard (Hs.GuardedAlt _ ([Hs.Qualifier e1]) e2) = (NormalG $ toExp e1,toExp e2) -----------------------------------------------------------------------------@@ -301,20 +314,33 @@ toName (Hs.KindedVar n _) = toName n toName (Hs.UnkindedVar n) = toName n +instance ToName Name where+ toName = id++#if MIN_VERSION_template_haskell(2,4,0) instance ToName TyVarBndr where toName (PlainTV n) = n toName (KindedTV n _) = n+#endif /* !MIN_VERSION_template_haskell(2,4,0) */ +#if MIN_VERSION_template_haskell(2,4,0) toKind :: Hs.Kind -> Kind toKind Hs.KindStar = StarK toKind (Hs.KindFn k1 k2) = ArrowK (toKind k1) (toKind k2) toKind (Hs.KindParen kp) = toKind kp toKind Hs.KindBang = error "toKind: HsKindBang not supported" toKind (Hs.KindVar _) = error "toKind: HsKindVar not supported"+#endif /* !MIN_VERSION_template_haskell(2,4,0) */ +#if MIN_VERSION_template_haskell(2,4,0) toTyVar :: Hs.TyVarBind -> TyVarBndr toTyVar (Hs.KindedVar n k) = KindedTV (toName n) (toKind k) toTyVar (Hs.UnkindedVar n) = PlainTV (toName n)+#else /* !MIN_VERSION_template_haskell(2,4,0) */+toTyVar :: Hs.TyVarBind -> Name+toTyVar (Hs.KindedVar n _) = toName n+toTyVar (Hs.UnkindedVar n) = toName n+#endif /* !MIN_VERSION_template_haskell(2,4,0) */ {- | TH does't handle@@ -350,10 +376,17 @@ toCxt :: Hs.Context -> Cxt toCxt = fmap toPred where+#if MIN_VERSION_template_haskell(2,4,0) toPred (Hs.ClassA n ts) = ClassP (toName n) (fmap toType ts) toPred (Hs.InfixA t1 n t2) = ClassP (toName n) (fmap toType [t1, t2]) toPred (Hs.EqualP t1 t2) = EqualP (toType t1) (toType t2)- toPred a@(Hs.IParam _ _) = error $ errorMsg "toType" a+ toPred a@(Hs.IParam _ _) = error $ errorMsg "toPred" a+#else /* !MIN_VERSION_template_haskell(2,4,0) */+ toPred (Hs.ClassA n ts) = foldAppT (ConT (toName n)) (fmap toType ts)+ toPred (Hs.InfixA t1 n t2) = foldAppT (ConT (toName n)) (fmap toType [t1, t2])+ toPred a@(Hs.EqualP _ _) = error $ errorMsg "toPred" a+ toPred a@(Hs.IParam _ _) = error $ errorMsg "toPred" a+#endif /* !MIN_VERSION_template_haskell(2,4,0) */ foldAppT :: Type -> [Type] -> Type foldAppT t ts = foldl' AppT t ts@@ -454,7 +487,7 @@ toDec a@(Hs.InfixDecl _ asst i ops) = error $ errorMsg "toDec" a toDec a@(Hs.ClassDecl _ cxt n ns funDeps cDecs) = error $ errorMsg "toDec" a toDec a@(Hs.InstDecl _ cxt qn ts instDecs) = error $ errorMsg "toDec" a- toDec a@(Hs.DerivDecl _ cxt qn ts) = error $ errorMsg "toDec" a + toDec a@(Hs.DerivDecl _ cxt qn ts) = error $ errorMsg "toDec" a toDec a@(Hs.DefaultDecl _ ts) = error $ errorMsg "toDec" a toDec a@(Hs.SpliceDecl _ s) = error $ errorMsg "toDec" a -- This type-signature conversion is just wrong. @@ -463,8 +496,10 @@ -- XXXXXXXXXXXXXX: oh crap, we can't return a [Dec] from this class! = let xs = fmap (flip SigD (toType t) . toName) ns in case xs of x:_ -> x; [] -> error "toDec: malformed TypeSig!"+#if MIN_VERSION_template_haskell(2,4,0) toDec (Hs.InlineSig _ b act id) = PragmaD $ InlineP (toName id) (InlineSpec True False Nothing)+#endif /* MIN_VERSION_template_haskell(2,4,0) */ {- data HsDecl = ... | HsFunBind [HsMatch] | ... data HsMatch = HsMatch SrcLoc HsName [HsPat] HsRhs HsBinds@@ -582,7 +617,11 @@ toDecs a = [toDec a] collectVars e = case e of+#if MIN_VERSION_template_haskell(2,4,0) VarT n -> [PlainTV n]+#else /* !MIN_VERSION_template_haskell(2,4,0) */+ VarT n -> [n]+#endif /* !MIN_VERSION_template_haskell(2,4,0) */ AppT t1 t2 -> nub $ collectVars t1 ++ collectVars t2 ForallT ns _ t -> collectVars t \\ ns _ -> []
src/Language/Haskell/Meta/Syntax/Vars.hs view
@@ -1,3 +1,4 @@+{-# LANGUAGE CPP #-} {-# LANGUAGE FlexibleContexts, FlexibleInstances, MultiParamTypeClasses #-} {- |@@ -45,24 +46,29 @@ vars (ConP n ps) = n `S.insert` vars ps vars (InfixP p n q) = n `S.insert` vars [p,q] vars (TildeP p) = vars p- vars (BangP p) = vars p vars (AsP n p) = n `S.insert` vars p vars (WildP) = S.empty vars (RecP n pfs) = (n `S.insert`) . vars . fmap snd $ pfs vars (ListP ps) = vars ps vars (SigP p _) = vars p+#if MIN_VERSION_template_haskell(2,4,0)+ vars (BangP p) = vars p+#endif /* MIN_VERSION_template_haskell(2,4,0) */+ bvs (LitP _) = S.empty bvs (VarP n) = S.singleton n bvs (TupP ps) = bvs ps bvs (ConP _ ps) = bvs ps bvs (InfixP p _ q) = bvs [p,q] bvs (TildeP p) = bvs p- bvs (BangP p) = bvs p bvs (AsP n p) = n `S.insert` bvs p bvs (WildP) = S.empty bvs (RecP _ pfs) = bvs . fmap snd $ pfs bvs (ListP ps) = bvs ps bvs (SigP p _) = bvs p+#if MIN_VERSION_template_haskell(2,4,0)+ bvs (BangP p) = bvs p+#endif /* MIN_VERSION_template_haskell(2,4,0) */ instance Vars Range Name where
src/Language/Haskell/Meta/Utils.hs view
@@ -1,3 +1,4 @@+{-# LANGUAGE CPP #-} {-# LANGUAGE TemplateHaskell, RankNTypes, StandaloneDeriving, DeriveDataTypeable, PatternGuards, FlexibleContexts, FlexibleInstances, TypeSynonymInstances #-}@@ -15,8 +16,8 @@ import Language.Haskell.TH.Quote import Language.Haskell.TH.Syntax import Language.Haskell.TH.Lib+import Language.Haskell.TH.Lift (deriveLift) import Language.Haskell.TH.Ppr-import Language.Haskell.TH.Lift import Text.PrettyPrint import Control.Monad @@ -117,19 +118,22 @@ mkVarT = varT . mkName -+-- | Infinite list of names composed of lowercase letters myNames :: [Name] myNames = let xs = fmap (:[]) ['a'..'z'] ys = iterate (join (zipWith (++))) xs in fmap mkName (concat ys) +-- | Generalisation of renameTs+renameThings _ env new acc [] = (reverse acc, env, new)+renameThings f env new acc (t:ts) =+ let (t', env', new') = f env new t+ in renameThings f env' new' (t':acc) ts+ -- | renameT applied to a list of types renameTs :: [(Name, Name)] -> [Name] -> [Type] -> [Type] -> ([Type], [(Name,Name)], [Name])-renameTs env new acc [] = (reverse acc, env, new)-renameTs env new acc (t:ts) =- let (t',env',new') = renameT env new t- in renameTs env' new' (t':acc) ts+renameTs = renameThings renameT -- | Rename type variables in the Type according to the given association -- list. Normalise constructor names (remove qualification, etc.)@@ -140,7 +144,7 @@ renameT env [] _ = error "renameT: ran out of names!" renameT env (x:new) (VarT n) | Just n' <- lookup n env = (VarT n',env,x:new)- | otherwise = (VarT x, (n,x):env, new) + | otherwise = (VarT x, (n,x):env, new) renameT env new (ConT n) = (ConT (normaliseName n), env, new) renameT env new t@(TupleT {}) = (t,env,new) renameT env new ArrowT = (ArrowT,env,new)@@ -149,21 +153,31 @@ (s',env'',new'') = renameT env' new' t' in (AppT s s', env'', new'') renameT env new (ForallT ns cxt t) =- let unVarT (VarT n) = PlainTV n -- dropping kinds here- (ns',env2,new2) = renameTs env new [] (fmap (VarT . toName) ns)- ns'' = fmap unVarT ns'- renameCs env new acc [] = (reverse acc, env, new)- renameCs env new acc (ClassP n ts:cs) =- let (ts', env', new') = renameTs env new [] ts- in renameCs env' new' (ClassP (normaliseName n) ts' : acc) cs- renameCs env new acc (EqualP t1 t2:cs) =- let (t1', env', new') = renameT env new t1- (t2', env'', new'') = renameT env' new' t2- in renameCs env'' new'' (EqualP t1' t2' : acc) cs- (cxt',env3,new3) = renameCs env2 new2 [] cxt- (t',env4,new4) = renameT env3 new3 t- in (ForallT ns'' cxt' t', env4, new4)+ let (ns',env2,new2) = renameTs env new [] (fmap (VarT . toName) ns)+ ns'' = fmap unVarT ns'+ (cxt',env3,new3) = renamePreds env2 new2 [] cxt+ (t',env4,new4) = renameT env3 new3 t+ in (ForallT ns'' cxt' t', env4, new4)+ where+#if MIN_VERSION_template_haskell(2,4,0)+ unVarT (VarT n) = PlainTV n+ renamePreds = renameThings renamePred + renamePred env new (ClassP n ts) = let+ (ts', env', new') = renameTs env new [] ts+ in (ClassP (normaliseName n) ts', env', new')++ renamePred env new (EqualP t1 t2) = let+ (t1', env1, new1) = renameT env new t1+ (t2', env2, new2) = renameT env1 new1 t2+ in (EqualP t1' t2', env2, new2)++#else /* !MIN_VERSION_template_haskell(2,4,0) */+ unVarT (VarT n) = n+ renamePreds = renameTs++#endif /* !MIN_VERSION_template_haskell(2,4,0) */+ -- | Remove qualification, etc. normaliseName :: Name -> Name normaliseName = mkName . nameBase@@ -189,7 +203,6 @@ - -- | Produces pretty code suitable -- for human consumption. deriveLiftPretty :: Name -> Q String@@ -201,7 +214,6 @@ - splitCon :: Con -> (Name,[Type]) splitCon c = (conName c, conTypes c) @@ -231,7 +243,11 @@ decCons _ = [] +#if MIN_VERSION_template_haskell(2,4,0) decTyVars :: Dec -> [TyVarBndr]+#else /* !MIN_VERSION_template_haskell(2,4,0) */+decTyVars :: Dec -> [Name]+#endif /* !MIN_VERSION_template_haskell(2,4,0) */ decTyVars (DataD _ _ ns _ _) = ns decTyVars (NewtypeD _ _ ns _ _) = ns decTyVars (TySynD _ ns _) = ns
src/Language/Haskell/TH/Instances/Lift.hs view
@@ -1,3 +1,4 @@+{-# LANGUAGE CPP #-} {-# LANGUAGE StandaloneDeriving, TemplateHaskell #-} {-# LANGUAGE TypeSynonymInstances #-} @@ -20,13 +21,7 @@ deriving instance Ord Dec deriving instance Ord Stmt deriving instance Ord Type-deriving instance Ord TyVarBndr-deriving instance Ord Pred-deriving instance Ord Kind-deriving instance Ord FamFlavour deriving instance Ord Foreign-deriving instance Ord InlineSpec-deriving instance Ord Pragma deriving instance Ord FunDep deriving instance Ord Con deriving instance Ord Body@@ -40,6 +35,15 @@ deriving instance Ord Pat deriving instance Ord Lit +#if MIN_VERSION_template_haskell(2,4,0)+deriving instance Ord TyVarBndr+deriving instance Ord Pred+deriving instance Ord Kind+deriving instance Ord FamFlavour+deriving instance Ord InlineSpec+deriving instance Ord Pragma+#endif /* MIN_VERSION_template_haskell(2,4,0) */+ deriving instance Show Loc deriving instance Eq Loc @@ -50,8 +54,33 @@ instance Ppr Lit where ppr l = ppr (LitE l) -deriveLiftMany [''Body, ''Callconv, ''Clause, ''Con, ''Dec,- ''Exp, ''FamFlavour, ''Fixity, ''FixityDirection, ''Foreign, ''FunDep,- ''Guard, ''Info, ''InlineSpec, ''Kind, ''Lit, ''Match, ''Pat, ''Pragma,- ''Pred, ''Range, ''Safety, ''Stmt, ''Strict, ''Type, ''TyVarBndr]+$(deriveLiftMany [ ''Body+ , ''Callconv+ , ''Clause+ , ''Con+ , ''Dec+ , ''Exp+ , ''Fixity+ , ''FixityDirection+ , ''Foreign+ , ''FunDep+ , ''Guard+ , ''Info+ , ''Lit+ , ''Match+ , ''Pat+ , ''Range+ , ''Safety+ , ''Stmt+ , ''Strict+ , ''Type+#if MIN_VERSION_template_haskell(2,4,0)+ , ''FamFlavour+ , ''InlineSpec+ , ''Kind+ , ''Pragma+ , ''Pred+ , ''TyVarBndr+#endif /* MIN_VERSION_template_haskell(2,4,0) */+ ])