如何处理我自己的`last`版本中的空列表?

Ste*_*eve 1 haskell list

我无法编译这个简单的Haskell函数.它来自99个Haskell问题,应该实现last.我写了以下版本:

 myLast :: [a] -> a
 myLast []     = []       
 myLast (x:[]) = x          
 myLast (x:xs) = myLast(xs) 
Run Code Online (Sandbox Code Playgroud)

但是,如果我将其加载到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.
Run Code Online (Sandbox Code Playgroud)

这告诉了我

myLast[]    = [] 
Run Code Online (Sandbox Code Playgroud)

是问题.

如果我删除它,它会被正确解释.但是,如果我通过空列表

Prelude> myLast []
Run Code Online (Sandbox Code Playgroud)

我明白了

> Non-exhaustive patterns in function myLast
Run Code Online (Sandbox Code Playgroud)

这是有道理的,因为我在匹配条件中没有空列表.任何人都可以向我解释这个错误以及如何解决它?

Lee*_*Lee 5

如果您有一个空列表,那么您将无法返回,a因为没有返回.你可以myLast通过返回a Maybe a而不是a 来编码这种可能性a.然后,Nothing如果列表为空,您可以返回:

myLast :: a -> Maybe a
myLast [] = Nothing
Run Code Online (Sandbox Code Playgroud)

如果您无法更改函数的类型,则唯一的选择是引发错误:

myLast [] = error "Empty list"
Run Code Online (Sandbox Code Playgroud)

  • 我会添加类似的东西:"毕竟,你如何选择空列表的最后一个元素?你如何选择空列表的_any_元素?没有明智的选择.但是,你可以改变你的函数类型一点点到'myLast :: [a] - >也许是一个`并返回`Just x`或`Nothing`". (2认同)