Haskell - Tại sao việc hiểu danh sách này lại trả về một danh sách vô hạn?

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

Tôi không thực sự hiểu tại sao điều này mang lại

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

Và không tìm thấy kết thúc

Trả lời

14 chi Jan 15 2021 at 23:37

Ngữ nghĩa của

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

là thử tất cả các phần tử của [1..]và giữ những phần tử thỏa mãn điều kiện bộ lọc 3*x<20.

Một người có thể thấy rằng sau lần đầu tiên xlàm sai điều kiện thì chẳng ích gì khi thử tất cả các giá trị lớn hơn, nhưng Haskell dù sao cũng sẽ thử những giá trị đó và bị mắc kẹt trong một loại vòng lặp vô hạn.

Điều này là do, trong trường hợp chung, điều kiện có thể trở thành đúng một lần nữa, ví dụ:

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

Nói chung, không thể quyết định được nếu không còn giải pháp nào nữa, vì vậy Haskell, giống như bất kỳ ngôn ngữ lập trình nào khác, không thể chọn dừng lại sau giải pháp cuối cùng.

Nếu bạn muốn danh sách dừng lại sau giá trị đầu tiên không thỏa mãn điều kiện lọc, hãy sử dụng takeWhile:

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