问题
I'm trying to create a function definition for the function all
using foldr
. p
is the predicate. I know this can be done:
all p = and . foldr (\x xs -> p x : xs) []
But what I want to do is to shift the function and
into the foldr
equation. Can this be done?
I've tried the following, which all failed to work:
all p = foldr (\x p -> \ys -> and (p x) ys) True
all p = foldr (\x and -> (\ys -> (p x and ys))) True
all p = foldr (\x ys -> and . (p x) ys) True
Am I falling short in my understanding of how to apply foldr
?
回答1:
We have
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
because folding replaces each constructor with the specified combination operation (aka reducer), and replacing a cons of an element with a cons of a modified element, and then replacing that cons with (&&)
, is just replacing a cons of an element with the (&&)
of a modified element right away:
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
In other words, folds compose by fusing their reducer functions, and reducer functions fuse by replacing the {constructors they use} with the next fold's reducer in the chain of folds, so that their corresponding transducers compose (as in Clojure's transducers); thus,
= foldr (reducingWith (&&)) True
. foldr ((mapping p) (:)) []
= foldr ((mapping p) (reducingWith (&&))) True
= foldr ((mapping p . reducingWith) (&&) ) True
-- first map p, then reduce with (&&)
for the appropriate definitions of reducingWith
and 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)
来源:https://stackoverflow.com/questions/62851579/haskell-creating-a-function-definition-for-the-function-all-using-foldr