Reputation: 103
I'm a beginner to Haskell and I decided to try to write a simple function to check if a number is prime or not. Here is my attempt. Forgive me if its too shabby.
isPrime x = if x > 2 then (True `elem` [(x `mod` num)==0 |num<-[2..x/2]]) else if x>0 then True else False
Using interactive GHC, the error when I type in isPrime 7 is as follows:
<interactive>:75:1: error:
• Ambiguous type variable ‘a0’ arising from a use of ‘isPrime’
prevents the constraint ‘(Integral a0)’ from being solved.
Probable fix: use a type annotation to specify what ‘a0’ should be.
These potential instances exist:
instance Integral Integer -- Defined in ‘GHC.Real’
instance Integral Int -- Defined in ‘GHC.Real’
instance Integral Word -- Defined in ‘GHC.Real’
• In the expression: isPrime 7
In an equation for ‘it’: it = isPrime 7
<interactive>:75:9: error:
• Ambiguous type variable ‘a0’ arising from the literal ‘7’
prevents the constraint ‘(Num a0)’ from being solved.
Probable fix: use a type annotation to specify what ‘a0’ should be.
These potential instances exist:
instance Num Integer -- Defined in ‘GHC.Num’
instance Num Double -- Defined in ‘GHC.Float’
instance Num Float -- Defined in ‘GHC.Float’
...plus two others
...plus one instance involving out-of-scope types
(use -fprint-potential-instances to see them all)
• In the first argument of ‘isPrime’, namely ‘7’
In the expression: isPrime 7
In an equation for ‘it’: it = isPrime 7
Upvotes: 1
Views: 100
Reputation: 35512
Here's what's wrong with your code:
mod
requires that the numbers involved be an instance of Integral
(integers)/
requires that the numbers involved be an instance of Fractional
(floating points)Therefore, x
must be both Integral
and Fractional
, which does not exist in the Haskell standard library. Instead, you can use div
, which is like /
but operates on Integral
:
isPrime x = if x > 2 then (True `elem` [(x `mod` num)==0 |num<-[2..x `div` 2]]) else if x>0 then True else False
However, your code also has logic errors and is much longer than it could be. First of all, you're not looking for True
in the array, you're looking for True
not being in the array, so you have to negate that statement. Additionally, you can just use function guards:
isPrime :: (Integral a) => a -> Bool
isPrime x
| x > 2 = all (\num -> x `mod` num /= 0) [2..x `div` 2]
| otherwise = x > 1
Upvotes: 4