[Haskell-cafe] parametrized data types and Template Haskell

Richard Eisenberg eir at cis.upenn.edu
Thu Dec 26 20:39:38 UTC 2013

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
expands out to a name for the term-level thing (i.e., function or variable) named `blah` that is in scope. Code like
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!

On Dec 26, 2013, at 6:36 AM, Maarten Faddegon <haskell-cafe at maartenfaddegon.nl> wrote:

> 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 at haskell.org
> http://www.haskell.org/mailman/listinfo/haskell-cafe

More information about the Haskell-Cafe mailing list