Domanda

Recently, I have learned how to implement quasiquoters with antiquote capabilities, like printfQ in the following piece of code:

main = do
  let itemName = "apple"
      price = 1.29 
  [printfQ| The price of #{itemName} is #{price}. |]

The ingredient string of the quasiquote will be passed to quoteExp printfQ :: String -> ExpQ. So what we do is to parse the given String, find names to be embedded "itemName" and "price", apply varE . mkName for each name, and build the ExpQ.

Now suppose I'd like to extend this printfQ to allow expression embedding as follows:

[printfQ| The price of #{itemNames !! i} is #{price + taxOf price}. |]

I can write the parser that detects two string"itemNames !! i" and "price + taxOf price". But then I need a stronger version of varE . mkName, a function of type String -> ExpQ that turns those strings into ExpQ, interpreting them as expressions referring to the namespace the printfQ is used.

My question: is there any library function that does this string to AST conversion? Are there some easy ways to do this, or do I need to write an entire Haskell parser?

È stato utile?

Soluzione

After taking a bath an excellent idea came to me:

Hey, if I need an entire Haskell parser, why not use an existing one?

After a couple of search in that line I found my answer: parseExp from http://hackage.haskell.org/package/haskell-src-meta-0.6.0.4/docs/Language-Haskell-Meta-Parse.html#v:parseExp .

I wrote a self-contained example for this:

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

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top