[Template-haskell] Useful TH library functions
Alastair Reid
alastair at reid-consulting-uk.ltd.uk
Fri Sep 26 16:42:57 EDT 2003
Here's some functions I found myself needing when I wrote Template Greencard
which I think would be useful additions to the TH libraries. The names could
probably be a bit better and, in some cases, putting a function in the Q
monad (i.e., lift the args and result) might be helpful.
-- Functions for building types
--| mkIOTy alpha = [| IO alpha |]
mkIOTy :: Typ -> Typ
mkIOTy ty = ConTyp (ConNameTag "GHC.IOBase:IO") `AppTyp` ty
--| mkArrows [t1,...tm] rty = [| t1 -> ... -> tm -> rty |]
mkArrows :: [Typ] -> Typ -> Typ
mkArrows as r = foldr (\ a as -> tapply (ConTyp ArrowTag) [a,as]) r as
--| mkTupleTy [t1, ... tm] = [| (t1, ... tm) |]
mkTupleTy :: [Typ] -> Typ
mkTupleTy [] = htype_Void
mkTupleTy [ty] = ty
mkTupleTy tys = tapply (ConTyp (TupleTag (length tys))) tys
--| tapply tc [t1,...tm] = [| tc t1 ... tm |]
tapply :: Typ -> [Typ] -> Typ
tapply f [] = f
tapply f (a:as) = tapply (AppTyp f a) as
-- Functions for taking types apart
--| unarrow [| t1 -> ... tm -> rty |] = ([t1, ... tm], rty)
unarrow :: Typ -> ([Typ],Typ)
unarrow (AppTyp (AppTyp (ConTyp ArrowTag) ty1) ty2) = let (as,r) = unarrow ty2
in (ty1:as,r)
unarrow ty = ([],ty)
--| unIO [| IO ty |] = (True, ty)
unIO :: Typ -> (Bool,Typ)
unIO (AppTyp (ConTyp (ConNameTag "GHC.IOBase:IO")) ty) = (True, ty)
unIO ty = (False, ty)
--| untuple [| (ty1,...tm) |] = [ty1,..tm]
untuple :: Typ -> [Typ]
untuple ty = case split ty of
(ConTyp (TupleTag n), tys) -> tys
(ConTyp (ConNameTag "GHC.Base:()"),[]) -> []
_ -> [ty]
-- Functions for building expressions and patterns
--| simpleLet v e body = [| let v = e in body |]
simpleLet :: Var -> Q Exp -> Q Exp -> Q Exp
simpleLet v e body = letE [val (VarPat v) (normal e) []] body
--| mkPTuple [p1,...pm] = [| (p1,...pm() |]
mkPTuple :: [Pat] -> Pat
mkPTuple [p] = p
mkPTuple ps = TupPat ps
-- Reifications of common types
-- (The important thing here is that they are not in the Q monad
-- so I can refer to them in guards.)
htype_Ptr :: HType
htype_Ptr = ConTyp (ConNameTag "GHC.Ptr:Ptr")
htype_FunPtr :: HType
htype_FunPtr = ConTyp (ConNameTag "GHC.Ptr:FunPtr")
htype_StablePtr :: HType
htype_StablePtr = ConTyp (ConNameTag "GHC.Stable:StablePtr")
htype_Void :: HType
htype_Void = ConTyp (ConNameTag "GHC.Base:()")
More information about the template-haskell
mailing list