Haskell: ¿Por qué la comprensión de esta lista devuelve una lista infinita?
[3 * x | x <- [1 ..], 3 * x < 20]
Realmente no entiendo por qué esto da
[3,6,9,12,15,18
Y no encuentra un final
Respuestas
La semántica de
[3 * x | x <- [1 ..], 3 * x < 20]
es probar todos los elementos de [1..]
y mantener aquellos que satisfagan la condición del filtro 3*x<20
.
Un humano puede ver que después del primero x
que falsifica la condición no tiene sentido probar todos los valores más grandes, pero Haskell los probará de todos modos y se quedará atascado en una especie de bucle infinito.
Esto se debe a que, en el caso general, la condición podría volverse verdadera una vez más, p. Ej.
[3 * x | x <- [1 ..], 3 * x < 20 || x == 1000000 ]
En general es indecidible detectar si no hay más soluciones, por lo que Haskell, como cualquier otro lenguaje de programación, no puede optar por detenerse después de la última solución.
Si desea que la lista se detenga después del primer valor que no satisface la condición de filtrado, utilice takeWhile
:
takeWhile (< 20) [3 * x | x <- [1 ..]]