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