I’m trying to make function primes which is a list of prime numbers, but somehow I have failed. The compiler throws an error I don’t know how to resolve:
Error:
Ambiguous type variable 'a0'
Code:
candidates :: [Integer]
candidates = [2]++[3,5..]
primes :: [Integer]
primes = filter is_prime candidates
is_prime :: Integer -> Bool
is_prime candidate
| candidate == 1 = False
| candidate == 2 = True
| candidate == 3 = True
| otherwise = r_is_prime candidate 0
-- r as recursive
r_is_prime :: Integer -> Integer -> Bool
r_is_prime candidate order
| n_th_prime >= max_compared_prime = True
| candidate `mod` n_th_prime == 0 = False
| otherwise = if (r_is_prime candidate (order+1) ) then True else False
where
n_th_prime = candidates !! fromIntegral(order)
-- this is the line that throws an error...
max_compared_prime = fromIntegral ( ceiling ( fromIntegral ( sqrt ( fromIntegral candidate))))
In
you have a
fromIntegraltoo much.sqrthas typeso the result of
sqrtis not a member of anIntegraltype. And the result ofceilingis anIntegraltype, so the lastfromIntegralis superfluous (but does not harm).is all you need in that line.
Note, however, that
means that to test against the
n-th candidate prime, the list of candidates has to be traversed until then-th prime has been reached. Thus testing against then-th candidate is O(n) here instead of O(1) [Well, assuming that numbers are bounded] which a single division is.A more efficient trial division only tries primes for the division and remembers where in the list of primes it was when it goes on to the next prime. For example
Just traverses the list of primes in order to do the trial division, hence going from one prime to the next is a simple step in the list.