The following doesn't compile:
import Language.Haskell.TH
makeAlpha n = [d| data Alpha = Alpha $(conT n) deriving (Show, Read) |]
I can't make out what the error means at all:
Can't derive instances where the instance context mentions
type variables that are not data type parameters
Offending constraint: Show t_d
When deriving the instance for (Show Alpha)
In the Template Haskell quotation
[d| data Alpha = Alpha $(conT n) deriving (Show, Read) |]
In the expression:
[d| data Alpha = Alpha $(conT n) deriving (Show, Read) |]
Is it possible to do derivations like this?
This problem arises because TH quotes are type checked when they are compiled, with splices replaced by variables. This is usually a good idea, because it allows many kinds of problems to be detected before the splice is run, but in some cases this can make the compiler wrongfully reject a splice that would generate valid code.
In this case, this means that the compiler tries to check this code:
This doesn't work because the derived
Show
andRead
instances need to useShow
andRead
fort
, but sincet
is not a type parameter ofAlpha
, it cannot add the necessary constraints. Of course, when this splice is run,t
is replaced by a concrete type, so the appropriate instances will be available without the need for any constraints, so this is one of the cases where the compiler is being over-cautious.The workaround is to not use quoting, but instead use TH combinators, which are not subject to these extra checks. It's messy, but it works:
There has been some talk about relaxing the checks done on quotes, but for now you'll just have to deal with it.