Why can you reverse list with foldl, but not with foldr in Haskell

前端 未结 6 1909
栀梦
栀梦 2021-02-04 09:49

Why can you reverse a list with the foldl?

reverse\' :: [a] -> [a]
reverse\' xs = foldl (\\acc x-> x : acc) [] xs

But this one gives me a

6条回答
  •  刺人心
    刺人心 (楼主)
    2021-02-04 10:15

    A slight but significant generalization of several of these answers is that you can implement foldl with foldr, which I think is a clearer way of explaining what's going on in them:

    myMap :: (a -> b) -> [a] -> [b]
    myMap f = foldr step []
        where step a bs = f a : bs
    
    -- To fold from the left, we:
    --
    -- 1. Map each list element to an *endomorphism* (a function from one
    --    type to itself; in this case, the type is `b`);
    --
    -- 2. Take the "flipped" (left-to-right) composition of these
    --    functions;
    --
    -- 3. Apply the resulting function to the `z` argument.
    --
    myfoldl :: (b -> a -> b) -> b -> [a] -> b
    myfoldl f z as = foldr (flip (.)) id (toEndos f as) z
        where
          toEndos :: (b -> a -> b) -> [a] -> [b -> b]
          toEndos f = myMap (flip f)
    
    myReverse :: [a] -> [a]
    myReverse = myfoldl (flip (:)) []
    

    For more explanation of the ideas here, I'd recommend reading Tom Ellis' "What is foldr made of?" and Brent Yorgey's "foldr is made of monoids".

提交回复
热议问题