最近,我学会了如何在下面的代码中实现具有反引号功能的quasiquoter,例如printfQ
:
main = do
let itemName = "apple"
price = 1.29
[printfQ| The price of #{itemName} is #{price}. |]
quasiquote的成分字符串将传递给quoteExp printfQ :: String -> ExpQ
。我们所做的就是解析给定的String
,找到要嵌入的名称"itemName"
和"price"
,为每个名称应用varE . mkName
,然后构建ExpQ
。
现在假设我想扩展此printfQ
以允许表达式嵌入,如下所示:
[printfQ| The price of #{itemNames !! i} is #{price + taxOf price}. |]
我可以编写检测两个字符串"itemNames !! i"
和"price + taxOf price"
的解析器。但后来我需要一个更强版本的varE . mkName
,类型为String -> ExpQ
的函数,将这些字符串转换为ExpQ
,将它们解释为引用printfQ
命名空间的表达式
我的问题:是否有任何库函数可以将此字符串转换为AST转换?有没有一些简单的方法可以做到这一点,还是我需要编写一个完整的Haskell解析器?
答案 0 :(得分:4)
洗完澡后,我有一个好主意:
嘿,如果我需要一个完整的Haskell解析器,为什么不使用现有的?
经过几行搜索,我找到了答案:parseExp
来自
http://hackage.haskell.org/package/haskell-src-meta-0.6.0.4/docs/Language-Haskell-Meta-Parse.html#v:parseExp。
我为此写了一个自包含的例子:
https://github.com/nushio3/practice/tree/master/template-haskell/embed-expr