Document workaround for TH name quoting restriction
Summary
The Template Haskell section of the GHC User's Guide states:
A name whose second character is a single quote (sadly) cannot be quoted in this way, because it will be parsed instead as a quoted character. For example, if the function is called
f'7
(which is a legal Haskell identifier), an attempt to quote it as'f'7
would be parsed as the character literal'f'
followed by the numeric literal7
. There is no current escape mechanism in this (unusual) situation.
Proposed improvements or changes
While there is no escape mechanism, per se, there is a workaround, and I think it should be described here. Define the following:
-- Unexported type
newtype Id a = Id {unId :: a}
deriving (Functor, Applicative, Monad) via Identity
instance Quote Id where
newName _ = withFrozenCallStack $ error extractNameError
extractName :: HasCallStack => Id Exp -> Name
extractName m = case unId m of
VarE x -> x
ConE x -> x
_ -> withFrozenCallStack $ error extractNameError
extractNameError :: String
extractNameError = "extractName: the argument must be an expression quote containing a single bare name, such as [| f'1 |]"
If you have a function called f'7
, you can effectively quote its name by writing
extractName [| f'7 |]
Perhaps there should be something like extractName
in Language.Haskell.TH.Lib
?
Environment
- GHC version used (if appropriate):