Defining foldl in terms of foldr

后端 未结 2 1016
北荒
北荒 2021-01-20 03:24
myFoldl :: (a -> b -> a) -> a -> [b] -> a

myFoldl f z xs = foldr step id xs z
    where step x g a = g (f a x)

I am currently readi

2条回答
  •  野趣味
    野趣味 (楼主)
    2021-01-20 03:59

    The thing will be become obvious when to expand the expression of foldr step id xs z:

    As Adam Smith said in the comments:

    foldr step id xs z = (foldr step id xs) z

    Consider foldr step id xs firstly

    foldr step id xs
    = x1 `step` (foldr step id xs1)
    = x1 `step` (x2 `step` (foldr step id xs2))
    ...
    = x1 `step` (x2 `step` ... (xn `step` (foldr step id []))...)
    = x1 `step` (x2 `step` ... (xn `step` id)...)
    

    where

    xs = (x1:xs1)
    xs1 = (x2:xs2), xs = (x1:x2:xs2) 
    ....
    xsn = (xn:[]), xs = (x1:x2...xsn) respectively 
    

    Now, apply above function with argument z, i.e.

    (x1 `step` (x2 `step` ... (xn `step` id)...)) z
    

    and let

    g = (x2 `step` ... (xn `step` id)...) 
    

    gives

    (x1 `step` g) z
    

    i.e.

    (step x1 g) z
    

    and now apply the where part of foldl:

    where step x g a = g (f a x)

    gives

    (step x1 g) z = step x1 g z = g (step z x1)
    

    where

    g (step z x1) = (x2 `step` (x3 step ... (xn `step` id)...) (step z x1)
    

    let

    g' = (x3 step ... (xn `step` id)...)
    

    gives

    (x2 `step` g') (step z x1)
    = step x2 g' (step z x1)
    = g' (step (step z x1) x2))
    = (x3 step ... (xn `step` id)...) (step (step z x1) x2))
    

    repeats the same steps, finally we have,

    (xn `step` id) (step ....(step (step z x1) x2)....)
    = step xn id (step ....(step (step z x1) x2)....)
    = id (step (step ....(step (step z x1) x2)....) xn)
    = (step (step ....(step (step z x1) x2)....) xn)
    = foldl step z xs
    

    and now, it is obvious that why use id function. finally, see why

    foldl step z xs = (step (step ....(step (step z x1) x2)....) xn)
    

    initial case:

    foldl step z' [] = z'
    

    recursive case:

    foldl step z (x1:xs1) 
    = foldl step (step z x1) xs1
    = foldl step (step (step z x1) x2) xs2
    ...
    = foldl step (step (step ....(step (step z x1) x2)....) xn) []
    = (step (step ....(step (step z x1) x2)....) xn)
    

    where

    z' = (step (step ....(step (step z x1) x2)....) xn) in initial case
    

    Just same as above.

提交回复
热议问题