我遇到了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类型的事实所迷惑。
据我所知,这种解决方案有更明智的方法(包括简单的单功能或单线解决方案);但我只是想弄清楚上面的错误,以便我可以在这种问题的方法中了解我的错误。
答案 0 :(得分:3)
有关查看代码的一些意见:
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中调用函数的方式。您不能使用括号来调用函数。这些括号实际上做的是将两个值转换为元组,然后将该元组作为单个参数传递给函数,从而导致类型检查器的总混乱。