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
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.
I think you mean to use && rather than and. After doing that it loads without any errors.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With