12

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

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

4

3 回答 3

17

您将输入声明为 type 列表,[a]其余为 type a

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

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

于 2013-06-03T00:53:50.737 回答
6

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

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

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

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

于 2013-06-03T01:55:48.097 回答
2

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

myLast (_:x) = x

如果你想匹配最后一个元素,看看这个答案 -你可以使用模式匹配来绑定列表的最后一个元素吗?

于 2013-06-03T00:54:27.240 回答