Что я понял о foldl и foldr в списках:
Если мы вправо сбрасываем [0,1,2,3] с функцией s и начальным аккумулятором a , мы делаем это:
f 0 (f 1 (f 2 (f 3 a)))
Если мы оставили фолд [0,1,2,3] с функцией s и начальным аккумулятором a , мы делаем это:
f (f (f (f 0 a) 1) 2) 3)
Данный :
elem_r :: (Eq a) => a -> [a] -> Bool
elem_r y ys = foldr (\x acc -> if x == y then True else acc) False ys
и
elem_l :: (Eq a) => a -> [a] -> Bool
elem_l y ys = foldl (\acc x -> if x == y then True else acc) False ys
Мне кажется очевидным, что elem_r 3 [0..]
вычислит то, что действительно должно, и вернет True, как только будет достигнуто значение 3.
f 0 (f 1 (f 2 (f 3 (...)))
В то время как elem_l 3 [0..]
необходимо оценить все приложение вложенных функций, прежде чем возвращать результат.
f (f (f (f (f 0 3) 1) 2) 3) ...)
Теперь мой вопрос:
В конкретном случае elem_l 0 [0..]
искомым элементом является первый элемент списка.
В этом выражении: f (f (f (f (f 0 0) 1) 2) 3) ...)
Самая внутренняя функция (f 0 0) может быть немедленно оценена как «Истина». Почему Haskell продолжает оценивать остальные вложенные функции?
if x == y then True else acc
мог бы быть немного аккуратнее, чемacc || x == y
, имхо. - person Bartek Banachewicz   schedule 09.01.2015x == y || acc
. - person Will Ness   schedule 10.01.2015