Para ayudarme a aprender Haskell, estoy trabajando en los problemas del Proyecto Euler. Después de resolver cada problema, compruebo mi solución contra la wiki de Haskell en un intento de aprender mejores prácticas de codificación. Aquí es the solution-problem 3:¿Por qué este fragmento de código de Haskell no es infinitamente recursivo?
primes = 2 : filter ((==1) . length . primeFactors) [3,5..]
primeFactors n = factor n primes
where
factor n (p:ps)
| p*p > n = [n]
| n `mod` p == 0 = p : factor (n `div` p) (p:ps)
| otherwise = factor n ps
problem_3 = last (primeFactors 317584931803)
Mi lectura ingenua de esto es que primes
se define en términos de primeFactors
, que se define en términos de primes
. Así evaluar primeFactors 9
seguiría este proceso:
- Evaluar
factor 9 primes
. - Pregunte
primes
para su primer elemento, que es 2. - Pregunte
primes
para su siguiente elemento. - Como parte de este proceso, evalúe
primeFactors 3
. - Pregunte
primes
para su primer elemento, que es 2. - Pregunte
primes
para su siguiente elemento. - Como parte de este proceso, evalúe
primeFactors 3
. - ...
En otras palabras, los pasos 2-4 sería repetir infinitamente. Claramente estoy equivocado, ya que el algoritmo termina. ¿Qué error estoy haciendo aquí?
porque, como las respuestas aquí dicen, 'primeFactors' solo accede a' primos' hasta que el cuadrado de un primo excede el número que se está probando, ese código es equivalente a 'primos = 2: [n | n <- [3 ..], todo ((> 0) .rem n) $ takeWhile ((<= n). (^ 2)) primos] 'que claramente no es bucle. –