无法将预期类型“a”与实际类型“[a]”匹配

时间:2013-06-03 00:38:12

标签: haskell

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

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的初学者,错误信息对我来说太过希腊和拉丁语。根据我的理解,编译器无法在第二种情况下推断出类型。有人能指出我到底发生了什么吗?

3 个答案:

答案 0 :(得分:15)

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

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

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

答案 1 :(得分:6)

了解:究竟是什么将有助于解密错误消息。 :可以被认为是一个带有元素和列表的函数,并返回一个列表,其第一个元素是第一个参数,其余部分是第二个参数,或者:

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

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

此外,一般来说,当您不了解Haskell中的某些内容时,您应首先使用GHCI中的:t来查看它的类型。

答案 2 :(得分:2)

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

myLast (_:x) = x

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