This is partially a followup to Lift instance for a function?. However, the answer there is to either globally define the function or to rewrite it inside the quotation. However, we will be using foo
a lot with different functions for f
from within the scope of a let
. This makes it just about impossible for us to define multiple global version of f. The latter solution, of writing our function within the quote, seem equivalent to writing a lift on functions.
So, is there any way of lifting functions taken as arguments to use in a template Haskell quotation?
A very contrived example:
foo.hs
{-# Language TemplateHaskell #-}
import Language.Haskell.TH
foo :: (Int->Int) -> Int -> ExpQ
foo f x = [|f x|]
g :: ExpQ
g =
let
f = (\x -> x+1)
f' = (\x' -> f(x') + 1)
in foo f' 0
Will fail with:
foo.hs:5:11:
No instance for (Language.Haskell.TH.Syntax.Lift (Int -> Int))
arising from a use of ‘Language.Haskell.TH.Syntax.lift’
In the expression: Language.Haskell.TH.Syntax.lift f
In the expression:
[| f x |]
pending(rn) [x, f]
In an equation for ‘foo’:
foo f x
= [| f x |]
pending(rn) [x, f]