Yes, multi-parameter type classes are supported.
Somewhat confusingly, the Type
argument refers to the entire instance head, and, even though it's not really a type, it looks enough like one syntactically that the type Type
was reused for this purpose.
Therefore, if you're generating a multi-parameter instance Foo Int Bool
, you need to use the "type" Foo Int Bool
, constructed for example like this:
(ConT (mkName "Foo") `AppT` ConT (mkName "Int")) `AppT` ConT (mkName "Bool")
Here's a complete example:
{-# LANGUAGE MultiParamTypeClasses, TemplateHaskell #-}
import Language.Haskell.TH
class Foo a b where
foo :: (a, b)
$(return [InstanceD [] (((ConT (mkName "Foo")) `AppT` ConT (mkName "Int")) `AppT` ConT (mkName "Bool"))
[ValD (VarP (mkName "foo"))
(NormalB (TupE [LitE (IntegerL 42), ConE (mkName "False")])) []]])
main = print (foo :: (Int, Bool))