【问题标题】:Matching values in a tuple through a map通过映射匹配元组中的值
【发布时间】:2021-06-23 04:04:41
【问题描述】:

我正在尝试制作这样的功能

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 将 X 中的任何潜在原子 a 或 b 映射到输入中给出的值”是什么意思?除了让人们尝试破译那个受折磨的句子之外,给每个示例的输出示例提供一个示例要容易得多吗?
  • 这是我的问题,但我意识到我并不清楚我想要回答什么。由于我无法删除我的问题,我觉得我别无选择,只能写一个新问题来更好地描述我想要回答的问题。这个输入 eval({mul, {add, a, 3}, b}, #{a => 1, b => 2}) 将作为输出 8,就像在我的程序中通过 eval 函数一样 4*2 ({mul, {add, 1, 3}, 2}, #{a => 1, b => 2}) 在我的程序中是 (3+1)*2

标签: tuples erlang pattern-matching


【解决方案1】:

修改@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.

【讨论】:

    【解决方案2】:

    正如Map pattern matching in function head 的其他人所建议的那样(尽管这个问题的描述要清楚得多),您正在寻找的是类似于......

    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;
    …
    

    【讨论】:

    • 首先,感谢您的帮助,现在该程序可以在部分方面运行。这两个输入有效,eval({add, a, b}, #{a => 1, b => 2}), eval({add, a, 2}, #{a => 1}),但不是这个输入 eval({mul, {add, a, 3}, b}, #{a => 1, b => 2})。它创建此错误消息异常错误:在从 task1:eval/1 (task1.erl,第 15 行)调用中调用 operator +/2 中的算术表达式时发生错误:eval/1 调用中称为 + 3 (task1.erl,第 18 行)
    • @RasmusSteen,无论你做什么,都不要发布程序的第 15 行和第 18 行。
    猜你喜欢
    • 2018-10-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-11-05
    • 1970-01-01
    • 2014-08-19
    • 1970-01-01
    相关资源
    最近更新 更多