
My experience with Template Haskell is that any non-trivial code generation (that is, anything more complicated than a simple substitution into a simple template) requires heavy use of the TH constructors, as Adam suggests. I tend to prefer using the non-monadic ones (like `InstanceD :: Cxt -> Type -> [Dec] -> Dec`) over the monadic ones (exported from Language.Haskell.TH.Lib and like `instanceD :: Q Cxt -> Q Type -> [Q Dec] -> Q Dec`), though you may find the opposite is true in your domain. Using these constructors, it is straightforward to specify a context, and you can use an empty list (the type `Cxt` is a synonym for `[Pred]`) for an empty context.
As for naming a parameterized type, just use the base name. So, `Tree a` would be (AppT (ConT (mkName "Tree") (VarT (mkName "a"))) assuming `a` is in scope somehow. You may also be interested in the naming quote syntax: in an expression, code like
'blah
expands out to a name for the term-level thing (i.e., function or variable) named `blah` that is in scope. Code like
''Tree
expands out to a name for the **type**-level thing (i.e., type, type function, class, etc.) name `Tree` that is in scope. Note that the line of code above has two single-quotes and no double-quotes. The number of quotes is necessary to disambiguate data constructors from types.
I hope this helps!
Richard
On Dec 26, 2013, at 6:36 AM, Maarten Faddegon
Dear Cafe,
Hope you all had a nice Christmas.
I have been playing with generating method instances using Template Haskell but am a bit stuck now trying to generate an instance for a parametrized data type.
I would like to generate the following:
instance (MyClass a) => MyClass (Tree a) where mymethod _ = "todo"
I defined a genMyClassInstance that is working fine for unparametrized data types, but clearly there is nothing here that inserts the '(MyClass a) =>' part here. My first question is: how should I instruct Template Haskell to insert the beforementioned code when appropriate?
genMyClassInstance :: Name -> Q [Dec] genMyClassInstance name = [d|instance MyClass $(conT name) where mymethod _ = "todo" |]
My second question is how to pass the Name of a parametrized data type? I tried the following, but GHC does not seem to like that: "Not in scope: type constructor or class `Tree a' Perhaps you meant `Tree'"
$(genMyInstance (mkName "Tree a"))
Thank you!
Maarten Faddegon _______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe