模板Haskell:阶段错误

时间:2014-06-02 19:58:07

标签: haskell template-haskell

我试图了解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的函数参数名称才能使用它?

1 个答案:

答案 0 :(得分:1)

user2407038是正确的,翻译已关闭。这是一个更正确的翻译:

    gen (D:xs)   x = lamE [varP (mkName "n")] $
                        gen xs $
                              varE '(++)
                                    `appE` x
                                    `appE` (varE 'show `appE` varE (mkName "n"))

这里没有引用xsgen的名称:您只是递归调用该函数以生成更多的AST。这使一切都处于同一阶段。