I am new to Haskell, but I know C. I'm referring Learn You a Haskell for Great Good as study source and currently learning about "List comprehension". Since I can easily make a prime numbers program in C, I tried the same in Haskell with the following code:
primes = [x | x <- [2..100], null [f | f <- [2..round (x/2)], 0 == rem x f]]
--it creates a list of prime numbers upto 100. `f` denotes factors.
--working principle: this code adds those numbers to the main list who have no factors (excluding 1 and the number itself.
But it is showing a big error in my GHCi:
train.hs:84:20:
No instance for (Enum t0)
arising from the arithmetic sequence ‘2 .. 100’
The type variable ‘t0’ is ambiguous
Relevant bindings include primes :: [t0] (bound at train.hs:84:1)
Note: there are several potential instances:
instance forall (k :: BOX) (s :: k). Enum (Data.Proxy.Proxy s)
-- Defined in ‘Data.Proxy’
instance Integral a => Enum (GHC.Real.Ratio a)
-- Defined in ‘GHC.Real’
instance Enum Ordering -- Defined in ‘GHC.Enum’
...plus 8 others
In the expression: [2 .. 100]
In a stmt of a list comprehension: x <- [2 .. 100]
In the expression:
[x |
x <- [2 .. 100],
null [f | f <- [2 .. round (x / 2)], 0 == rem x f]]
train.hs:84:21:
No instance for (Num t0) arising from the literal ‘2’
The type variable ‘t0’ is ambiguous
Relevant bindings include primes :: [t0] (bound at train.hs:84:1)
Note: there are several potential instances:
instance Integral a => Num (GHC.Real.Ratio a)
-- Defined in ‘GHC.Real’
instance Num Integer -- Defined in ‘GHC.Num’
instance Num Double -- Defined in ‘GHC.Float’
...plus three others
In the expression: 2
In the expression: [2 .. 100]
In a stmt of a list comprehension: x <- [2 .. 100]
train.hs:84:49:
No instance for (Integral t0) arising from a use of ‘round’
The type variable ‘t0’ is ambiguous
Relevant bindings include
x :: t0 (bound at train.hs:84:15)
primes :: [t0] (bound at train.hs:84:1)
Note: there are several potential instances:
instance Integral Integer -- Defined in ‘GHC.Real’
instance Integral Int -- Defined in ‘GHC.Real’
instance Integral Word -- Defined in ‘GHC.Real’
In the expression: round (x / 2)
In the expression: [2 .. round (x / 2)]
In a stmt of a list comprehension: f <- [2 .. round (x / 2)]
train.hs:84:57:
No instance for (Fractional t0) arising from a use of ‘/’
The type variable ‘t0’ is ambiguous
Relevant bindings include
x :: t0 (bound at train.hs:84:15)
primes :: [t0] (bound at train.hs:84:1)
Note: there are several potential instances:
instance Integral a => Fractional (GHC.Real.Ratio a)
-- Defined in ‘GHC.Real’
instance Fractional Double -- Defined in ‘GHC.Float’
instance Fractional Float -- Defined in ‘GHC.Float’
In the first argument of ‘round’, namely ‘(x / 2)’
In the expression: round (x / 2)
In the expression: [2 .. round (x / 2)]
train.hs:84:65:
No instance for (Eq t0) arising from a use of ‘==’
The type variable ‘t0’ is ambiguous
Relevant bindings include
f :: t0 (bound at train.hs:84:40)
x :: t0 (bound at train.hs:84:15)
primes :: [t0] (bound at train.hs:84:1)
Note: there are several potential instances:
instance (Eq a, Eq b) => Eq (Either a b)
-- Defined in ‘Data.Either’
instance forall (k :: BOX) (s :: k). Eq (Data.Proxy.Proxy s)
-- Defined in ‘Data.Proxy’
instance (GHC.Arr.Ix i, Eq e) => Eq (GHC.Arr.Array i e)
-- Defined in ‘GHC.Arr’
...plus 28 others
In the expression: 0 == rem x f
In a stmt of a list comprehension: 0 == rem x f
In the first argument of ‘null’, namely
‘[f | f <- [2 .. round (x / 2)], 0 == rem x f]’
Failed, modules loaded: none.
I'm sorry, but I rechecked my code, but it just seems fine, considering the syntax.
However, when I put the same code in my ghci>, the result is bit different:
Prelude> let primes = [x | x <- [2..100], null [f | f <- [2..round (x/2)], 0 == rem x f]]
Prelude> primes
<interactive>:12:1:
No instance for (Integral t0) arising from a use of ‘it’
The type variable ‘t0’ is ambiguous
Note: there are several potential instances:
instance Integral Integer -- Defined in ‘GHC.Real’
instance Integral Int -- Defined in ‘GHC.Real’
instance Integral Word -- Defined in ‘GHC.Real’
In the first argument of ‘print’, namely ‘it’
In a stmt of an interactive GHCi command: print it
I would be glad if I get to know my mistake.
Same code from my textbook:----------------
- I had to declare
primesas integer list like this:
primes :: [Integer]
But why did this problem did not occur for other functions?
Like this function just worked fine. I had not declare listCom's type:
listCom = [2*x | x <- [1..50], rem x 3 == 0]
- I have to modify the draw list of factors by adding
fromIntegralwithx/2:
f <- [2..round (fromIntegral x/2)]
Now why I have to state that even if I have already converted x/2 to integer using round?
Edit:
If there is problem with [2..round (x/2)], then does this code work perfectly fine:
ii = 33
samLis = [2..round (ii/2)]
It is not converting
x/2, it is convertingx. Indeed,(/) :: Fractional a => a -> a -> aworks with fractional numbers, and anIntegeror any other integral number is not aFractionalnumber, so without thefromIntegral, it requires thatxis bothFractional(because you use it inx/2), andIntegral(since you use it inrem :: Integral a => a -> a -> a), while one can technically "fabricate" such type, it makes no sense: a number type is either integral, or fractional, not both.If you thus implement this as:
we're done.
The prime check is however far from efficient: we can for example already stop at √n for checking.
Because there it uses type defaulting rules, will use
Integer, and since you don't usexin any function that forces a type constraint it can not satisfy, there is no problem.