Template Haskell messes up scoping?

Hi, when I tried to reorganize some code to use the data-accessor and data-accessor-template packages, i stumbled across a strange effect: When using template haskell some things are out of scope that really shouldn't be. Let me give an example: ============== T.hs ============== {-# LANGUAGE TemplateHaskell #-} data Foo = Foo { bar :: Bar } $( return [] ) data Bar = Bar ==================================
ghci T.hs GHCi, version 6.10.1: http://www.haskell.org/ghc/ :? for help Loading package ghc-prim ... linking ... done. Loading package integer ... linking ... done. Loading package base ... linking ... done. [1 of 1] Compiling Main ( T.hs, interpreted )
T.hs:4:13: Not in scope: type constructor or class `Bar' Failed, modules loaded: none. No matter what you do in $( ... ), the code doesn't compile. Even in the simple case above, it doesn't work. What's happening here? Bug or feature? And do you know a workaround? //Stephan -- Früher hieß es ja: Ich denke, also bin ich. Heute weiß man: Es geht auch so. - Dieter Nuhr

Hi Stephan, Stephan Friedrichs wrote:
Hi,
when I tried to reorganize some code to use the data-accessor and data-accessor-template packages, i stumbled across a strange effect: When using template haskell some things are out of scope that really shouldn't be.
Apart from the specific problematic file you gave, I had some other scoping issues when using TH to generate the accessors. I worked around this by defining my data types in a separate module Types and calling the TH functions in that module as the last lines. Then I had my other modules import Types, bringing the types and the accessors back in scope. See: http://code.google.com/p/custard/source/browse/trunk/MudTypes.hs Hope this helps, Martijn.

Hi Martijn, Martijn van Steenbergen wrote:
[...]
Apart from the specific problematic file you gave, I had some other scoping issues when using TH to generate the accessors. I worked around this by defining my data types in a separate module Types and calling the TH functions in that module as the last lines. [...]
looks like your workaround also works in this case. This file (the template instanciation was moved to the last line) compiles: ============== T.hs ============== {-# LANGUAGE TemplateHaskell #-} data Foo = Foo { bar :: Bar } data Bar = Bar $( return [] ) ================================== It looks like the scope is interrupted just above $( ... ) - but I'd like to know why and find a more beautiful way than just moving all th calls to the bottom of the module file :) Regards Stephan -- Früher hieß es ja: Ich denke, also bin ich. Heute weiß man: Es geht auch so. - Dieter Nuhr

It looks like the scope is interrupted just above $( ... ) - but I'd like to know why and find a more beautiful way than just moving all th calls to the bottom of the module file :)
Top-level splices can introduce bindings. IIRC, the current TH implementation uses a simple sequencing approach, preventing splices to be part of a recursive dependency chain. If you have A; $(S); B then first A is compiled, then S, then B. So, B can refer to what S builds, but neither A nor S can refer to B. Btw, there is a TH mailing list, and a wiki page with links to tutorials and papers, needed given the sparsity of the Haddocks: http://www.haskell.org/haskellwiki/Template_Haskell Claus
participants (3)
-
Claus Reinke
-
Martijn van Steenbergen
-
Stephan Friedrichs