0

我遇到了 Haskell 的问题,它似乎不喜欢我从辅助函数返回布尔语句的事实。我正在检查列表中两个数字之间的距离是否非常小(小于 0.01);如果是真的,我会返回这个数字。在它为假的情况下,我检查列表中接下来的两个数字。

代码:

positionChecker Pos ns = if compareDistance(ns !! Pos, ns !! (Pos+1))
                         then Pos
                         else positionChecker(Pos+1) ns

compareDistance n1 n2 = if abs(n1 - n2) < 0.01
                         then True
                         else False

(注意:我已经删除了构建列表并调用 positionChecker 的前面代码,将其初始化为位置 0,以及一个数字列表)

以上返回以下错误;

pchk.hs:9:49:
Couldn't match expected type ‘Bool’ with actual type ‘(a, a)’

Relevant bindings include
  ns :: [a] (bound at pchk.hs:9:21)
  positionChecker' :: Int -> [a] -> a (bound at pchk.hs:9:1)
In the first argument of ‘compareDistance’, namely
  ‘(ns !! Pos, ns !! (Pos + 1))’
In the expression:
  compareDistance (ns !! Pos, ns !! (Pos + 1))
In the expression:
  if compareDistance (ns !! Pos, ns !! (Pos + 1)) then
      ns !! (Pos + 1)
  else
      positionChecker' (Pos + 1) ns

同样,据我所知,haskell 似乎对 compareDistance 返回 Bool 类型这一事实感到困惑。

我知道这个解决方案有更明智的方法(包括简单的、单功能或单线解决方案);但我只是试图理解上述错误,以便我可以了解在这种解决问题的方法中我哪里出错了。

4

3 回答 3

4

关于查看您的代码的一些评论:

  • 仅在 Haskell 中键入名称以大写字母开头。所以你必须解决这个问题:

positionChecker Pos ns = ...

  • 不要使用!!函数,这是不安全的:

λ> [0,1] !! 3 *** Exception: Prelude.(!!): index too large

  • 始终为您的函数编写类型签名。这将帮助您更轻松地调试问题。

  • Haskell 有柯里化的概念。所以你不要像这样传递参数:

compareDistance(ns !! Pos, ns !! (Pos+1))

但像这样:

compareDistance (ns !! Pos) (ns !! (Pos+1))
于 2014-11-18T21:16:23.380 回答
2

您使用元组作为参数调用“compareDistance”,而不是给它两个参数。去掉括号和昏迷。是 Haskell,不是 C。

于 2014-11-18T21:13:13.030 回答
1

这不是您在 Haskell 中调用函数的方式。您不使用括号来调用函数。这些括号实际上所做的是将两个值转换为一个元组,然后将该元组作为单个参数传递给函数,从而导致类型检查器完全混乱。

于 2014-11-18T21:13:47.427 回答