O.Phillips
O.Phillips

Reputation: 451

Template Haskell: generating code for a function signature with the type class constraints

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

Answers (1)

Lucy Maya Menon
Lucy Maya Menon

Reputation: 1590

I believe that, as was mentioned in the comments, TH does not draw a distinction between Types and Constraints (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

Related Questions