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
(((x
mody) /= 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