2012-06-07 21 views
5

Mam następujący kod, który implementuje Sito Eratostenesa:Filtrowanie listy nieskończoną w 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])) 

chciałbym zmienić główny coś jak

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

Nic dziwnego, że to wisi, bo musi porównać p względem każdego elementu nieskończonej liczby liczb pierwszych list. Ponieważ wiem, że liczby pierwsze są w porządku, jak mogę skrócić nieskończoną listę, gdy tylko znajdę element przekraczający mój górny limit?

p.s. Teoretycznie, liczby pierwsze filtrują listę wejściową, aby zwrócić listę liczb pierwszych. Wiem, że będą pewne problemy, jeśli zacznę listę na czymś innym niż 2. Nadal pracuję nad tym, jak rozwiązać ten problem na własną rękę, więc proszę nie spoilery. Dzięki ;-)

+5

Nawiasem mówiąc, to nie jest prawdziwa sito Erastostenesa. Sprawdź [ten fajny artykuł] (www.cs.hmc.edu/~oneill/papers/Sieve-JFP.pdf). – hugomg

+0

Dzięki za artykuł. Jeszcze nie skończyłem jej czytać, ale do tej pory wygląda to interesująco. –

Odpowiedz

18

W takich przypadkach, gdzie wiesz, że kiedyś predykat zwraca wartość false dla danego elementu, nie będzie kiedykolwiek wrócić prawdziwe dla późniejszego elementu, można zastąpić filter z takeWhile, który przestaje wykonywać elementy jak najszybciej ponieważ predykat po raz pierwszy zwraca wartość false.

+0

Dziękuję. Zajrzę do tego. –