Haskell:
primes = filterPrime [2..]
where filterPrime (p:xs) = p : filterPrime [x | x <- xs, x `mod` p /= 0] primes = filterPrime [2..]
where filterPrime (p:xs) = p : filterPrime [x | x <- xs, x `mod` p /= 0] primes = 2 : filter isPrime [3..]
isPrime x = all (\p -> x `mod` p /= 0) $ takeWhile (\p -> p * p <= x) primes
primes is a list of prime numbers. It is defined as number 2 and numbers 3,4,5... for which isPrime is True.isPrime is a function that checks that x is a prime number by taking numbers whose squares don't exceed x from... primes list... and then making sure they all divide x with a reminder.
It only works because isPrime never touches an unevaluated element of primes list. Otherwise, the program would loop.
Instead you should use the Sieve of Eratosthenes algorithm. Unfortunately this algorithm is easier to implement in an imperative, eager fashion than in a lazy, functional fashion.
See the paper "The Genuine Sieve of Eratosthenes" for more details: https://www.cs.hmc.edu/~oneill/papers/Sieve-JFP.pdf
λ(λ1 (1((λ1 1)(λλλ1(λλ1)((λ4 4 1((λ1 1)(λ2(1 1))))(λλλλ1 3(2(6 4)))))(λλλ4(1 3)))))(λλ1(λλ2)2)
[1] https://tromp.github.io/cl/cl.html