Idempotent Template Haskell
Yesterday I was looking for a way to have some Template Haskell code generate a definition for a certain identifier if and only if such a definition did not already exist. Essentially I want to be able to call the code multiple times but have it generate something only once. This turns out to be extremely easy but non-obvious, so I thought I’d write it here for posterity. The trick is that reify
throws an error if called on an identifier that doesn’t exist, and recover
can be used to catch TH errors. Thus:
recover (generateBinding n) (reify n >> return [])
which uses generateBinding n
to “recover” from the error of n
’s non-existence.