
Hi all, the community is increasingly using quasiquotation as a means to interoperate with foreign languages. E.g. language-c-inline, inline-c and inline-r allow calling foreign functions using foreign language syntax, rather than "foreign import" declarations. There are efforts underway for Java, Javascript and other languages too. The pattern common to most of these libraries is: * collect the content of all quasiquotes that appear in a module, generate a compilable foreign source file based on that, and then link the object code resulting from compiling that. When the foreign language is itself statically typed, we need to make sure we generate code with proper type annotations, including for any antiquotation variables. In older versions of GHC, we could derive the type annotations from the inferred Haskell types, but this is not possible since 7.8 because the types of any variable in the current "declaration group" are not made available. So libraries like inline-c ask for some extra verbosity from the user: mycossin1 :: Double -> IO Double mycossin1 somex = [cexp| double { cos($(double somex)) * sin($(double somex)) } |] The type annotations inside the quasiquote are redundant with the explicitly provided type signature. C types are typically short enough, but other languages (e.g. C++, Java), have really long fully qualified type names, so the extra annotations are a cost. The are good reasons why types aren't available from within a declaration group (it was possible to observe the order in which type inference works), hence why the extra annotations are necessary. But by the time type checking of the whole module is finished, types are fixed once and for all. So the question is: * Could we make it possible to query the types of local variables at the end of type checking? The reason I ask is: with 'addModFinalizer' and friends that TH provides, we're tantalizingly close to being able to generate foreign code wrappers that have the right types that match those of the antiquotation variables present in a module. Template Haskell already provides 'addModFinalizer'. You feed it a Q action, which will run once the whole module is type checked. If at that point we could ask, "what's the type of somex (above)?", then we could let the user write mycossin2 :: Double -> IO Double mycossin2 somex = [cexp| cos($somex) * sin($somex) |] and yet still generate a C file capturing the content of above quasiquote with the right types: double module_foo_qq1(double v1) { return (cos(v1) * sin(v1)); } since we know that somex :: Double and that the Haskell type "Double" corresponds to C's "double" primitive type. Bound variables have a unique name associated to them, which we can get hold of in Template Haskell using the 'var syntax, but f x = $(let name = 'x in addModFinalizer (reify name >>= \info -> runIO (print info)) >> [| x |]) results in a compiler error, The exact Name `x' is not in scope Probable cause: you used a unique Template Haskell name (NameU), perhaps via newName, but did not bind it If that's it, then -ddump-splices might be useful because by the time the TH finalizer runs, we're no longer in the scope of x. But since the names of the local variables are unique, could it possibly make sense to allow calling reify on them, even outside of their scope, so as to get at their type? Best, Mathieu