如果要折叠列表,我会看到四种方法。
从列表的右边折叠,在右边有递归项
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
这些折叠中只有两个折叠成为
foldr
和foldl
成为Prelude。是否有任何理由只包括两折,为什么要这两折呢? 最佳答案
foldrl
和foldlr
不会增加任何表达能力:它们与其他两个折叠相同,但是折叠功能被翻转了。
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/