Reputation:
I'm trying to make a function like this essentially
eval(X, Map = #{}) ->
%% expression
.
X is supposed to be a tuple that will contain three elements, with the first one being a description. The other values can be either integers, or they can be the atom a or b, or another tuple. The second parameter is supposed to be a map that will map any potential atom a or b in X to a value. Example inputs can be
eval({add, a, b}, #{a => 1, b => 2})
eval({add, a, 2}, #{a => 1})
eval({mul, {add, a, 3}, b}, #{a => 1, b => 2}).
I for the life of me cannot find a way to have Map, map any potential atom a or b in X to the values given in the input. Anyone has a suggestion for how to implement so that any atom a or b are mapped to vales given in Map?
Upvotes: 0
Views: 82
Reputation: 391
Modifications to the already posted answer by @BrujoBenavides to handle nested tuples:
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.
Upvotes: 0
Reputation: 1958
As suggested by other folks at Map pattern matching in function head (Although this question has a far clearer description), what you are looking for is something along the lines of…
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;
…
Upvotes: 1