[Template-haskell] unexpected behaviour

Simon Peyton-Jones simonpj@microsoft.com
Tue, 15 Apr 2003 08:26:13 +0100


| -----Original Message-----
| out' :: Dec -> ()
| out' _ =3D ()
|=20
| outGen' :: Q [Dec]
| outGen' =3D do d<-reifyDecl Tree
| 	     dec1<-clause [pvar "x"] (normal [|out' d|]) []
| 	     return [Fun "out" [dec1]]
|=20
| 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. =20

| Whereas if I replace outGen' by:
|=20
| foo :: Q ()
| foo =3D do d<-reifyDecl Tree
| 	 return (out' d)
|=20
| outGen :: Q [Dec]
| outGen =3D do dec1<-clause [pvar "x"] (normal [|foo|]) []
| 	    return [Fun "out" [dec1]]

or you could, I think, say

| foo :: Q Dec -> Q ()
| foo qd =3D do d<-qd
| 	          return (out' d)
|=20
| outGen :: Q [Dec]
| outGen =3D do let d =3D 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:
|=20
| foo :: Q ()
| foo =3D do d<-reifyDecl Tree
| 	 return $( [| out' d |] )
|=20
| 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 |]  =3D  e

for any e. =20

| 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