Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/haskell/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Haskell 我的函数return last list有一个错误_Haskell - Fatal编程技术网

Haskell 我的函数return last list有一个错误

Haskell 我的函数return last list有一个错误,haskell,Haskell,我刚开始学习Haskell,我打算编写一个返回到上一个列表2的函数 lastButOne x=if((==)(长度x)2) 然后(标题x) 其他(尾x) 这是一个错误: ‧ Occurs check: cannot construct the infinite type: a ~ [a] ‧ In the expression: (tail x) In the expression: if ((==) (length x) 2) then (head

我刚开始学习Haskell,我打算编写一个返回到上一个列表2的函数

lastButOne x=if((==)(长度x)2)
然后(标题x)
其他(尾x)
这是一个错误:

    ‧ Occurs check: cannot construct the infinite type: a ~ [a]
    ‧ In the expression: (tail x)
      In the expression:
        if ((==) (length x) 2) then (head x) else (tail x)
      In an equation for ‘lastButOne’:
          lastButOne x = if ((==) (length x) 2) then (head x) else (tail x)
    ‧ Relevant bindings include
        x :: [a] (bound at D:\\tool\8.6.3\test\lBoErr.hs:1:12)
        lastButOne :: [a] -> a (bound at D:\\tool\8.6.3\test\lBoErr.hs:1:1)

  |
3 |                            else (tail x)
  |                                  ^^^^^^

我不明白我的代码哪里出错以及错误的含义。

lastButOne
的预期类型为
[a]->a
,但使用
尾x
您试图返回类型为
[a]
的值。该错误消息是由于类型检查器试图找到一个同时与
a
[a]
相结合的类型,以试图理解一个函数,该函数根据所采用的分支返回一个或另一个

您要做的是在列表末尾递归:

lastButOne x = if length x == 2
               then head x
               else lastButOne (tail x)
不过,这是更自然地使用模式匹配编写的

lastButOne [x,_] = x  -- lists of length exactly 2
lastButOne (_:xs) = lastButOne xs -- All other non-empty lists
注意
lastButOne
只是没有为空列表或单例列表定义,如果在这样的列表上调用,将产生运行时错误。您可以通过更改返回到
的值来修复此问题,可能是一个

lastButOne :: [a] -> Maybe a
lastButOne [x,_] = Just x
lastButOne (_:xs) = lastButOne xs
lastButOne _ = Nothing

函数
lastButOne
应该是什么类型?这可能会帮助您了解问题所在。我同意,此错误消息有点神秘。但是,如果查找和的类型签名,就可以看到基本问题。一个返回单个元素,另一个返回列表。GHC的错误消息基本上是在抱怨它试图同时找到一个类型,但显然失败了。添加一个显式类型签名
lastButOne::[a]->…
,将有助于编译器识别问题,并提供更好的错误消息。强烈建议从它的类型开始编写函数。我理解你所说的。因为我的功能同时使用“头”和“尾”,导致ghci类型检查混乱。我使用递归,因为它是一种容易实现的方法。当我学习Lisp时,递归是规则的。你能告诉我哈斯克尔的情况吗?谢谢你的回答,递归是任何迭代计算的唯一选择,可能比Lisp中的情况还要多。