| -----Original Message----- | out' :: Dec -> () | out' _ = () | | outGen' :: Q [Dec] | outGen' = do d<-reifyDecl Tree | dec1<-clause [pvar "x"] (normal [|out' d|]) [] | return [Fun "out" [dec1]] | | I get an unexpected: | No instance for (Lift Dec) arising from use of `d'... The lifting thing is described (somewhat) in the paper. The idea is that [| out' d |] builds some code (i.e. a data structure) for later execution. That code needs 'd', but d may not be in scope where the code is executed. So the code must include code to build d. That's what lifting does. Yes, Dec could be made liftable, but it's unlikely to be what you want. | Whereas if I replace outGen' by: | | foo :: Q () | foo = do d<-reifyDecl Tree | return (out' d) | | outGen :: Q [Dec] | outGen = do dec1<-clause [pvar "x"] (normal [|foo|]) [] | return [Fun "out" [dec1]] or you could, I think, say | foo :: Q Dec -> Q () | foo qd = do d<-qd | return (out' d) | | outGen :: Q [Dec] | outGen = do let d = reifyDecl Tree | dec1<-clause [pvar "x"] (normal [|foo d|]) [] | return [Fun "out" [dec1]] | Now another thing: after writing some code randomly, I happened to | write foo like this: | | foo :: Q () | foo = do d<-reifyDecl Tree | return $( [| out' d |] ) | | Because I meant that the "out' d" should really be executed _before_. | Now, I understand this was not really sensible (or was it ?). No I don't think so. It should be the case that $[| e |] = e for any e. | However, ghc gives an ugly "panic!" message upon this, which is not | nice, and I suppose had to be reported. Yes, that's a bug, thank you. Simon