"Reactive" Template Haskell
When metaprogramming, I often encounter the situation where I want GHC to do something for every definition in scope. For example, I recently posted a simple library called ifcxt that relies on defining instance IfCxt cxt
for every instance cxt
that gets defined (where cxt
is an arbitrary class instance).
Currently, the library has a TH function that generates these IfCxt cxt
instances, but it can only work for instances that already exist at the time the TH function is called. Any instances created afterward get silently ignored.
To solve this problem, I would like to be able to register TH functions with the compiler that get executed everytime the compiler adds a definition. This might take the form of a function like:
registerTH :: (Dec -> Q [Dec]) -> Q ()
When regesterTH
is called, it would add the argument function to an internal list. Then, whenever the compiler defines a new declaration, it calls each function in the list on that declaration to see what new declarations should be added to the code.
AFAICT, there are two main drawbacks to this proposal. One, end users do not have to specifically invoke a TH function to get TH code to run. This would allow library authors to take over people's programs in possibly unexpected ways. So this might justify an additional extension beyond just -XTemplateHaskell
to signal the potentially dangerous nature of the code, or implementing this feature by extending the compiler plugin interface. Second, it would be very easy to accidentally send the compiler into infinite loops if two registered functions don't take care to behave properly with each other.
Trac metadata
Trac field | Value |
---|---|
Version | 7.10.2 |
Type | FeatureRequest |
TypeOfFailure | OtherFailure |
Priority | normal |
Resolution | Unresolved |
Component | Compiler |
Test case | |
Differential revisions | |
BlockedBy | |
Related | #9699 |
Blocking | |
CC | |
Operating system | |
Architecture |