在下面的 Haskell 代码中,函数 typeError 不进行类型检查。
wrap x = [x]
listf :: [[a]] -> [[a]]
listf = id
typeCheck :: [a] -> [[a]]
typeCheck x = listf (wrap x)
typeError :: [a] -> [[a]]
typeError = wrap . listf
如果未注释 GHC 会产生此错误:
Couldn't match type `a' with `[a0]'
`a' is a rigid type variable bound by
the type signature for typeError :: [a] -> [[a]] at tim.hs:10:1
Expected type: [a] -> [a]
Actual type: [[a0]] -> [[a0]]
In the second argument of `(.)', namely `listf'
In the expression: wrap . listf
我不明白为什么。a
应该能够统一[a0]
- 它们是独立的类型变量。这正是它推断的类型 for typeCheck
- 但不是在使用.
运算符时。
Hugs 产生了一个非常相似且同样虚假的错误消息:
ERROR "repro.hs":10 - Inferred type is not general enough
*** Expression : typeError
*** Expected type : [a] -> [[a]]
*** Inferred type : [[a]] -> [[[a]]]
此外,这很好用:
listf' :: [a] -> [a]
listf' = id
typeCheck' :: [a] -> [[a]]
typeCheck' = wrap . listf'
该问题仅发生在 [[a]] 或 [[[a]]] 或更大的情况下。这是怎么回事?