Couldn't match expected type ‘Bool’ with actual type ‘(a, a)’

2.4k views Asked by At

I've got an issue with Haskell where it appears to be disliking the fact that I'm returning a Boolean statement from a helper function. I'm checking if the distance between two numbers in a list is very small (less than 0.01); and in the case where it is true, I return this number. In the case where it is false, I check the next two numbers in the list.

Code:

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

(NB: I've removed the preceeding code that builds the list and calls positionChecker, initialising it with position 0, and a list of numbers)

The above is returning the following error;

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

Again, from what I can make it, haskell seems to be confused by the fact that compareDistance is returning a Bool type.

I understand that there are far more sensible approaches to this solution (inclusive of simple, single-function or single-line solutions); but I'm just trying to make sense of the above error so that I can learn where I'm going wrong in this type of approach to a problem.

3

There are 3 answers

1
Sibi On BEST ANSWER

Some comments on seeing your code:

  • Only type names in Haskell start with Capital letter. So you have to fix this:

positionChecker Pos ns = ...

  • Don't use !! function, it's unsafe:

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

  • Always write type signature for your functions. That will help you in debugging your problem more easily.

  • Haskell has the concept currying. So you don't pass parameters like this:

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

but like this:

compareDistance (ns !! Pos) (ns !! (Pos+1))
0
Eugene Sh. On

You are calling "compareDistance" with a tuple as parameter instead of giving it two arguments. Remove the brackets and the coma. It's Haskell, not C.

0
Sebastian Redl On

This isn't how you call functions in Haskell. You don't use parentheses to call functions. What these parentheses actually do is turn the two values into a tuple, and then that tuple is passed as a single argument to the function, resulting in total chaos for the type checker.