我有一个错误,我不明白为什么。 所以,如果我输入:
凸出:计算值([{推,{NUM,2}},{推,{NUM,3}},{加},{推,{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:计算值([{推,{NUM,2}},{推,{NUM,3}},{加},{弹出},{保留},{推,{NUM,4}}, {MUL},{弹出},{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].
我收到错误:
异常错误:没有匹配proj的函数子句:calc({pop},[5])
我是er lang的新手,为什么会发生这种情况,我该如何解决?
答案 0 :(得分:3)
折叠,贴图或过滤器的每次迭代仅消耗列表中的一个元素。这里有三个代表单个操作的元素:{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的一个子句 - 这在开头是不合法的。
在任何情况下,您所描述的系列都是堆栈计算机固有的,不需要拼写出来。这就是为什么您的实现看起来比大多数示例更复杂。