[GHC] #11832: Allow reify to yield types in the current declaration group

GHC ghc-devs at haskell.org
Thu Jun 2 11:43:32 UTC 2016


#11832: Allow reify to yield types in the current declaration group
-------------------------------------+-------------------------------------
        Reporter:                    |                Owner:
  facundo.dominguez                  |  facundo.dominguez
            Type:  feature request   |               Status:  patch
        Priority:  normal            |            Milestone:
       Component:  Template Haskell  |              Version:  7.10.3
      Resolution:                    |             Keywords:  reify
Operating System:  Unknown/Multiple  |         Architecture:
                                     |  Unknown/Multiple
 Type of failure:  None/Unknown      |            Test Case:
      Blocked By:                    |             Blocking:
 Related Tickets:                    |  Differential Rev(s):  Phab:D2286
       Wiki Page:                    |
  TemplateHaskell/Reify              |
-------------------------------------+-------------------------------------

Comment (by simonpj):

 I'm confused by the patch.  I believe that the poster-child example is
 this:
 {{{
 f x = $(do { let name = 'x in
            ; addModFinalizer (reify name >>= \info ->
                               runIO (print info))
            ; [| x |]) }
 }}}
 Now, the issue is that
  * the splice is run by the renamer
  * but you want the finaliser to have access to the type environment
 giving the type of `x`, which we only have a typecheck time.

 Rather than mess around with IORefs, why not do this
 {{{
 data HsExpr  = ...
   | HsSpliced [Q ()] (HsExpr ..)
   ..
 }}}
 So the `Spliced` collects the finalisers emitted by the splice, but does
 not run them.

 Now when the typechecker finds a `HsSpliced`, it does
 {{{
 tcExpr (Spliced fs e)
   = do { env <- getLclEnv
        ; addModFinaliser (setLclEnv env (sequence fs))
        ; tcExpr e }
 }}}
 That is, it just grabs the env, and emits a new finaliser that sets that
 env.  Much nicer!



 ------
 Generally, could we not combine `addModFinaliser` with `addTopDecls` into
 one primitive, by offering
 {{{
 later :: Q [Decl] -> Q ()
 }}}
 It takes a computation and puts it aside for "later" (just like
 addModFinaliser).  But when it finally run, which happens at top level, it
 can produce some decls which are spliced in.

 So we have
 {{{
 addModFinaliser thing = later (thing >> return [])

 addTopDecls dec = later (return dec)
 }}}
 Nice!

--
Ticket URL: <http://ghc.haskell.org/trac/ghc/ticket/11832#comment:5>
GHC <http://www.haskell.org/ghc/>
The Glasgow Haskell Compiler


More information about the ghc-tickets mailing list