如果要折叠列表,我会看到四种方法。

从列表的右边折叠,在右边有递归项


foldrr :: (a -> b -> b) -> b -> [a] -> b
foldrr step zero (x:xs) = step x (foldrr step zero xs)
foldrr _    zero []     = zero

从列表的右边折叠,在左边有递归项


foldrl :: (a -> b -> a) -> a -> [b] -> a
foldrl step zero (x:xs) = step (foldrl step zero xs) x
foldrl _    zero []     = zero

从列表的左边折起,在右边的递归项


foldlr :: (a -> b -> b) -> b -> [a] -> b
foldlr step zero (x:xs) = foldlr step (step x zero) xs
foldlr _    zero []     = zero

从列表的左边折起,在左边有递归项


foldll :: (a -> b -> a) -> a -> [b] -> a
foldll step zero (x:xs) = foldll step (step zero x) xs
foldll _    zero []     = zero

这些折叠中只有两个折叠成为foldrfoldl成为Prelude。是否有任何理由只包括两折,为什么要这两折呢?

最佳答案

foldrlfoldlr不会增加任何表达能力:它们与其他两个折叠相同,但是折叠功能被翻转了。

foldrl f = foldr (flip f)
foldlr f = foldl (flip f)

-- Or this, if you prefer
foldrl = foldr . flip
foldlr = foldl . flip

但是用foldl定义foldr并不是那么容易,因此同时提供它们都是有用的。

关于haskell - 缺失的褶皱,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/44869048/

10-13 06:04