gpt4 book ai didi

erlang - 在 erlang 中构建堆栈

转载 作者:行者123 更新时间:2023-12-01 10:56:32 26 4
gpt4 key购买 nike

我仍然是 Erlang 的新手,并试图让我的头脑无法改变变量。假设我创建了一个堆栈并想要添加一个新元素。如果我无法为列表分配新值,我将如何更新堆栈?我每次都需要创建一个新列表吗?

例如,我在想 Push 可能看起来像

List = [X|List].

然后是流行音乐
[Head|Tail] = List
Head
List = Tail

当然这行不通,因为我无法更改 List 的值,这是我的问题。任何帮助表示赞赏。

最佳答案

Erlang 在函数内部不能有副作用,functional programming 中的一个常见特性语言。更改变量状态是一种副作用。 Erlang 中的所有状态变化都被进程和消息传递隐藏,在所谓的 actor model 中。 .

“更改”变量的常用方法是让函数使用更改后的变量调用自身,该变量称为 recursion。 .例如,要对列表的所有元素求和:

sum([]) -> 0;
sum([H|Tail]) -> H + sum(Tail).

更好的是让你的函数 tail recursive ,这意味着它们将自己称为函数体中的最后一条指令。这将节省内存,因为并非所有函数调用都需要保存在堆栈中( tail-call optimization)。相同的示例,但使用尾递归:
sum([], Acc) -> Acc;
sum([H|Tail], Acc) -> sum(Tail, Acc + H).

sum(L) -> sum(L, 0).

在这个例子中,我引入了一个累加器变量来传递中间结果。

如何使程序无副作用并不总是显而易见的,尤其是当您尝试以过程术语(如在 C 或 Java 中)来考虑问题时。它需要实践,可能还需要在更理论的层面上理解函数式编程的意愿。

纯粹的函数式编程语言根本不会有任何副作用;函数的返回值必须仅基于函数的输入参数,并且函数的唯一输出必须是返回值。这不是 Erlang 的情况。 recieve子句和 !运算符用于函数内部的输入和输出;副作用。外部状态可以作为可以发送消息和获得回复的进程来保存。

这是一个如何创建一个变量的示例,该变量的值可以通过消息传递来更改(尝试确定 var_proc 是否是尾递归的!):
var_proc(Value) ->
receive
{get, Pid} ->
Pid ! {value, Value},
var_proc(Value);
{set, New} ->
var_proc(New)
end.

var_start(Init) ->
spawn(?MODULE, var_proc, [Init]).

var_set(Pid, Value) ->
Pid ! {set, Value}.

var_get(Pid) ->
Pid ! {get, self()},
receive
{value, Value} -> Value
end.

这是一个如何使用它的示例(我将模块称为“sum”):
13> V = sum:var_start(6).
<0.72.0>
14> sum:var_get(V).
6
15> sum:var_set(V, 10).
{set,10}
16> sum:var_get(V).
10

更多示例和一些动机可以在 Concurrent Programming 中找到。 Erlang 文档中的章节。

关于erlang - 在 erlang 中构建堆栈,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14912056/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com