
On Fri, Dec 30, 2011 at 05:50:18PM -0800, Michael D. Adams wrote:
On Fri, Dec 30, 2011 at 5:05 PM, Simon Peyton-Jones
wrote: | Currently quote forms have type "Q Exp" and nested splices expect | their contents to have type "Q Exp". I propose that quote forms have | type "forall m. Quasi m => m Exp" and nested splices expect a body of | type "m Exp" where the "m" of the nested splice is the same as the "m" | of the quote form that it is inside of.
Happily they already have that type. Have a look in Language.Haskell.TH.Syntax: newtype Q a = Q { unQ :: forall m. Quasi m => m a }
You want a function from "Q Exp" to "forall m. Quasi m => m Exp". It would have type
Q Exp -> forall m. Quasi m => m Exp
or, isomorphically
forall m. Quasi m => Q Exp -> m Exp
And indeed there is such a function: it's called runQ.
So I think what you want is already available.
If there are no splices in the quote then, yes, that is sufficient. However, as there is no function of type "forall m. Quasi m => m Exp -> Q Exp", the contents of all splices must be of type "Q Exp". Thus in the expression "[| ... $( foo ) ... |]" there is no way for foo to modify the state of the memoization table.
Given Simon's description of Q above, there is such a function: namely, the constructor Q. Unfortunately it seems that it is not exported. -Brent