Haskell - Dlaczego to rozumienie listy zwraca nieskończoną listę?

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

Naprawdę nie rozumiem, dlaczego to daje

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

I nie znajduje końca

Odpowiedzi

14 chi Jan 15 2021 at 23:37

Semantyka

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

polega na wypróbowaniu wszystkich elementów [1..]i zachowaniu tych, które spełniają warunki filtra 3*x<20.

Człowiek może zobaczyć, że po pierwszym, xktóry fałszuje warunek, nie ma sensu próbować wszystkich większych wartości, ale Haskell i tak je wypróbuje i utknie w czymś w rodzaju nieskończonej pętli.

Dzieje się tak, ponieważ w ogólnym przypadku warunek mógłby się ponownie spełnić, np

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

Generalnie nierozstrzygalne jest wykrycie, czy nie ma już rozwiązań, więc Haskell, jak każdy inny język programowania, nie może zdecydować się na zatrzymanie się po ostatnim rozwiązaniu.

Jeśli chcesz, aby lista zatrzymywała się po pierwszej wartości, która nie spełnia warunku filtrowania, użyj takeWhile:

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