如何允许在反引号中不仅嵌入值,还嵌入任意 haskell 表达式

nus*_*hio 4 haskell quotations template-haskell

最近,我学习了如何实现具有反引号功能的准引号,如printfQ下面的代码所示:

main = do
  let itemName = "apple"
      price = 1.29 
  [printfQ| The price of #{itemName} is #{price}. |]
Run Code Online (Sandbox Code Playgroud)

准引号的成分字符串将被传递到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 -> ExpQExpQprintfQ

我的问题:是否有任何库函数可以将此字符串转换为 AST?有一些简单的方法可以做到这一点,还是我需要编写整个 Haskell 解析器?

nus*_*hio 5

洗完澡后,我想到了一个绝妙的主意:

嘿,如果我需要一个完整的 Haskell 解析器,为什么不使用现有的解析器呢?

经过几次搜索后,我找到了答案:parseExp来自 http://hackage.haskell.org/package/haskell-src-meta-0.6.0.4/docs/Language-Haskell-Meta-Parse.html#v:解析表达式

我为此编写了一个独立的示例:

https://github.com/nushio3/practice/tree/master/template-haskell/embed-expr