在Haskell quasiquoter中拼接任意表达式

Fré*_*Bel 6 haskell template-haskell

阅读为什么引用很好,在第3节中有一个在quasiquote中拼接变量标识符的例子.

subst [:lam | $exp:e1 $exp:e2 |] x y =
    let e1' = subst e1 x y
        e2' = subst e2 x y
    in
        [:lam | $exp:e1' $exp:e2' |]
Run Code Online (Sandbox Code Playgroud)

我知道为什么递归调用subst是在外部完成的[:lam| ... |],这是因为antiVarE3.2节中的函数构建了一个TH.varE变量名.

我的问题是,除了变量名之外,还需要多少工作才能支持任意表达式拼接?

例如:

subst [:lam | $exp:e1 $exp:e2 |] x y =
      [:lam | $exp:(subst e1 x y) $exp:(subst e2 x y) |]
Run Code Online (Sandbox Code Playgroud)

Fré*_*Bel 2

为后代回答我自己的问题。

事实证明这很简单。使用haskell-src-metaparseExp包中的函数,我能够轻松地将字符串转换为 AST 片段。

在原始论文中,除了捕获括号之间的表达式字符串所需的解析器更改之外,还antiExpE可以这样重写该函数。

antiExpE :: Exp -> Maybe TH.ExpQ
antiExpE (AE v) =
    case parseExp v of
        Right exp -> Just . return $ exp
        Left _    -> Nothing
antiExpE = Nothing
Run Code Online (Sandbox Code Playgroud)