我试图了解Quasi Quoter如何生成TH结构。所以我试图将第一个示例从Template Meta-programming for Haskell转换为引用格式,只转换为类型。
gen :: [Format] -> ExpQ -> ExpQ
gen [] x = x
gen (D:xs) x = [| \n -> $(gen xs [| $x ++ show n |]) |]
gen (S:xs) x = [| \s -> $(gen xs [| $x ++ s |]) |]
gen (L s:xs) x = gen xs [| $x ++ $(THS.lift s) |]
gen (D:xs) x
会转换为
gen (D:xs) x = lamE [varP $ mkName "n"]
(appE (appE (varE 'gen) (varE 'xs))
(uInfixE (x) (varE '(Prelude.++))
(appE (varE 'Prelude.show) (varE $ mkName "n"))))
但是,此片段不会编译对'xs
的引用。
GHC吐出以下错误:
src/Print/Default.hs:28:51:
Stage error: the non-top-level quoted name 'xs
must be used at the same stage at which is is bound
In the Template Haskell quotation 'xs
In the first argument of `varE', namely 'xs
In the second argument of `appE', namely `(varE 'xs)'
是否还有其他方法需要引用Template Haskell的函数参数名称才能使用它?
答案 0 :(得分:1)
user2407038是正确的,翻译已关闭。这是一个更正确的翻译:
gen (D:xs) x = lamE [varP (mkName "n")] $
gen xs $
varE '(++)
`appE` x
`appE` (varE 'show `appE` varE (mkName "n"))
这里没有引用xs
或gen
的名称:您只是递归调用该函数以生成更多的AST。这使一切都处于同一阶段。