【问题标题】:Couldn't match expected type `a' with actual type `[a]'无法将预期类型“a”与实际类型“[a]”匹配
【发布时间】:2013-06-03 00:38:11
【问题描述】:

我能够完美地执行以下代码

myLast :: [a] -> a
myLast [] = error "Can't call myLast on an empty list!"
myLast (x:_) = x

但我收到以下代码的错误Couldn't match expected type `a' with actual type `[a]'. `a' is a rigid type variable bound by the type signature for myLast :: [a] -> a

myLast :: [a] -> a
myLast [] = error "Can't call myLast on an empty list!"
myLast (_:x) = x

我是 Haskell 的初学者,错误信息对我来说太希腊化和拉丁化了。据我了解,编译器无法推断第二种情况的类型。有人可以指出这里实际发生的事情吗?

【问题讨论】:

    标签: haskell


    【解决方案1】:

    您将输入声明为[a] 类型的列表,其余为a 类型。

    Haskell 中[a] 类型的列表由a 类型的头部和[a] 类型的尾部组成。 cons 构造函数: 将头部和尾部作为其参数。

    当您将列表解构为(x:y) 时,x 是头部,y 是尾部。因此,在您的第二个代码片段中,当您的类型签名要求您返回 a 类型的值时,您将绑定列表类型为 [a] 的列表的 tail(头部就是一个例子)。

    【讨论】:

      【解决方案2】:

      了解: 的真正含义将有助于解密错误消息。 : 可以被认为是一个函数,它接受一个元素和一个列表,并返回一个列表,其第一个元素是第一个参数,其余部分是第二个参数,或者:

      (:) :: a -> [a] -> [a]
      

      进入你的功能,你写了myLast :: [a] -> a;但是,myLast (_:x) = x 的类型是 myLast :: [a] -> [a],因为 :(您将其命名为 x)的第二个参数本身就是一个列表。

      另外,一般来说,当你对 Haskell 有什么不明白的时候,你应该先在 GHCI 中使用 :t 来看看它的类型。

      【讨论】:

        【解决方案3】:

        (_:x) 将 _ 与列表的头部匹配,将 x 与列表的尾部匹配。列表尾部的类型是 [a]。您正在尝试返回 [a]',因为函数声明将返回类型指定为 a。

        myLast (_:x) = x
        

        如果您想匹配最后一个元素,请查看此答案 - Can you use pattern matching to bind the last element of a list?

        【讨论】:

          猜你喜欢
          • 2018-04-05
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2016-11-21
          • 2015-04-15
          相关资源
          最近更新 更多