模拟基本错误,Erlang

Simulation basic error, Erlang

我有一个错误,我不明白为什么。 所以如果我输入:

proj:calc([{push,{num,2}},{push,{num,3}},{plus},{push,{num,4}},{mul}]).

而代码:

calc(List) -> 
[Res] = lists:foldl(fun calc/2, [], List),
Res.

calc({plus}, [N1, N2 | Stack]) -> [N1 + N2 | Stack];
calc({mul}, [N1, N2 | Stack]) -> [N1 * N2 | Stack];
calc({push,{num,X}}, Stack) -> [X | Stack].

我得到 20 的输出(完美的正是我想要的)。

但是如果我有这样的输入:

proj:calc([{push,{num,2}},{push,{num,3}},{plus},{pop},{ret},{push,{num,4}},{mul},{pop},{ret}]).

而代码:

calc(List) -> 
[Res] = lists:foldl(fun calc/2, [], List),
Res.

calc({plus},{pop},{ret}, [N1, N2 | Stack]) -> [N1 + N2 | Stack];
calc({mul},{pop},{ret}, [N1, N2 | Stack]) -> [N1 * N2 | Stack];
calc({push,{num,X}}, Stack) -> [X | Stack].

我得到一个错误:

exception error: no function clause matching proj:calc({pop},[5])

我是er lang的新手,为什么会这样,我该如何解决?

折叠、映射或过滤器的每次迭代仅使用列表中的一个元素。这里有三个元素代表一个操作:{plus},{pop},{ret}。您要么必须将其包装在单个元组 {{plus},{pop},{ret}} 中,要么记住堆栈机器 隐式执行 {pop}{ret} 在每个操作结束时已经-- 所以这两个操作可以去掉。

考虑到这一点,您的代码应该以第一种方式阅读,或者像这样:

calc({{plus},{pop},{ret}}, [N1, N2 | Stack]) -> [N1 + N2 | Stack];
calc({{mul},{pop},{ret}}, [N1, N2 | Stack]) -> [N1 * N2 | Stack];
calc({push,{num,X}}, Stack) -> [X | Stack].

你的输入应该是:

[{push,{num,2}},{push,{num,3}},{{plus},{pop},{ret}},{push,{num,4}},{{mul},{pop},{ret}}]

传递给 map 函数的函数必须是 arity 2,在这里你在同一个函数定义中混合了两个 arity 4 的子句和一个 arity 2 的子句——一开始是不合法的。

反正你说的这个系列已经是栈机固有的了,不用拼写了。这就是为什么您的实施始终比大多数示例更复杂 looking/problematic。