У меня есть код Haskell, который делает работает правильно в бесконечном списке, но я не понимаю , почему он может сделать это успешно. (Я изменил свой исходный код, который не обрабатывал бесконечные списки, - чтобы включить что-то из какого-либо другого кода в Интернете, и вдруг я вижу, что он работает, но не знает почему).Почему этот код Haskell успешно работает с бесконечными списками?
myAny :: (a -> Bool) -> [a] -> Bool
myAny p list = foldr step False list
where
step item acc = p item || acc
Мое понимание foldr является то, что он будет цикл через каждый элемент списка (и, возможно, что понимание является неполным). Если это так, не имеет значения, как выражается функция «шаг» ... код не должен обрабатывать бесконечные циклы.
Однако следующие работы:
*Main Data.List> myAny even [1..]
True
Пожалуйста, помогите мне понять: почему ??
Кроме того, вы можете убедиться, что код не вычисляет более двух элементов с помощью: 'myAny p list = foldr (\ ia -> trace (show i) (pi || a))' - который будет показывать только '1 2 True' – viraptor
Вау, это был ОЧЕНЬ хороший ответ на открытие глаза. Прежде всего, я не начинал с определения foldr передо мной. Я предположил, что его код будет использовать расширенные функции, которые я пока не знаю, поэтому я рассматривал его только как последнее средство. Ваш ответ заставил меня взглянуть, и это многое проясняет. foldr сам использует «обычную старую» структурную рекурсию. Мне нравится, как ты сломал это. Благодарю. –
BTW, является || полностью строгий в своем первом аргументе, или он просто «отдаёт предпочтение» своему первому аргументу? Например, что, если arg 2 уже был оценен, но arg 1 все еще был просто тонким? И скажем, arg 2 был ложным. Будет ли Haskell короткое замыкание в противоположном направлении? Благодарю. –