导出Show的模板Haskell数据声明

时间:2011-12-31 18:01:04

标签: haskell template-haskell

以下内容无法编译:

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) |]

可以做这样的派生吗?

1 个答案:

答案 0 :(得分:7)

出现此问题是因为TH引号在编译时会进行类型检查,并且拼接由变量替换。这通常是一个好主意,因为它允许在运行拼接之前检测到多种问题,但在某些情况下,这会使编译器错误地拒绝生成有效代码的拼接。

在这种情况下,这意味着编译器会尝试检查此代码:

data Alpha = Alpha t deriving (Show, Read)

这不起作用,因为派生的ShowRead实例需要使用ShowReadt,但是从{{ 1}}不是t的类型参数,它不能添加必要的约束。当然,当运行此拼接时,Alpha将被具体类型替换,因此适当的实例将可用,而不需要任何约束,因此这是编译器过于谨慎的情况之一

解决方法是不使用引用,而是使用TH组合器,这些组合器不受这些额外检查的限制。这很麻烦,但它确实有效:

t

已经有some talk about relaxing the checks done on quotes,但现在你只需处理它。