简体   繁体   English

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

[英]Haskell type signatures: Question on type signature of lastButOne Program

I'm reading through Real World Haskell and one of the exercises is to construct a function lastButOne, which simply returns the second to last element of a list.我正在阅读真实世界的 Haskell ,其中一个练习是构造一个 function lastButOne,它只返回列表的倒数第二个元素。

My code so far:到目前为止我的代码:

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

My problem : The input should be a list, which then returns an empty list if it is either nonempty or is of length 1, and in other cases returns the second to last element.我的问题:输入应该是一个列表,如果它是非空的或长度为 1,则返回一个空列表,在其他情况下返回倒数第二个元素。 However, I get an error when I input a list.但是,当我输入列表时出现错误。 I don't get any errors when I input a second order nested list.当我输入二阶嵌套列表时,我没有收到任何错误。

I suspected something was wrong with the type signature, and when I call the type signature, it returns我怀疑类型签名有问题,当我调用类型签名时,它返回

lastButOne :: [[a]] -> [a].

But I want the type signature to be [a] -> a .但我希望类型签名是[a] -> a I've stared at this function for a while and have explored other posts, but I can't seem to figure out why the type signature is [[a]] -> a .我已经盯着这个 function 看了一段时间并探索了其他帖子,但我似乎无法弄清楚为什么类型签名是[[a]] -> a Any hints would be appreciated.任何提示将不胜感激。

You can acomplish that with pattern matching like:您可以使用以下模式匹配来完成此操作:

lastButOne :: [a] -> a
lastButOne []    = error "not elements"
lastButOne [x]   = x
lastButOne [x,_] = x
lastButOne (x:xs) = lastButOne xs

You may explicitly declare your function's type signature by adding lastButOne:: [a] -> [a] to your code.您可以通过在代码中添加lastButOne:: [a] -> [a]来显式声明函数的类型签名。 The function will then expect xs to be a list.然后 function 将期望 xs 是一个列表。

But then we would meet another error: the fact that one of the outputs of your function ( head xs ) isn't in fact a list [a] , but rather an element a .但是随后我们会遇到另一个错误:您的 function ( head xs )的输出之一实际上不是列表[a] ,而是元素a

A similar error message will pop up if you add the signature lastButOne:: [a] -> a , but this time because [] is not an element of type a .如果添加签名lastButOne:: [a] -> a会弹出类似的错误消息,但这次是因为[]不是 a 类型a元素。

A simple solution might be to return your second to last element inside a list, using [head xs] as an output.一个简单的解决方案可能是返回列表中倒数第二个元素,使用[head xs]作为 output。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM