Haskell类型签名:有关lastButOne程序的类型签名的问题

tru*_*llo 3 haskell types

我正在阅读真实世界的Haskell,其中的一项练习是构造一个函数lastButOne,该函数仅返回列表的倒数第二个元素。

到目前为止,我的代码:

lastButOne xs = if null xs || length xs == 1
                    then []
                else if length xs == 2
                    then head xs
                else lastButOne (tail xs)

Run Code Online (Sandbox Code Playgroud)

我的问题:输入应该是一个列表,如果它是非空的或长度为1,则返回一个空列表,在其他情况下,返回倒数第二个元素。但是,输入列表时出现错误。输入第二级嵌套列表时没有任何错误。

我怀疑类型签名有问题,当我调用类型签名时,它返回

lastButOne :: [[a]] -> [a].
Run Code Online (Sandbox Code Playgroud)

但是我希望类型签名是[a] -> a。我盯着这个功能已经有一段时间了,还浏览了其他文章,但是我似乎无法弄清为什么类型签名是[[a]] -> a。任何提示将不胜感激。

Dam*_*ero 5

您可以通过以下模式匹配来完成:

lastButOne :: [a] -> a
lastButOne []    = error "not elements"
lastButOne [x]   = x
lastButOne [x,_] = x
lastButOne (x:xs) = lastButOne xs
Run Code Online (Sandbox Code Playgroud)

  • @trujello,模式匹配是这种定义样式的名称,其中您为要定义的函数提供多个方程式。第一个说的是给一个空列表时的操作,第二个说给一个具有一个元素的列表时的操作,依此类推。[在此处了解更多信息](http://learnyouahaskell.com/syntax-in-functions) (3认同)
  • 我并不完全相信OP希望`lastButOne [x] = x`而不是错误。(仍然是+1) (3认同)