[Haskell-cafe] parametrized data types and Template Haskell
Maarten Faddegon
haskell-cafe at maartenfaddegon.nl
Mon Dec 30 17:08:08 UTC 2013
Dear Cafe,
Thanks to the kind help of Adam and Richard I now can generate instances
for parametrized data types with Template Haskell.
However, I still struggle adding class constraints to the type
variables. I try to follow the derive_show example of Ian Lynagh but it
seems some interfaces have changed since he wrote "Template Haskell: A
Report From The Field".
I generate MyClass constraints for a set of type variables with the
following code:
> genCxt :: [TyVarBndr] -> Q Cxt
> genCxt tvs = return [classp $ map (\v -> (tvname v)) tvs]
>
> classp :: [Type] -> Pred
> classp = ClassP (mkName "TH_playground.MyClass")
>
> tvname :: TyVarBndr -> Type
> tvname (PlainTV name ) = ConT name
> tvname (KindedTV name _) = ConT name
To be able to generate MyClass instances with:
> genInstance :: Q Type -> Q [Dec]
> genInstance qt
> = do { t <- qt
> ; n <- case t of
> (ForallT tvs _ t') -> [t| MyClass $(return t') |]
> _ -> [t| MyClass $qt |]
> ; m <- genMethod qt
> ; c <- case t of
> (ForallT tvs _ t') -> genCxt tvs
> _ -> return []
> ; return [InstanceD c n m]
> }
Up to here, everything type checks and I can build the module where I
defined it.
In a different module I try to generate an instance for MyData a:
> data MyData a = MyCon a
> $(genInstance [t| forall a.MyData a |])
This however does not seems to go down well with the compiler.
|| Illegal type constructor or class name: `a'
|| When splicing a TH declaration:
|| instance TH_playground.MyClass a_0 => TH_playground.MyClass
(Main.MyData a_0)
|| where myMethod (Main.MyCon x_1) = "todo"
This error message confuses me because it seems to complain about the
type variable a in the generate instance, but in the generated instance
this variable is renamed to a_0. Also, when I copy the generated code
from the error message the ghc is completely happy.
Without the class constraints the generated instance type checks and
compiles as well:
> genCxt _ = return []
But I would like to apply myMethod on the fields in parametrized data
types, which is not correct without the class constraints.
Did I find a bug in ghc's Template Haskell implementation or am I doing
something silly?
Thanks,
Maarten
More information about the Haskell-Cafe
mailing list