List.foldr或List.foldl与Elixir的理解

时间:2017-09-08 14:37:50

标签: elixir

我正在阅读Elixir文档并且遇到了这个' foldr' Elixir List模块的功能。我真的很难理解它。以下是该文档所说的内容:

DOCS

Folds (reduces) the given list from the right with a function. Requires an accumulator.

iex> List.foldr([1, 2, 3, 4], 0, fn(x, acc) -> x - acc end)
-2

所以这应该返回-2。但是当我读到它时,我似乎认为它每次都试图减去0,如果是这样的话,我们怎么得-2?我显然不理解累加器,有人可以为我分解它吗?

3 个答案:

答案 0 :(得分:3)

理解这些函数如何工作的最简单方法是坚持使用所有参数进行IO.puts调用。

iex(1)> List.foldr([1, 2, 3, 4], 0, fn(x, acc) -> IO.puts "#{x} - #{acc} = #{x - acc}"; x - acc end)
4 - 0 = 4
3 - 4 = -1
2 - -1 = 3
1 - 3 = -2
-2

因此,在第一次迭代中,x为4,acc为0,我们得到x - acc = 4 - 0 = 4。最后,我们最终得到-2

答案 1 :(得分:2)

  

使用函数从右侧折叠(缩小)给定列表。需要一个累加器。

这意味着列表是从右边迭代的,例如。 G。传递的函数按以下顺序调用4次:

fn(4, 0) -> 4 - 0 end
fn(3, 4) -> 3 - 4 end
fn(2, -1) -> 2 + 1 end
fn(1, 3) -> 1 - 3 end

因此,结果会返回-2

答案 2 :(得分:2)

虽然两个答案已经完全回答了问题,但我会把自己的答案放在OOP背景下:

List.foldr/3List.foldl/3都是简单的缩减器。在伪代码中(为了清楚起见,我们选择),List.foldl/3完全相当于:

[1, 2, 3, 4].reduce(0) { |acc, x| x - acc }
#⇒ 2

List.foldr/3以RtL顺序接受一个参数,因此我们应该提前反转一个列表:

[1, 2, 3, 4].reverse.reduce(0) { |acc, x| x - acc }
#⇒ -2