地图,过滤器,折叠等?我们真的需要在Erlang中使用这些吗?

HIR*_*KUR 0 erlang

地图,过滤器,折叠等:http://learnyousomeerlang.com/higher-order-functions#maps-filters-folds

我读的越多,我就越困惑.

任何人都可以帮助简化这些概念吗?

我无法理解这些概念的重要性.在哪些用例中需要这些?

我认为主要是因为语法,diff来查找流程.

ers*_*zcz 6

函数式编程中普遍存在的映射,过滤和折叠的概念实际上是对数据集合执行的不同操作的简化 - 或刻板印象 - .在命令式语言中,您通常使用循环执行这些操作.

我们来map举个例子吧.这三个循环都采用一系列元素并返回元素的一系列正方形:

// C - a lot of bookkeeping
int data[] = {1,2,3,4,5};
int squares_1_to_5[sizeof(data) / sizeof(data[0])];
for (int i = 0; i < sizeof(data) / sizeof(data[0]); ++i)
    squares_1_to_5[i] = data[i] * data[i];

// C++11 - less bookkeeping, still not obvious
std::vec<int> data{1,2,3,4,5};
std::vec<int> squares_1_to_5;
for (auto i = begin(data); i < end(data); i++)
    squares_1_to_5.push_back((*i) * (*i));

// Python - quite readable, though still not obvious
data = [1,2,3,4,5]
squares_1_to_5 = []
for x in data:
    squares_1_to_5.append(x * x)
Run Code Online (Sandbox Code Playgroud)

a的属性map是它采用元素的集合并返回相同数量的以某种方式修改的元素.不多也不少.在上面的片段中乍一看是否很明显?不,至少在我们阅读循环体之前.如果if循环中有一些s怎么办?让我们拿最后一个例子并稍微修改一下:

data = [1,2,3,4,5]
squares_1_to_5 = []
for x in data:
    if x % 2 == 0:
        squares_1_to_5.append(x * x)
Run Code Online (Sandbox Code Playgroud)

这不再是一个map,虽然在阅读循环体之前并不明显.结果集合可能比输入集合的元素少(可能没有?),这一点并不清晰可见.

我们filter编辑了输入集合,仅对输入中的某些元素执行操作.这个循环实际上是一个map结合filter.

由于分配细节(为输出数组分配多少空间?),在C中解决这个问题会更加嘈杂 - 数据操作的核心思想将在所有簿记中被淹没.

A fold是最通用的,其结果不必包含任何输入元素,但某种程度上取决于它们(可能只有一部分).

让我们重写Erlang中的第一个Python循环:

lists:map(fun (E) -> E * E end, [1,2,3,4,5]).
Run Code Online (Sandbox Code Playgroud)

这很明确.我们看到一张地图,所以我们知道只要输入,这个调用就会返回一个列表.第二个:

lists:map(fun (E) -> E * E end,
          lists:filter(fun (E) when E rem 2 == 0 -> true;
                           (_) -> false end,
                       [1,2,3,4,5])).
Run Code Online (Sandbox Code Playgroud)

再次,filter只要输入,将返回一个列表,map将以某种方式修改每个元素.

后者的Erlang示例还显示了另一个有用的属性 - 组合maps,filters和folds以表达更复杂的数据转换的能力.使用命令式循环是不可能的.