通过映射匹配元组中的值



我正在尝试制作一个类似的函数

eval(X, Map = #{}) ->
%% expression
. 

X应该是一个包含三个元素的元组,第一个元素是描述。其他值可以是整数,也可以是原子a或b,或者另一个元组。第二个参数应该是一个映射,它将X中的任何潜在原子a或b映射到一个值。示例输入可以是

eval({add, a, b}, #{a => 1, b => 2})
eval({add, a, 2}, #{a => 1})
eval({mul, {add, a, 3}, b}, #{a => 1, b => 2}). 

我一生都找不到一种方法来使用Map,将X中的任何潜在原子a或b映射到输入中给定的值。有人对如何实现任何原子a或b都映射到Map中给定的值有建议吗?

正如函数头中Map模式匹配的其他人所建议的那样(尽管这个问题有更清晰的描述(,您正在寻找的是…

eval({Op, a, b}, #{a := A, b := B}) ->
eval(Op, A, B);
eval({Op, A, b}, #{b := B}) ->
eval(Op, A, B);
eval({Op, a, B}, #{a := A}) ->
eval(Op, A, B);
eval({Op, A, B}, _) ->
eval(Op, A, B).
eval(add, A, B) ->
A + B;
eval(mul, A, B) ->
A * B;
…

@BrujoBenavides对已发布答案的修改,以处理嵌套元组:

eval({Op, a, b}, #{a := A, b := B}) ->
eval(Op, A, B);
eval({Op, a, B}, #{a := _} = Map) when is_integer(B) ->
eval({Op, a, b}, Map#{b => B});
eval({Op, a, Expr}, #{a := _} = Map) ->
B = eval(Expr, Map),
eval({Op, a, b}, Map#{b => B});
eval({Op, A, b}, #{b := _} = Map) when is_integer(A) ->
eval({Op, a, b}, Map#{a => A});
eval({Op, Expr, b}, #{b := _} = Map) ->
A = eval(Expr, Map),
eval({Op, a, b}, Map#{a => A});
eval({Op, A, B}, _) when is_integer(A), is_integer(B) ->
eval({Op, a, b}, #{a => A, b => B});
eval({Op, Expr1, Expr2}, #{} = Map) ->
%% need to evaluate Expr1 and Expr2 before Op
A = eval(Expr1, Map),
B = eval(Expr2, Map#{a => A}),
eval({Op, a, b}, Map#{a => A, b => B}).
eval(add, A, B) ->
A+B;
eval(sub, A, B) ->
A - B;
eval(mul, A, B) ->
A * B;
eval('div', A, B) ->
A div B.

最新更新