我是一名Haskell初学者,正在进行Real World Haskell第2章的练习,在那里你编写一个返回列表倒数第二个元素的函数。
我已经编写了以下函数来尝试解决此问题:
-- file: \Learn Haskell\lastButOne.hs
lastButOne xs = if length xs == 2
then head xs
else lastButOne tail xs
我不明白的是编译器抛出的这个错误:
lastButOne.hs:2:1: error:
• Couldn't match type ‘[a] -> [a]’ with ‘[t]’
Expected type: ([a] -> [a]) -> [t] -> t
Actual type: [t] -> t
• Relevant bindings include
lastButOne :: ([a] -> [a]) -> [t] -> t (bound at lastButOne.hs:2:1)
根据我的理解,ghci认为我的功能应该与它的类型不同,但我不明白为什么会发生这种情况,或者我如何解决它。
编辑:谢谢你的回答!我已将代码更新为:
-- file: \Learn Haskell\lastButOne.hs
lastButOne xs = if length xs == 2
then head xs
else if length xs < 2
then error "This list does not have a second-to-last element."
else lastButOne (tail xs)
这消除了将tail xs
解释为两个参数而不是单个表达式的错误。我还添加了一些代码,确保列表不会太短。 Willem Van Onsem的解决方案更好,但作为一种练习,我认为我提出的解决方案只使用了本书目前介绍的概念。
答案 0 :(得分:2)
问题出在以下几行:
else lastButOne tail xs
应该是:
else lastButOne (tail xs)
其他ghci
您提供lastButOne
两件事:tail
和xs
。
然而,您可以使代码更优雅:
lastButOne [x,_] = x
lastButOne xs = lastButOne $ tail xs
此外,您必须找到一种方法使用一个元素解析列表,并使用空列表。现在该函数将开始循环。一个想法可能是在这些列表上出错,例如:
lastButOne [x,_] = x
lastButOne (_:xs) = lastButOne xs
lastButOne [] = error "The list has no last but one element."