Reputation: 451
I need to generate code for the function signature with type class constraints, for example:
fun :: (Ord a) => a -> a
I'm using the following signature constructor:
SigD Name Type
So, I need to generate a type. My best guess is to use the following constructor:
ForallT [TyVarBndr] Cxt Type
It corresponds to the following declaration (as seen at Temaplate Haskell documentation):
forall <vars>. <ctxt> => <type>
But Cxt
is just a synonym for the list of Type
's, and I can't find an appropriate constructor of Type
for generating a type class constraint. What should I do to generate code for a type class constraint?
Upvotes: 3
Views: 480
Reputation: 1590
I believe that, as was mentioned in the comments, TH does not draw a distinction between Type
s and Constraint
s (which kind of makes sense, especially now that ConstraintKinds
is around). I've generally found inspecting the quasiquoted AST for a specific, concrete, example of whatever I'm trying to implement to be useful when working on generating code with TH that the quasiquoters aren't good enough for. For example, in GHCI:
λ> :set -XTemplateHaskell
λ> import Language.Haskell.TH
λ> runQ $ [d|f :: Ord a => a -> a; f = id|]
[SigD f_1 (ForallT [] [AppT (ConT GHC.Classes.Ord) (VarT a_0)] (AppT (AppT ArrowT (VarT a_0)) (VarT a_0))),ValD (VarP f_1) (NormalB (VarE GHC.Base.id)) []]
This shows that the constraint portion is just the Name
for Ord
applied to the name that you use for the type variable. Note that, at least at this level, the ForallT
parameter list is empty, since the a
in the type signature wasn't written as an explicit forall a.
.
Upvotes: 1