模拟基本错误,Erlang
我有个错误,我不明白为什么。 因此,如果我进入: proj:calc([{push,{num,2}},{push,{num,3}},{plus},{push,{num,4},{mul}]) 而守则:模拟基本错误,Erlang,erlang,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
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].
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].
我得到了20的输出(正是我想要的)
但如果我有这样的输入:
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([{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}, [N1, N2 | Stack]) -> [N1 + N2 | Stack];
calc({mul}, [N1, N2 | Stack]) -> [N1 * N2 | Stack];
calc({push,{num,X}}, Stack) -> [X | Stack].
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]匹配的函数子句
我是二郎的新手,为什么会发生这种情况,我该如何解决 折叠、映射或过滤器的每次迭代只消耗列表中的一个元素。这里有三个元素表示单个操作:
{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}}]
传递给映射函数的函数必须是arity 2,这里您在同一个函数定义中混合了arity 4的两个子句和arity 2的一个子句,这是不合法的
在任何情况下,您所描述的系列都是堆栈机器固有的,不需要详细说明。这就是为什么您的实现始终比大多数示例看起来更复杂/问题更大。谢谢,我知道当我尝试所有方法时它都不起作用。我也尝试过使用过滤器,但我不知道如何正确地实现它,否则它将无法正常工作。过滤器会根据测试结果进行过滤,留下列表的其余部分。映射通过对列表的每个成员应用一个操作来转换列表。您试图做的是将列表中的所有值压缩成一个值,这就是折叠所做的:它在最后将所有内容折叠成一个值(聚合操作)。恰好可以将堆栈机器的每个操作定义为单个函数,并且由于fold本身已经完成了“pop、operation、push、iterate”步骤,因此很容易用fold构建堆栈机器。或者在
calc/2
中为{plus}
,{mul}
,{pop}使用单独的子句
和{ret}
。请注意,不需要将这些指令作为元组,它们也可以是plus
、mul
、pop
和ret
。