В настоящее время я читаю "Программирование в Хаскелле" Грэма Хаттона.
В с .40 представлен тест на игрушку:
factors :: Int -> [Int]
factors n = [x | x <- [1..n], n `mod` x == 0]
prime :: Int -> Bool
prime n = factors n == [1,n]
Далее автор объясняет, как
", считая, что число не является простым, не требует функции чтобы произвести все его факторы, потому что при ленивой оценке результат
False
возвращается, как только любой фактор, отличный от одного или сам номер получается"
Как кто-то из C и Java, я нахожу это шокирующим. Я ожидал, что вызов factors
завершится первым, сохраните результат в стеке и передайте элемент управления вызывающей функции. Но, по-видимому, здесь выполняется совсем другая программа: должен быть цикл над пониманием списка в factors
, и проверка равенства в prime
проверяется на каждый новый элемент, добавленный в список факторов.
Как это возможно? Разве это не затрудняет рассуждение о порядке выполнения программы?