2
votes

I have some problems with the different types in Haskell, how can I solve this?

Couldn't match expected type Integer with actual type Int -> t0 -> t0

Thanks

isPrime :: Int -> Bool
isPrime number
    | (number == 1) || (number == 2) = True
    | even number = False
    | otherwise = checkDiv number (fromInteger (`sqrt` number))

checkDiv :: Int -> Int -> Bool
checkDiv number divisor 
    | number == 2 = True
    | (floor number `mod` divisor) == 0 = False
    | otherwise = checkDiv number $ divisor - 1
1
What are you trying to solve with this problem?bheklilr
Why did you put sqrt in backticks? Just use (sqrt number).Tom Ellis
isPrime number should be true if number is a prime number, and false if not, but I want to use this algorithmmsietrterc
you can't take sqrt of number because it is an Int not a Floating. And fromInteger is for Integer. fromIntegral is for any Integral type.DiegoNolan
Note that 1 isn't prime.j.i.h.

1 Answers

7
votes

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 Ints (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?