以下内容无法编译:
import Language.Haskell.TH
makeAlpha n = [d| data Alpha = Alpha $(conT n) deriving (Show, Read) |]
我无法弄清楚错误的含义:
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) |]
可以做这样的派生吗?
答案 0 :(得分:7)
出现此问题是因为TH引号在编译时会进行类型检查,并且拼接由变量替换。这通常是一个好主意,因为它允许在运行拼接之前检测到多种问题,但在某些情况下,这会使编译器错误地拒绝生成有效代码的拼接。
在这种情况下,这意味着编译器会尝试检查此代码:
data Alpha = Alpha t deriving (Show, Read)
这不起作用,因为派生的Show
和Read
实例需要使用Show
和Read
来t
,但是从{{ 1}}不是t
的类型参数,它不能添加必要的约束。当然,当运行此拼接时,Alpha
将被具体类型替换,因此适当的实例将可用,而不需要任何约束,因此这是编译器过于谨慎的情况之一
解决方法是不使用引用,而是使用TH组合器,这些组合器不受这些额外检查的限制。这很麻烦,但它确实有效:
t
已经有some talk about relaxing the checks done on quotes,但现在你只需处理它。