У нас есть
all p = and
. foldr (\x xs -> p x : xs) []
= foldr (&&) True -- {y : ys} -> y && {ys} 2-3
. foldr (\x xs -> p x : xs) [] -- {x , xs} -> p x : {xs} 1-2
= foldr (\x xs -> p x && xs) True -- {x , xs} -> p x && {xs} 1---3
, потому что сворачивание заменяет каждый конструктор указанной комбинированной операцией (также известной как reducer ) и заменяет cons элемента на cons измененного элемента, а затем замена этого cons на (&&)
, просто заменяет cons элемента на (&&)
измененного element сразу:
a : ( b : ( c : ( d : ( ... )))) _OR_ [] -- | | 1
-- | |
p a : (p b : (p c : (p d : ( ... )))) _OR_ [] -- ↓ | | 2
-- | |
p a && (p b && (p c && (p d && ( ... )))) _OR_ True -- ↓ ↓ 3
Другими словами, свертки объединяются путем объединения своих функций-редукторов, а функции-редукторы объединяются, заменяя {конструкторы, которые они используют} редуктором следующей свертки в цепочке складок, так что их соответствующие преобразователи составляют (как в преобразователях Clojure); таким образом,
= foldr (reducingWith (&&)) True
. foldr ((mapping p) (:)) []
= foldr ((mapping p) (reducingWith (&&))) True
= foldr ((mapping p . reducingWith) (&&) ) True
-- first map p, then reduce with (&&)
для соответствующих определений reducingWith
и mapping
:
reducingWith cons x xs = cons x xs
mapping f cons x xs = cons (f x) xs
filtering p cons x xs | p x = cons x xs
| otherwise = xs
concatting t cons x xs = foldr cons xs (t x)