Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

The function `(y * y) < x' is applied to two arguments, but its type `Bool' has none

Tags:

haskell

So I am working on Problem 31.

I have written the following function in hopes to determine if a number is a prime:

isPrime :: Integer -> Bool

isPrime x = prime x 2
            where
            prime :: Integer -> Integer -> Bool
            prime x y | ((y*y) < x) and ((x `mod` y) /= 0) = prime x (y+1)
                      | ((y*y) >= x) = True
                      | otherwise = False

My logic was make an isPrime function, and have a function within isPrime called prime to store 2 parameters, the number I want to check to see if it is prime (x) and an iterator to check all the numbers below sqrt of x and see if they divide x. prime has 3 guards:

| ((y*y) < x) and ((x `mod` y) == 0) = prime x (y+1)

This line is supposed to say: is the number I passed less than the square root of x (((y*y) < x)) and if it is check if x is divisible by y (((xmody) /= 0)), if it isn't I use recursion and increment y to check again with a higher number.

This line:

| ((y*y) >= x) = True

Is supposed to be like if all the numbers below the square root don't divide x in anyway, x must be prime.

Finally, this line:

| otherwise = False

means that a number somewhere along the line a number divided x so it is not prime.

I thought the code I wrote made sense, I know it isn't the most efficient, considering I could just check primes below sqrt x and not all the numbers below sqrt x, but anyways, I am having problems with this statement:

((y*y) < x)

GHCi says:

The function `(y * y) < x' is applied to two arguments, but its type `Bool' has none

I thought that the < was supposed to take in two arguments and return a Bool, the error message doesn't really make sense to me. Can you help me figure out what I am doing wrong? Thanks.

Quick edit now that I got it to run, this line:

| ((y*y) >= x) = True

should be:

| ((y*y) > x) = True
like image 249
Dair Avatar asked Mar 16 '12 03:03

Dair


2 Answers

To explain what's happening here... the problem isn't with <, it's with the whole expression:

((y*y) < x) and ((x `mod` y) /= 0)

What you're missing is the backticks around and:

((y*y) < x) `and` ((x `mod` y) /= 0)

When you use a function infix like that, if it isn't an operator (i.e. made of symbols, like ++), then you need to surround it with backticks.

Alternately, you can use it non-infix as a function, like:

and ((y*y) < x) ((x `mod` y) /= 0)

Now to explain the error message. What the compiler is saying is that you're trying to use the expression ((y*y) < x) as a function. Since function application in Haskell doesn't use brackets, anything like f x y is a function f applied to two arguments x and y.

Since you forgot to put backticks around the and, Haskell interprets ((y*y) < x) and ((x `mod` y) /= 0) as you trying to apply the function ((y*y) < x) to the arguments and and ((x `mod` y) /= 0). Of course, this doesn't work, because ((y*y) < x) returns Bool, which isn't a function, so it complains with "The function (y * y) < x is applied to two arguments, but its type Bool has none". Bool isn't a function type, and so it has no arguments.

...

Of course, the other error you have now is that it should be && not and - and has type [Bool] -> Bool.

like image 129
porges Avatar answered Sep 30 '22 21:09

porges


I think you mean to use && rather than and. After doing that it loads without any errors.

like image 38
ivanm Avatar answered Sep 30 '22 19:09

ivanm