I've figured out the modifications to get the code to compile, but it does not actually find primes. I had to change
fromInteger (`sqrt` number)
to
floor $ sqrt $ fromIntegral number
The backtick notation around a function name is to turn it in to an infix "operator" of sorts, so you could do
mod x y
or
x `mod` y
but not
`mod` x y
Next, you were using fromInteger
instead of fromIntegral
, which is the one that works on Int
s (Int
and Integer
are different types). Finally, I removed the floor
from number
in the second guard of checkDiv
, since number
is already an Int
.
isPrime :: Int -> Bool
isPrime number
| (number == 1) || (number == 2) = True
| even number = False
| otherwise = checkDiv number (floor $ sqrt $ fromIntegral number)
checkDiv :: Int -> Int -> Bool
checkDiv number divisor
| number == 2 = True
| (number `mod` divisor) == 0 = False
| otherwise = checkDiv number $ divisor - 1
So let's work through your code so that you can see what's going on. If I were to compute checkDiv 17 4
(4
is floor $ sqrt $ fromIntegral 17
), it would perform
checkDiv 17 4
| 17 == 2 No
| 17 `mod` 4 == 0 No
| otherwise = checkDiv 17 (4 - 1) = checkDiv 17 3
checkDiv 17 3
| 17 == 2 No
| 17 `mod` 3 == 0 No
| otherwise = checkDiv 17 (3 - 1) = checkDiv 17 2
checkDiv 17 2
| 17 == 2 No
| 17 `mod` 2 == 0 No
| otherwise = checkDiv 17 (2 - 1) = checkDiv 17 1
checkDiv 17 1
| 17 == 2 No
| 17 `mod` 1 == 0 Yes = False
But 17
is prime! Do you see where your algorithm is doing something wrong?
sqrt
in backticks? Just use(sqrt number)
. – Tom Ellissqrt
ofnumber
because it is anInt
not aFloating
. AndfromInteger
is forInteger
.fromIntegral
is for anyIntegral
type. – DiegoNolan