无法将预期类型'Bool'与实际类型'(a,a)'匹配

时间:2014-11-18 21:08:49

标签: haskell ghci winghci

我遇到了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类型的事实所迷惑。

据我所知,这种解决方案有更明智的方法(包括简单的单功能或单线解决方案);但我只是想弄清楚上面的错误,以便我可以在这种问题的方法中了解我的错误。

3 个答案:

答案 0 :(得分:3)

有关查看代码的一些意见:

  • 只有Haskell中的类型名称以大写字母开头。所以你必须解决这个问题:

positionChecker Pos ns = ...

  • 不要使用!!功能,这是不安全的:

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

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

  • Haskell的概念是currying。所以你不传递这样的参数:

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

但是像这样:

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

答案 1 :(得分:2)

您正在呼叫&#34; compareDistance&#34;使用元组作为参数而不是给它两个参数。删除括号和昏迷。它是Haskell,而不是C.

答案 2 :(得分:1)

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