丢失的折叠

mar*_*tin 9 recursion language-features haskell fold haskell-prelude

如果你想折叠一个列表,我会看到四种方法.

从列表右侧折叠,右侧是递归项

foldrr( - )100 [1..10] = 1 - (2 - (3 - (4 - (5 - (6 - (7 - (8 - (9 - (10 - (100)))))))) )))= 95

foldrr :: (a -> b -> b) -> b -> [a] -> b
foldrr step zero (x:xs) = step x (foldrr step zero xs)
foldrr _    zero []     = zero
Run Code Online (Sandbox Code Playgroud)

从列表右侧折叠,左侧是递归项

foldrl( - )100 [1..10] =(((((((((((100) - 10) - 9) - 8) - 7) - 6) - 5) - 4) - 3) - 2 ) - 1 = 45

foldrl :: (a -> b -> a) -> a -> [b] -> a
foldrl step zero (x:xs) = step (foldrl step zero xs) x
foldrl _    zero []     = zero
Run Code Online (Sandbox Code Playgroud)

从列表左侧折叠,右侧是递归项

foldlr( - )100 [1..10] = 10 - (9 - (8 - (7 - (6 - (5 - (4 - (3 - (2 - (1 - (100))))))) )))= 105

foldlr :: (a -> b -> b) -> b -> [a] -> b
foldlr step zero (x:xs) = foldlr step (step x zero) xs
foldlr _    zero []     = zero
Run Code Online (Sandbox Code Playgroud)

从列表左侧折叠,左侧是递归项

foldll( - )100 [1..10] =(((((((((((100) - 1) - 2) - 3) - 4) - 5) - 6) - 7) - 8) - 9 ) - 10 = 45

foldll :: (a -> b -> a) -> a -> [b] -> a
foldll step zero (x:xs) = foldll step (step zero x) xs
foldll _    zero []     = zero
Run Code Online (Sandbox Code Playgroud)

这些折叠中只有两个成为Prelude as foldrfoldl.有没有理由只包括两个折叠,为什么这两个?

ama*_*loy 17

foldrl并且foldlr不添加任何表现力:它们与其他两个折叠相同但折叠功能翻转.

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

-- Or this, if you prefer
foldrl = foldr . flip
foldlr = foldl . flip
Run Code Online (Sandbox Code Playgroud)

但就定义foldl来说并不容易foldr,因此提供它们都是有用的.

  • @ftor因为`-`遵循身份`(ab)-c =(ac)-b`.一般来说,所有四个结果可能不同,但不是`-`. (2认同)
  • @ftor,有这种性质的一般认同:`foldl fb xs = foldr(翻转f)b(反向xs)`.对于有限列表,'foldr cn xs = foldl(flip c)n(reverse xs)`也是如此. (2认同)
  • 另一个总是持有:`foldr cn(reverse xs)= foldl(flip c)n xs`. (2认同)