如何阅读ghci类型错误?

时间:2014-06-02 02:05:23

标签: haskell types ghci

我一直在尝试从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 xf a匹配。但b如何与此相关? b仅出现在元组的第二个元素中。

我猜测的第二个错误来自a与之前的x应用中liftFunc匹配的事实,现在我们尝试将其与b匹配在第二个,但这不是很有效。这是对的吗?

读取这些错误消息的正确方法是什么?“无法匹配类型..与...”中提到的变量之间的关系是什么?“预期类型:..实际类型:..”消息中提到的变量是什么?

2 个答案:

答案 0 :(得分:4)

您正在正确阅读类型错误:

  1. GHC正在尝试推断/检查表达式liftFunc t
  2. 的类型
  3. 它发现liftFunc此应用程序的返回类型为f x
  4. 它发现此表达式的预期类型应为f a
  5. 这要求f xf a属于同一类型; GHC在试图证明要求xb是同一件事时失败了
  6. “期望类型”和“实际类型”与之后立即讨论的表达式的类型相关(“在对liftFunc的调用的返回类型...”中)。但是“无法将类型'x'与'b'匹配”告诉你它注意到的事情是不可能的,当试图将预期的类型与实际类型相匹配时,所以它不一定直接报告那个两者不匹配。

    这可能不直观,但它是有效的。由于liftFuncliftTup中具有单形类型,并且它适用于ab两种类型的值,因此类型检查器会推断出xab必须完全相同。所以x ~ b~是如何在Haskell中编写类型相等)实际上必须保持这一点是一个良好类型的表达式,并确定它不能统一(通过观察xb都是必须保持独立普遍量化的“刚性类型变量”确定确定存在类型错误。

    我的猜测是类型检查器已经做了一些分析以得出一组成对约束,包括f x ~ f af x ~ f bx ~ ax ~ ba ~ b,然后开始证明他们。也许x ~ b只是它尝试过的第一个。或许它必须证明x ~ a,并且没有直接的方法来证明这一点,并且唯一可用的其他信息是a ~ b它尝试应用它来导出x ~ b,然后无法证明(并且循环检查阻止它应用b ~ a再次以x ~ a结束)它在那时失败。无论如何,沿着这些方向的东西。我很漂亮x ~ b只是在尝试检查liftFunc t的过程中发现的第一件事是不可能的。

答案 1 :(得分:2)

这些错误完全描述了您的问题。但阅读ghc错误消息有时很困难,因为它们包含如此多的信息。

Couldn't match type x with b表示它希望xb属于同一类型,但无法证明这一点。同样地,对于另一个错误。所以从两个错误一起,你知道编译器期望a==b==x,但这不是你写的。

但是你不知道为什么它确实期待这个。第一条错误消息说明如下:

Expected type: f a
  Actual type: f x
In the return type of a call of `liftFunc'

您声称liftunc的类型为x -> f x。但是,您还声称liftFunc t的类型为f a。从这一点来看,编译器可以推断的{em>仅事物ax必须是同一类型。但是没有办法证明,因此,输入错误。

第二个错误是将完全相同的逻辑应用于元组的第二个参数。