It would be useful to be able to add module exports with TH, although I'm not sure exactly how it would be done. Perhaps something like
$( do n <- newName "foo" let d = funD n ... addExport (varE n) return [d]
but at the point we call addExport the typechecker doesn't know that there will be a declaration for the name.
Less useful, as TH names include the package and module of the name's definition, is the ability to add module imports. However, this can still be used to get a kind of dynamic binding effect, either with mkName's names or plain Haskell code, e.g.:
I would love for template haskell to be able to add imports. I am using haskelldb to write strongly-typed SQL queries. These queries depend on a compile time representation of the database schema. That representation is obtained by running a program which produces Haskell source describing a given set of tables, etc. If TH could write import statements, I could dynamically generated my modules and then import them in one go. My queries would always be compiled against the most recent schema! It would be a great feature to have.
Whoa! Can you give more detail on your example? At the moment you definitely can't write a TH function that generates a Haskell module, compiles it, and imports it. You can generate those definitions in the current module though.
Remember too that a TH definition can mention things in scope, and those things do not need to be imported where the TH function is called. Example
module T(f) where import List f = [| null |]module Foo where import T h = $f
Here $f expands to null, but you do not need to import List in module Foo. In fact $f expands to Data.List.null, a kind of absolute reference to null.
As the intro to this ticket says, TH-generated imports are really only useful for a form of dynamic binding.
I don't need TH to dynamically create a module, compile it and import it in one go (though my message does imply that). Just being able to add import statements would be enough. Continuing with haskelldb, "table" definitions can be stored in separate modules. For example, If I have two tables, customers and orders, then they would normally be in the modules Acme.Customers and Acme.Orders. If I have a third module which defines all my queries, Acme.Queries, then I import the two tables as:
module Acme.Queries where import qualified Acme.Customers as Customers import qualified Acme.Orders as Orders
Notice the qualified imports - those are necessary to avoid name clashes between the two modules (e.g., imagine if both tables have an ID column).
As I add more tables, I need to add more import statements. Maybe I have a registration table:
import qualified Acme.Registration as Registration
And so on, adding more and more clutter. Right now I have a file that imports about 15 "tables" and it's painful. I'd much rather have TH generate the import definition for me. For example:
module Acme.Queries where $(importTables "Acme", ["Registration", "Customers", "Orders"])
This becomes more important when you consider that I am trying to create a tool for other developers in my organization to use. They don't know Haskell, and I'd rather they didn't know they are learning Haskell until it's too late. Having to add these import statements would be a barrier for them.
I have a use case very similar to Simon Hengel's in my hails library. I am currently generating these imports using a custom Setup.hs and an ad hoc auxiliary tool.
Warning: allowing splicing of imports would make it much harder to track dependencies between modules, so things like ghc --make would become harder. I've only just realised this.
I still want it. singletons generates gobs of boilerplate, some of which it is important to export. It's not terribly hard for users to write the export lists manually, but it's just more boilerplate that would be nice to automate.
However, for my use case, I care only about TH writing to export lists, not import lists. TH-controlled export lists wouldn't hit the problem SPJ points out in ticket:1475#comment:84043.
I have also a use case for it. I need to generate imports that are extracted from GIT history. Using TH to do that would be elegant as I could extract the file and splice in the module name in the import list at the same time.
Also, I think it's worthwhile to point out that quoting imports is fine. It's only splicing them that can be tricky. I'd like to be able to pretty-print quotes I never splice, including imports, in e.g. happy for example.
I just realized I am missing this feature too. I am finishing a first version of TH based library generating polymorphic visitor function traversing an AST tree of mutually recursive data types. There are a few places I need import Data.Foldable (foldlM).
Today I generate Haskell functions for Sql Server API - some API units have some many variants (such as FIRST_VALUE, LAST_VALUE, LEAD, NTILE) so amount of generated code for a single API unit hits GHC limit for source file size.
Yes I think we want the per-stage imports that have been discussed a few times first. Then we have a new form of stratification that makes this less weird: stage n+1 imports are dynamic only with respect to values imported in stage n.