最近学习了如何实现具有antiquote能力的quasiquoters,比如下面一段代码中的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 解析器?
最佳答案
洗完澡后,我想到了一个绝妙的主意:
Hey, if I need an entire Haskell parser, why not use an existing one?
在该行中进行了几次搜索后,我找到了答案:
parseExp
fromhttp://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
关于haskell - 如何不仅允许在反引号中嵌入值而且允许嵌入任意的 Haskell 表达式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19466399/