Splicing arbitrary expressions in a Haskell quasiquoter

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) |]

Upvotes: 6

Views: 300

Answers (1)

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

Upvotes: 2

Related Questions