2012-06-07 22 views
5

tengo el siguiente código que implementa la criba de Eratóstenes:Filtrado de una lista infinita en Haskell

primes :: [Int] 
primes = primes' [2..] 

primes' :: [Int] -> [Int] 
primes' [] = [] 
primes' (p:ps) = p:(primes' [p' | p' <- ps, not (p' `isMultiple` p)]) 

a `isMultiple` b = (a `mod` b) == 0 

main = print (sum (primes' [2..100000])) 

me gustaría cambiar principal a algo así como

main = print (sum [p | p <- primes, p < 100000])) 

Como es lógico, esta cuelga debido debe comparar p contra cada elemento de los primos de lista infinita. Como sé que los números primos están en orden creciente, ¿cómo trunco ​​la lista infinita tan pronto como encuentre un elemento que exceda mi límite superior?

p.s. En teoría, primos 'filtra la lista de entrada para devolver una lista de primos. Sé que habrá algunos problemas si empiezo la lista en algo distinto a 2. Todavía estoy trabajando en cómo abordar este problema por mi cuenta, así que por favor no se preocupen. Gracias ;-)

+5

Por cierto, este no es el verdadero Tamiz de Erastóstenes. Verifique [este excelente artículo] (www.cs.hmc.edu/~oneill/papers/Sieve-JFP.pdf). – hugomg

+0

Gracias por el artículo. No he terminado de leerlo todavía, pero parece interesante hasta ahora. –

Respuesta

18

En casos como este donde sabes que una vez que el predicado devuelve falso para un elemento, nunca volverá a ser verdadero para un elemento posterior, puedes reemplazar filter con takeWhile, que deja de tomar elementos tan pronto como el predicado devuelve falso por primera vez.

+0

Gracias. Voy a investigar eso. –

Cuestiones relacionadas