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

地图、过滤器、折叠等?在Erlang我们真的需要这些吗?,erlang,Erlang,贴图、过滤器、折叠等: 我读得越多,就越糊涂 任何机构都能帮助简化这些概念吗 我无法理解这些概念的意义。在哪些用例中需要这些概念 我认为这主要是因为语法不同,无法找到流程。它们几乎用于每个应用程序,因为它们在列表上抽象出不同类型的迭代 映射用于将一个列表转换为另一个列表。比方说,你有一个键值元组列表,你只需要这些键。你可以写: keys([]) -> []; keys([{Key, _Value} | T]) -> [Key | keys(T)]. 然后,您希望具有以下值:

贴图、过滤器、折叠等:

我读得越多,就越糊涂

任何机构都能帮助简化这些概念吗

我无法理解这些概念的意义。在哪些用例中需要这些概念

我认为这主要是因为语法不同,无法找到流程。

它们几乎用于每个应用程序,因为它们在列表上抽象出不同类型的迭代

映射用于将一个列表转换为另一个列表。比方说,你有一个键值元组列表,你只需要这些键。你可以写:

keys([]) -> [];
keys([{Key, _Value} | T]) ->
    [Key | keys(T)].
然后,您希望具有以下值:

values([]) -> [];
values([{_Key, Value} | T}]) ->
    [Value | values(T)].
或仅元组第三个元素的列表:

third([]) -> [];
third([{_First, _Second, Third} | T]) ->
    [Third | third(T)].
你能看到图案吗?唯一的区别是您从元素中获取了什么,所以您可以简单地编写对一个元素所做的操作并使用map,而不是重复代码

这要短得多,代码越短,错误就越少。就这么简单。 你不必考虑角落里的案例,如果列表是空的呢?对于有经验的开发人员来说,它更容易阅读

筛选搜索列表。您给它函数,它接受元素,如果它返回true,元素将在返回的列表中,如果它返回false,元素将不在那里。例如,从列表中筛选登录用户

foldl和foldr用于在迭代列表时进行额外的簿记,例如对所有元素求和或计数


关于这些函数,我发现最好的解释是关于Lisp:和的书籍。

函数编程中流行的映射、过滤和折叠概念实际上是对数据集合执行的不同操作的简化或定型。在命令式语言中,通常使用循环执行这些操作

让我们以地图为例。这三个循环都采用元素序列,并返回元素的平方序列:

// 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)
这不再是一张地图,尽管在阅读循环体之前它并不明显。结果集合中的元素可能较少,但可能没有,这一点并不清楚?而不是输入集合

我们过滤了输入集合,只对输入中的某些元素执行操作。这个循环实际上是一个结合了过滤器的映射

由于分配细节,在C中处理这一问题会更加嘈杂—要为输出数组分配多少空间数据操作的核心思想将淹没在所有簿记中

折叠是最通用的一种,其结果不必包含任何输入元素,但在某种程度上可能仅取决于其中的一些元素

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

lists:map(fun (E) -> E * E end, [1,2,3,4,5]).
这是明确的。我们看到一个映射,所以我们知道这个调用将返回一个与输入相同长的列表。 第二个:

lists:map(fun (E) -> E * E end,
          lists:filter(fun (E) when E rem 2 == 0 -> true;
                           (_) -> false end,
                       [1,2,3,4,5])).
同样,过滤器将返回一个列表,只要输入,映射将以某种方式修改每个元素

Erlang的后一个示例还展示了另一个有用的特性——合成映射、过滤器和折叠以表示更复杂的数据转换的能力。使用命令式循环是不可能的

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