Search code examples
haskellmetaprogrammingtemplate-haskelltype-families

Generate InstanceD declaration that contains type families


I am writing a function deriveMyTypeClass ::Q [Dec] where, given the name of a type, I am walking over it's constructors and instancing a typeclass I wrote based on the structure.

My type class looks like:

class MyTypeclass a where
  type Foo a
  f :: a -> a -> Foo a 
  g :: Foo a -> a -> a 

In my function deriveMyTypeclass, what declaration should I pass to InstanceD to satisfy the type family declaration. Would it be TySynInstD?

Right now I have something along the lines of:

deriveMyTypeclass :: Name -> Q [Dec] 
deriveMyTypeclass tyName = do 
... blah blah blah reify tyName ...
return $ [
  InstanceD Nothing [] 
            (AppT (ConT ''MyTypeclass) (ConT tyName) 
            [ -- declarations go here
            , TySynInstD $ ????? 
            , FunD 'f ... 
            , FunD 'g ...
            ]
   ]

Any help is appreciated :)

P.S. I'm using version template-haskell-2.14.0.0 but if your solution requires 2.15, then I'll consider upgrading.


Solution

  • Thanks to Joseph's comment to my question, I found my answer. Just in case anyone stumbles upon this question, the typeclass instance with a type family instance would look like:

    InstanceD Nothing [] 
             (AppT (ConT ''MyTypeclass) (ConT tyName)) 
             [TySynInstD ''Foo 
                         (TySynEqn [ConT tyName] {{THE RIGHT HANDSIDE TYPE HERE}})
             , FunD ....
             , .....
             ] 
    

    I was originally confused as to how the Type family name (Foo) and the type I was instancing it for (tyName) would be composed. Here it is composed as the type family name as just a name (''Foo), a list of types to instantiate Foo's type variable (ConT tyName) and then a type for the right hand side.