【发布时间】:2014-06-02 02:05:22
【问题描述】:
我一直在尝试this question的答案中的一个小例子:
liftTup :: (x -> f x) -> (a, b) -> (f a, f b)
liftTup liftFunc (t, v) = (liftFunc t, liftFunc v)
这显然需要forall 量词才能工作,但我正在尝试理解错误消息的语法,以便能够在将来遇到类似问题时知道什么是错误的。所以对于这个我得到:
monad.hs:112:28-37: Couldn't match type `x' with `b' …
`x' is a rigid type variable bound by
the type signature for
liftTup :: (x -> f x) -> (a, b) -> (f a, f b)
at /Users/user/monad.hs:111:12
`b' is a rigid type variable bound by
the type signature for
liftTup :: (x -> f x) -> (a, b) -> (f a, f b)
at /Users/user/monad.hs:111:12
Expected type: f a
Actual type: f x
In the return type of a call of `liftFunc'
In the expression: liftFunc t
In the expression: (liftFunc t, liftFunc v)
monad.hs:112:40-49: Couldn't match type `a' with `b' …
`a' is a rigid type variable bound by
the type signature for
liftTup :: (x -> f x) -> (a, b) -> (f a, f b)
at /Users/user/monad.hs:111:12
`b' is a rigid type variable bound by
the type signature for
liftTup :: (x -> f x) -> (a, b) -> (f a, f b)
at /Users/user/monad.hs:111:12
Expected type: f b
Actual type: f x
In the return type of a call of `liftFunc'
In the expression: liftFunc v
In the expression: (liftFunc t, liftFunc v)
据我所知,第一个错误与第一次将liftFunc 应用于t 有关,因此它尝试将f x 与f a 匹配。但是b 和这个有什么关系呢? b 只出现在元组的第二个元素中。
我猜第二个错误是因为a 在之前的liftFunc 应用程序中与x 匹配,而现在我们正试图将它与第二个应用程序中的b 匹配,但这并没有不太行。是这样吗?
阅读这些错误消息的正确方法是什么?“无法将类型..与..匹配”中提到的变量与“预期类型:..实际类型:..”消息中提到的变量之间的关系是什么?
【问题讨论】:
-
我的猜测(这是未受过足够教育的,我不会给出答案),是 GHC first 尝试统一类型变量以使所有内容都可以很好地键入,此时点它发现所有
a、b和x必须相同;并且只有 then 检查三个变量中的任何一个是否是刚性的并且不能相互统一,从而给出这种看起来随机的罪魁祸首。