在Haskell quasiquoter中拼接任意表达式 [英] Splicing arbitrary expressions in a Haskell quasiquoter
问题描述
阅读为什么很高兴被引用,在第3节中有一个例子在quasiquote中拼接变量标识符。
subst [:lam | $ exp:e1 $ exp:e2 |] x y =
让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 xy)$ exp:(subst e2 xy)|]
原来这很简单。使用 haskell-src中的 parseExp
函数-meta 包我能够轻松地将字符串转换为AST片段。
在原始文件中,除了捕获表达式字符串所需的解析器更改外在括号之间, antiExpE
函数可以被重写。
antiExpE :: Exp - >也许TH.ExpQ
antiExpE(AE v)=
case parseExp v
Right exp - >只是。返回$ exp
Left _ - > Nothing
antiExpE = Nothing
Reading through Why It’s Nice to be Quoted, in section 3 there's an example of splicing a variable identifier in a 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' |]
I see why the recursive calls to subst
are done outside the [:lam| ... |]
, it's because the function antiVarE
in section 3.2 builds a TH.varE
out of the variable name.
My question is how much work would be required to support arbitrary expression splices beyond just a variable name?
For example:
subst [:lam | $exp:e1 $exp:e2 |] x y =
[:lam | $exp:(subst e1 x y) $exp:(subst e2 x y) |]
Answering my own question for posterity.
Turns out it was quite simple. Using the parseExp
function in haskell-src-meta package I was able to easily convert a string to AST fragment.
In the original paper, aside from the parser changes required to capture an expression string between parentheses, the antiExpE
function could be rewritten as such.
antiExpE :: Exp -> Maybe TH.ExpQ
antiExpE (AE v) =
case parseExp v of
Right exp -> Just . return $ exp
Left _ -> Nothing
antiExpE = Nothing
这篇关于在Haskell quasiquoter中拼接任意表达式的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!