Потому что foldl
всегда должен проходить список аргументов в целом , прежде чем начать сокращать его до конечного результата; и foldl'
перебирает список аргументов в целом , сокращая его до конечного результата:
foldl f z [x1, x2, ..., xn] == foldl f (f z x1) [x2, ..., xn]
foldl' f z [x1, x2, ..., xn] == z `seq` foldl' f (f z x1) [x2, ..., xn]
-- thus,
foldl f z1 [x1, x2, ..., xn] == f (...(f (f z1 x1) x2)...) xn
foldl' f z1 [x1, x2, ..., xn] == z1 `seq` (let z2 = f z1 x1 in
z2 `seq` (let z3 = f z2 x2 in
z3 `seq` (... `seq` (f zn xn)...)))
Вы хотели иметь возможность остановить обход, который выполняется с помощью вправо сворачивание с нестрогой сокращающей функцией:
present y xs = foldr myfunc False xs
where
myfunc x r = y == x || r
Поскольку myfunc
не является строгим во втором аргументе, foldr myfunc
исследует список xs
в слева направо порядок,
foldr myfunc False (x:xs) = myfunc x (foldr myfunc False xs)
= y == x || foldr myfunc False xs