Ana*_*Ana 8 haskell template-haskell
以下内容无法编译:
import Language.Haskell.TH
makeAlpha n = [d| data Alpha = Alpha $(conT n) deriving (Show, Read) |]
Run Code Online (Sandbox Code Playgroud)
我无法弄清楚错误意味着什么:
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) |]
Run Code Online (Sandbox Code Playgroud)
有可能做这样的派生吗?
出现此问题是因为TH引号在编译时会进行类型检查,并且拼接由变量替换.这通常是一个好主意,因为它允许在运行拼接之前检测到多种问题,但在某些情况下,这会使编译器错误地拒绝生成有效代码的拼接.
在这种情况下,这意味着编译器尝试检查此代码:
data Alpha = Alpha t deriving (Show, Read)
Run Code Online (Sandbox Code Playgroud)
这不起作用,因为派生Show
和Read
实例需要使用Show
和Read
for t
,但由于t
不是类型参数Alpha
,因此无法添加必要的约束.当然,当运行此拼接时,t
将替换为具体类型,因此可以使用适当的实例而无需任何约束,因此这是编译器过于谨慎的情况之一.
解决方法是不使用引用,而是使用TH组合器,这些组合器不受这些额外检查的限制.这很麻烦,但它有效:
makeAlpha n = sequence [dataD (cxt []) alpha []
[normalC alpha [strictType notStrict (conT n)]] [''Show, ''Read]]
where alpha = mkName "Alpha"
Run Code Online (Sandbox Code Playgroud)
有一些关于放松对报价进行检查的讨论,但现在你只需处理它.