Haskell - creating a function definition for the function `all` using foldr

旧巷老猫 提交于 2021-02-05 12:30:55

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!