Haskell - Perché questa comprensione della lista restituisce una lista infinita?

Jan 15 2021
[3 * x | x <- [1 ..], 3 * x < 20]

Non capisco davvero perché questo dia

[3,6,9,12,15,18

E non trova una fine

Risposte

14 chi Jan 15 2021 at 23:37

La semantica di

[3 * x | x <- [1 ..], 3 * x < 20]

è provare tutti gli elementi [1..]e mantenere quelli che soddisfano la condizione del filtro 3*x<20.

Un umano può vedere che dopo il primo xche falsifica la condizione non ha senso provare tutti i valori più grandi, ma Haskell li proverà comunque e rimarrà bloccato su una sorta di loop infinito.

Questo perché, nel caso generale, la condizione potrebbe diventare nuovamente vera, ad es

[3 * x | x <- [1 ..], 3 * x < 20 || x == 1000000 ]

In generale è indecidibile rilevare se non ci sono più soluzioni, quindi Haskell, come qualsiasi altro linguaggio di programmazione, non può scegliere di fermarsi dopo l'ultima soluzione.

Se vuoi che l'elenco si fermi dopo il primo valore che non soddisfa la condizione di filtraggio, usa takeWhile:

takeWhile (< 20) [3 * x | x <- [1 ..]]