在Haskell quasiquoter中拼接任意表达式

时间:2013-01-26 21:46:29

标签: haskell template-haskell

通过Why It’s Nice to be Quoted阅读,在第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' |]

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

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

例如:

subst [:lam | $exp:e1 $exp:e2 |] x y =
      [:lam | $exp:(subst e1 x y) $exp:(subst e2 x y) |]

1 个答案:

答案 0 :(得分:2)

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

原来这很简单。使用haskell-src-meta包中的parseExp函数,我能够轻松地将字符串转换为AST片段。

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

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