在 Enumerable Protocol 官方文档中找到的 Elixir 代码中每个枚举中 acc 和 x 的值是多少?

问题描述 投票:0回答:1

我正在尝试剖析和理解

acc/0
reducer/0
在可枚举协议中如何工作。

def map(enumerable, fun) do
  reducer = fn x, acc -> {:cont, [fun.(x) | acc]} end
  Enumerable.reduce(enumerable, {:cont, []}, reducer) |> elem(1) |> :lists.reverse()
end

有人可以从每个枚举中的 x, acc 值开始解释这一点吗


functional-programming elixir
1个回答
0
投票

这几乎但不太像更高级别的

Enum.reduce/3
,以及其他函数语言中类似的“减少”或“折叠”操作。
Enumerable
是一个较低级别的 Elixir 协议(接口),类型可以实现它来表示它们是“容器”,并且可以与
Enum
函数一起使用;
reduce
是核心构建块。

reducer
参数将为列表中的每个元素调用一次,累加器的前一个(或初始)值作为该参数。 累加器参数的
Enumerable:acc/0
类型不仅包括值,还包括一个控制原子,它告诉
Enumerable
实现要做什么,特别是提供提前停止的选项。
:cont
这里的意思是“继续”,在这个例子中你将始终迭代整个列表。

假设您打电话

map([1, 2, 3], &(&1 * 2))

那么内部调用的顺序就是

reducer.(1, [])      # {:cont, [2]}
reducer.(2, [2])     # {:cont, [4, 2]}
reducer.(3, [4, 2])  # {:cont, [6, 4, 2]}

剩余的逻辑分离

:cont
标记并反转列表,使其处于正确的顺序。

© www.soinside.com 2019 - 2024. All rights reserved.