<div dir="ltr"><div>I generally have 2 questions. I am writing some functions to derive typeclass instances with a package called derive. I just want to get rid of using Derivation type with a stupid reason. I want use just Name type.</div><div><br></div><div>How can I defined a function with type </div><div><br></div><div>derivings :: Name -> Name -> Q [Dec]</div><div><br></div><div>by using function derive :: Derivation -> Name -> Q [Dec]</div><div>so that user can just write derivings ''Eq ''D instead of derive makeEq ''D?</div><div><br></div><div>> {-# LANGUAGE TemplateHaskell #-}</div><div><br></div><div>> import Data.DeriveTH -- in derive package</div><div>> import <a href="http://Language.Haskell.TH">Language.Haskell.TH</a></div><div>> import qualified Language.Haskell.TH.Syntax as S</div><div>> data D = D</div><div>> derivings :: Name -> String -> Q Exp</div><div>> derivings cla typ = do</div><div>>               let makeClassName = mkName $ "make" ++ nameBase cla</div><div>>               a <-  [| derive makeClassName (mkName typ) |]</div><div>>               return a</div><div><br></div><div>> instance S.Lift Name where</div><div>>         lift x = varE x</div><div><br></div><div>Main> :t derivings ''Eq "D"</div><div>derivings ''Eq "D" :: Q Exp</div><div><br></div><div>Main> :t $(derivings ''Eq "D")</div><div>$(derivings ''Eq "D") :: Q [Dec]</div><div><br></div><div>There is no problem to quote twice in other file in order to get the declaration. Maybe it should called second order meta programming. But the following has problems:</div><div><br></div><div>> derivings'' :: Name -> Name -> Q Exp</div><div>> derivings'' cla typ = do</div><div>>               let makeClassName = mkName $ "make" ++ nameBase cla</div><div>>               a <-  [| derive makeClassName typ |]</div><div>>               return a</div><div><br></div><div>Main> :t derivings''</div><div>derivings'' :: Name -> Name -> Q Exp</div><div><br></div><div>Main> :t derivings'' ''Eq ''D</div><div>derivings'' ''Eq ''D :: Q Exp</div><div><br></div><div>Main> :t $(derivings'' ''Eq ''D)</div><div><interactive>:1:3:</div><div>    Illegal variable name: ‘D’</div><div>    When splicing a TH expression:</div><div>      Data.DeriveTH.derive makeEq (Language.Haskell.TH.Syntax.mkName Main.D)</div><div>    In the splice: $(derivings'' ''Eq ''D)</div><div><br></div><div>In the first case I used String, it works. however, it is not workiing if I use D with a Name type. Cannot figure it out.</div><div>My second question is that if my return type is Q [Exp] while the [Exp] can be further expanded into [Dec]. How can I do it to expand [Exp] into [Dec]? Do we have a function for $ in $(thcode_with_Q_Exp) so that I do not need to splice each Exp value?</div><div><br></div><div>Best wishes</div><div>Song</div>
</div>