我无法编译这个简单的Haskell函数。这是来自99个Haskell问题,其中一个应该实现last
。我写了以下版本:
myLast :: [a] -> a
myLast [] = []
myLast (x:[]) = x
myLast (x:xs) = myLast(xs)
但是,如果我将其加载到GHCi中,我会收到错误:
Couldn't match expected type `a' with actual type `[t0]'
`a' is a rigid type variable bound by
the type signature for myLast :: [a] -> a at problem1.hs:1:11
Relevant bindings include
myLast :: [a] -> a (bound at problem1.hs:3:1)
In the expression: []
In an equation for `myLast': myLast [] = []
Failed, modules loaded: none.
告诉我
myLast[] = []
是问题。
如果我删除它,它会被正确解释。但是如果我通过空列表
Prelude> myLast []
我得到了
> Non-exhaustive patterns in function myLast
这是有道理的,因为我没有匹配条件中的空列表。任何人都可以向我解释这个错误以及如何解决它吗?
答案 0 :(得分:5)
如果您有一个空列表,则无法返回a
,因为没有返回。您可以通过返回myLast
而不是Maybe a
来对a
类型中的这种可能性进行编码。然后,如果列表为空,则可以返回Nothing
:
myLast :: a -> Maybe a
myLast [] = Nothing
如果您无法更改功能类型,则唯一的选择是引发错误:
myLast [] = error "Empty list"
答案 1 :(得分:2)
您的类型签名说
myLast :: [a] -> a
如果将列表传递给myList
,它将返回列表中元素类型的单个元素。但是,你的定义是
myLast [] = []
如果你传递一个空列表,它会返回一个空列表。在签名中,您提到了一个元素,但在定义时您正在说一个列表。这就是Haskell抱怨这条线的原因。
但是当您删除该定义并使用空列表调用myLast
时,它无法将输入与为myLast
定义的任何模式匹配。这就是它失败的原因
Non-exhaustive patterns in function myLast
在这种特殊情况下,您没有有效的输入可供使用。所以,最好抛出一个错误,比如这个
myLast [] = error "Atleast one element should be there to find the last element"