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

前端 未结 6 1814
栀梦
栀梦 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:31

    This is what foldl op acc does with a list with, say, 6 elements:

    (((((acc `op` x1) `op` x2) `op` x3) `op` x4) `op` x5 ) `op` x6
    

    while foldr op acc does this:

    x1 `op` (x2 `op` (x3 `op` (x4 `op` (x5 `op` (x6 `op` acc)))))
    

    When you look at this, it becomes clear that if you want foldl to reverse the list, op should be a "stick the right operand to the beginning of the left operand" operator. Which is just (:) with arguments reversed, i.e.

    reverse' = foldl (flip (:)) []
    

    (this is the same as your version but using built-in functions).

    When you want foldr to reverse the list, you need a "stick the left operand to the end of the right operand" operator. I don't know of a built-in function that does that; if you want you can write it as flip (++) . return.

    reverse'' = foldr (flip (++) . return) []
    

    or if you prefer to write it yourself

    reverse'' = foldr (\x acc -> acc ++ [x]) []
    

    This would be slow though.

提交回复
热议问题