O algoritmo mais eficiente para encontrar números primos, é o Crivo de Eratóstenes (assim chamado em honra ao matemático grego que o inventou), que permite obter todos os números primos até um determinados valor n. A ideia é a seguinte :
crivo [] = []
crivo (x:xs) = x : crivo [ n | n <- xs , n `mod` x /= 0 ]
primosAte n = crivo [2..n]
Lista infinita de números primos.
primos = crivo [2..]
O Teorema Fundamental da Aritmética (enunciado pela primeira vez por Euclides) diz que qualquer número inteiro (maior que 1) pode ser decomposto num produto de números primos.
Esta decomposição é única a menos de uma permutação.
Exemplo : Com o auxílio da lista de números primos, podemos definir uma função que dado um número (maior do que 1), calcula a lista dos seus fatores primos.
fatoriza :: Integer -> [Integer]
fatoriza n = aux n primos
where aux l _ = []
aux n (n:xs)
| n `mod` x /= 0 = aux n xs
| otherwise = x : aux (n `div` x) (x:xs)
> fatoriza 94753
[19,4987]
> fatoriza 9475312
[2,2,2,2,7,11,7691]