0

I need to make a function primes which is not taking any parameter and returns me the list of all the prime numbers. This is the code I came up with:

isqrt = floor . sqrt . fromIntegral
primes = 2:3:(primes' 4)
primes' n = 
        if (all(\y-> (y < isqrt n) && ((n `mod` y) /= 0)) primes) 
        then
           n:primes' (n+1)
        else
           primes` (n+1)

The program prints only 2:3: and then it stops. Shouldn't this work because of the lazy evaluation? (by taking primes as the list constructed until now and be able to see if my current number is divisible by any of the numbers in that list and then if yes append it and continue the recursion, if not keep going).

Can anyone please point me towards my mistake?

1 Answers1

2

Some points: technically, your program does not print anything. Second, it does not even compile — notice a typo in the last line.

As for your question: in your function you call all on the infinite list primes, and all tries to traverse all of it — that's why the program hangs. You need to take only the elements you need from primes and only then apply all. For example:

isqrt = floor . sqrt . fromIntegral
primes = 2:3:(primes' 4)
primes' n =
        if (all (\y-> (n `mod` y) /= 0) (takeWhile (<= isqrt n) primes))
        then
           n:primes' (n+1)
        else
           primes' (n+1)

main = print (take 5 primes)

Edit: using takeWhile as @behzad.nouri suggests.

fjarri
  • 9,546
  • 39
  • 49
  • [`takeWhile`](https://hackage.haskell.org/package/base-4.8.1.0/docs/Prelude.html#v:takeWhile) would fit better than `fst $ break` – behzad.nouri Nov 18 '15 at 00:10