I'm trying to write a Lift instance that lifts not only the constructor, but also its type variables.
For example, take Proxy a. I need a Lift instance such that, when lift (Proxy @Int) is spliced, GHC will correctly infer than the generated expression is a Proxy Int.
-- GHC should infer that x :: Proxy Int
x = $(TH.lift (Proxy @Int))
I tried this:
instance Lift (Proxy a) where
lift _ = [|Proxy @a|]
x = $(TH.lift (Proxy @Int))
It seems TH captured a and not Int as expected.
I'm not sure what else to try
/.../TH/Test.hs:15:7: error:
• The exact Name ‘a’ is not in scope
Probable cause: you used a unique Template Haskell name (NameU),
perhaps via newName, but did not bind it
If that's it, then -ddump-splices might be useful
template-haskell doesn't seem to provide anything like that. But there might be a solution that you can implement from scratch. The idea is to define a class to carry a quote representing each type:
class TLift a where
tlift :: Q Type
For instance:
instance TLift Int where
tlift = [t|Int|]
-- and so on
Then to define a quote featuring a type application:
proxyQ :: forall a. TLift a => Q Exp
proxyQ = [|Proxy @( $(tlift @a) )|]
One limitation here is that TLift instances can only produce quotes for completely concrete types, no type variables. Maybe reflection can work around that.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With