
I don't think that cross stage persistence will work as it is
currently implemented which is probably why the check exists.
1. The normal case
foo x = [| x |] ===>
foo x = [| $(lift x) |]
2. x is defined at stage 0, and used at stage 2.
One option is:
foo x = [| [| x |] |] ===>
foo x = [| [| $($(lift (lift x))) |] |]
or
foo x = [| [| x |] |] ===>
foo x = [| let x' = $(lift x) in [| $(lift [| x' |]) |]
We need to think a bit how to `lift` something of type `Q Exp` because
of the `Q` monad. Lifting an `Exp` seems trivial as it's a normal ADT
(I tested and this works after deriving 40 instances).
You can define `lift2` which lifts an expression twice as follows.
```
lift2 :: Lift a => a -> Q Exp
lift2 a = lift a >>= \e -> [| return $ $(lift e) |]
```
3. x is defined at stage 1 and used in stage 2
foo = [| \x -> [| x |] |] ===>
foo = [| \x -> [| $(lift x) |] |]
Desugared with a single call to `lift` like normal.
4. x is defined in stage 2 and used in stage 1
foo = [| [| \x -> $(x) |] |]
Rejected just like usual. `x` won't be bound when the splice is run.
It seems that with some suitable care that things will work out when
lifting across multiple levels but that is the point where care needs
to be taken.
Matt
On Thu, Jan 24, 2019 at 5:46 PM Richard Eisenberg
I think Geoff was primarily concerned with typed Template Haskell, not the untyped variety.
I, too, have wondered if there was a technical reason behind this restriction, or if merely it was assumed that nested brackets were not worthwhile.
One question: how would staging work between nesting levels of brackets?
Richard
On Jan 24, 2019, at 12:42 PM, Ben Gamari
wrote: Matthew Pickering
writes: There is a check in `RnSplice` which errors on the following program with nested brackets.
It might be good to explicitly include Geoff Mainland in this thread. I'm not sure he'll see it otherwise.
Cheers,
- Ben
_______________________________________________ ghc-devs mailing list ghc-devs@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-devs