List 如何处理我自己版本的“last”中的空列表?
我很难编译这个简单的Haskell函数。它来自99个Haskell问题,人们应该在这里实现List 如何处理我自己版本的“last”中的空列表?,list,haskell,List,Haskell,我很难编译这个简单的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]'
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 []
我明白了
这很有意义,因为我在匹配条件中没有空列表。有人能给我解释一下这个错误以及如何修复它吗?如果你有一个空列表,那么你就不能返回一个
a
,因为没有可以返回的。您可以通过返回一个可能是一个而不是a
来将这种可能性编码为myLast
类型。如果列表为空,则可以返回Nothing
:
myLast :: a -> Maybe a
myLast [] = Nothing
如果无法更改函数的类型,则唯一的选项是引发错误:
myLast [] = error "Empty list"
如果列表为空,则无法返回a
,因为没有可返回的列表。您可以通过返回一个可能是一个而不是a
来将这种可能性编码为myLast
类型。如果列表为空,则可以返回Nothing
:
myLast :: a -> Maybe a
myLast [] = Nothing
如果无法更改函数的类型,则唯一的选项是引发错误:
myLast [] = error "Empty list"
你的签名上写着
myLast :: [a] -> a
如果将列表传递给myList
,它将返回列表中元素类型的单个元素。但是,你的定义是
myLast [] = []
如果您传递一个空列表,它将返回一个空列表。在签名中,您提到了单个元素,但在定义时,您说的是列表。这就是哈斯克尔抱怨这句台词的原因
但是,当您删除该定义并使用空列表调用myLast
时,它无法将输入与为myLast
定义的任何模式匹配。这就是为什么它会失败
函数myLast中的非穷举模式
在这种特殊情况下,您没有可处理的有效输入。所以,最好抛出一个错误,像这样
myLast [] = error "Atleast one element should be there to find the last element"
你的签名上写着
myLast :: [a] -> a
如果将列表传递给myList
,它将返回列表中元素类型的单个元素。但是,你的定义是
myLast [] = []
如果您传递一个空列表,它将返回一个空列表。在签名中,您提到了单个元素,但在定义时,您说的是列表。这就是哈斯克尔抱怨这句台词的原因
但是,当您删除该定义并使用空列表调用myLast
时,它无法将输入与为myLast
定义的任何模式匹配。这就是为什么它会失败
函数myLast中的非穷举模式
在这种特殊情况下,您没有可处理的有效输入。所以,最好抛出一个错误,像这样
myLast [] = error "Atleast one element should be there to find the last element"
我想添加这样的内容:“毕竟,如何选择空列表的最后一个元素?如何选择空列表的任何元素?没有明智的选择。但是,您可以将函数的类型稍微更改为myLast::[a]->可能是a
,然后返回仅x
或无任何内容
”@Zeta我来自Scala。这就更有意义了。我想添加一些类似的内容:“毕竟,如何选择空列表的最后一个元素?如何选择空列表的任何元素?没有明智的选择。但是,您可以将函数的类型稍微更改为myLast::[a]->可能是一个
,或者返回仅x
或者无
“@Zeta我来自Scala背景。这就更有意义了。last实际上是一个非常糟糕的函数,它是局部函数,它对空列表没有正确的求值,因此唯一的选择是出错(隐式使用非穷举模式,或显式使用错误“last对空列表不起作用”
稍好一点,但在大型程序中调试时仍然很糟糕)。这是你不应该使用的函数之一,比如head
或tail
。如果你需要一个安全的最后一个,我会建议你看看库中的所有选择与理智的类型。当然,对于一个无关紧要的练习来说!:)只是为了好玩,你能用foldl
编写myLast::[a]>可能是一个
,并且没有显式递归吗?最后一个函数实际上是一个非常糟糕的函数,它是局部的,它没有对空列表进行适当的计算,所以唯一的选择是出错(隐式使用非穷举模式或显式使用错误)“last在空列表上不起作用”
这稍微好一点,但在大型程序中调试起来仍然很糟糕)。这是你不应该使用的函数之一,比如head
或tail
。如果你需要一个安全的last,我建议你在库中查找所有类型更为合理的选项。当然,对于一个不太重要的练习!:)只是为了好玩,你能写myLast:[a]->可能是一个
使用foldl
且没有显式递归的
?