Coding style 惯用的Erlang帮助

Coding style 惯用的Erlang帮助,coding-style,erlang,idioms,Coding Style,Erlang,Idioms,我这里有一个Erlang片段,我想将其转换成更地道的Erlang,而不是一个粗糙的Python翻译 该过程获取一对全等列表并将其组合。一些元素需要根据其属性从一个列表或另一个列表中获取,而其余元素需要求和。它工作正常,但我觉得它不是惯用语 Process = fun([RockA, FishA, TreeA, BarkA, DogA, CowA, MooA, MilkA, CheeseA, BreadA, WineA, GrapesA], [RockB, FishB, TreeB, BarkB,

我这里有一个Erlang片段,我想将其转换成更地道的Erlang,而不是一个粗糙的Python翻译

该过程获取一对全等列表并将其组合。一些元素需要根据其属性从一个列表或另一个列表中获取,而其余元素需要求和。它工作正常,但我觉得它不是惯用语

Process = fun([RockA, FishA, TreeA, BarkA, DogA, CowA, MooA, MilkA, CheeseA, BreadA, WineA, GrapesA], [RockB, FishB, TreeB, BarkB, DogB, CowB, MooB, MilkB, CheeseB, BreadB, WineB, GrapesB]) ->
                  if
                      RockA /= [0,0,0] ->
                          NewRock = RockA,
                          NewFish = FishA,
                          NewTree = TreeA,
                          NewBark = BarkA,
                          NewDog = DogA;
                      true ->
                          NewRock = RockB,
                          NewFish = FishB,
                          NewTree = TreeB,
                          NewBark = BarkB,
                          NewDog = DogB
                  end,
                  if
                      CowA > CowB ->
                          NewCow = CowA;
                      true ->
                          NewCow = CowB
                  end,
                  NewMoo = MooA + MooB,
                  NewMilk = MilkA + MilkB,
                  NewCheese = CheeseA + CheeseB,
                  NewBread = BreadA + BreadB,
                  NewWine = WineA + WineB,
                  NewGrapes = GrapesA + GrapesB,
                  [NewRock, NewFish, NewTree, NewBark, NewDog, NewMoo, NewMilk, NewCheese, NewBread, NewWine, NewGrapes];
             (_,_) ->
                  ok
          end.

这里有一些建议。但是你是否喜欢中间变量赋值,这是一个品味的问题。请注意,“case”和“if”是始终计算为某个值的表达式。我还删除了“(,)->ok”一概而论;这似乎是Erlang中不鼓励的防御性编程

Process = fun([RockA, FishA, TreeA, BarkA, DogA, CowA, MooA, MilkA, CheeseA, BreadA, WineA, GrapesA], 
              [RockB, FishB, TreeB, BarkB, DogB, CowB, MooB, MilkB, CheeseB, BreadB, WineB, GrapesB]) ->

            FirstStuff = case RockA of 
                           [ 0,0,0] ->
                             [RockB, FishB, TreeB, BarkB, DogB];
                           _ ->
                             [RockA, FishA, TreeA, BarkA, DogA]
                         end,

              NewCow = if
                         CowA > CowB -> 
                            CowA;
                         true -> 
                            CowB
                       end,

              lists:flatten( [ FirstStuff,
                               NewCow,
                               MooA + MooB,
                               MilkA + MilkB,
                               CheeseA + CheeseB,
                               BreadA + BreadB,
                               WineA + WineB,
                               GrapesA + GrapesB ]);
          end.
甚至

Process = fun([RockA, FishA, TreeA, BarkA, DogA, CowA, MooA, MilkA, CheeseA, BreadA, WineA, GrapesA], 
              [RockB, FishB, TreeB, BarkB, DogB, CowB, MooB, MilkB, CheeseB, BreadB, WineB, GrapesB]) ->

              lists:flatten( [ case RockA of 
                                 [ 0,0,0] ->
                                   [RockB, FishB, TreeB, BarkB, DogB];
                                 _ ->
                                   [RockA, FishA, TreeA, BarkA, DogA]
                               end,
                               lists:max([CowA,CowB]),
                               MooA + MooB,
                               MilkA + MilkB,
                               CheeseA + CheeseB,
                               BreadA + BreadB,
                               WineA + WineB,
                               GrapesA + GrapesB ]);
          end.

这里有一些建议。但是你是否喜欢中间变量赋值,这是一个品味的问题。请注意,“case”和“if”是始终计算为某个值的表达式。我还删除了“(,)->ok”一概而论;这似乎是Erlang中不鼓励的防御性编程

Process = fun([RockA, FishA, TreeA, BarkA, DogA, CowA, MooA, MilkA, CheeseA, BreadA, WineA, GrapesA], 
              [RockB, FishB, TreeB, BarkB, DogB, CowB, MooB, MilkB, CheeseB, BreadB, WineB, GrapesB]) ->

            FirstStuff = case RockA of 
                           [ 0,0,0] ->
                             [RockB, FishB, TreeB, BarkB, DogB];
                           _ ->
                             [RockA, FishA, TreeA, BarkA, DogA]
                         end,

              NewCow = if
                         CowA > CowB -> 
                            CowA;
                         true -> 
                            CowB
                       end,

              lists:flatten( [ FirstStuff,
                               NewCow,
                               MooA + MooB,
                               MilkA + MilkB,
                               CheeseA + CheeseB,
                               BreadA + BreadB,
                               WineA + WineB,
                               GrapesA + GrapesB ]);
          end.
甚至

Process = fun([RockA, FishA, TreeA, BarkA, DogA, CowA, MooA, MilkA, CheeseA, BreadA, WineA, GrapesA], 
              [RockB, FishB, TreeB, BarkB, DogB, CowB, MooB, MilkB, CheeseB, BreadB, WineB, GrapesB]) ->

              lists:flatten( [ case RockA of 
                                 [ 0,0,0] ->
                                   [RockB, FishB, TreeB, BarkB, DogB];
                                 _ ->
                                   [RockA, FishA, TreeA, BarkA, DogA]
                               end,
                               lists:max([CowA,CowB]),
                               MooA + MooB,
                               MilkA + MilkB,
                               CheeseA + CheeseB,
                               BreadA + BreadB,
                               WineA + WineB,
                               GrapesA + GrapesB ]);
          end.

由于列表的压缩和附加,它可能不是最有效的版本,但是假设它们不会变得更长,与可读性的提高相比,它在大多数程序中不应该是显而易见的

Process = fun([RockA, FishA, TreeA, BarkA, DogA, CowA, | RestA], 
              [RockB, FishB, TreeB, BarkB, DogB, CowB, | RestB]) ->
              Start = if RockA =:= [0,0,0] ->
                            [RockB, FishB, TreeB, BarkB, DogB];
                         true ->
                            [RockA, FishA, TreeA, BarkA, DogA]
                      end,
              Start ++ [max(CowA, CowB)] ++ [X+Y || {X,Y} <- lists:zip(RestA, RestB)]
          end.
Process=fun([RockA,FishA,TreeA,BarkA,DogA,CowA,| RestA],
[RockB、FishB、TreeB、BarkB、Dobb、Cobb、| RestB]->
开始=如果RockA=:=[0,0,0]->
[RockB,FishB,TreeB,BarkB,DogB];
正确->
[RockA,FishA,TreeA,BarkA,DogA]
完,,

Start++[max(CowA,CowB)]++[X+Y |{X,Y}由于列表的压缩和附加,可能不是最有效的版本,但是假设它们不会变得更长,与可读性的提高相比,在大多数程序中它不应该是明显的

Process = fun([RockA, FishA, TreeA, BarkA, DogA, CowA, | RestA], 
              [RockB, FishB, TreeB, BarkB, DogB, CowB, | RestB]) ->
              Start = if RockA =:= [0,0,0] ->
                            [RockB, FishB, TreeB, BarkB, DogB];
                         true ->
                            [RockA, FishA, TreeA, BarkA, DogA]
                      end,
              Start ++ [max(CowA, CowB)] ++ [X+Y || {X,Y} <- lists:zip(RestA, RestB)]
          end.
Process=fun([RockA,FishA,TreeA,BarkA,DogA,CowA,| RestA],
[RockB、FishB、TreeB、BarkB、Dobb、Cobb、| RestB]->
开始=如果RockA=:=[0,0,0]->
[RockB,FishB,TreeB,BarkB,DogB];
正确->
[RockA,FishA,TreeA,BarkA,DogA]
完,,
Start++[max(CowA,CowB)]++[X+Y | |{X,Y}另一种解决方案:

process([RockA, FishA, TreeA, BarkA, DogA | TlA],
        [RockB, FishB, TreeB, BarkB, DogB | TlB]) ->
  case RockA of
    [0,0,0] -> [RockB, FishB, TreeB, BarkB, DogB | process2(TlA, TlB)];
    _       -> [RockA, FishA, TreeA, BarkA, DogA | process2(TlA, TlB)]
  end.

process2([CowA | TlA], [CowB | TlB]) ->
  [erlang:max(CowA, CowB) | process3(TlA, TlB)].

process3([HdA | TlA], [HdB | TlB]) ->
  [HdA + HdB | process3(TlA, TlB)];

process3([], []) -> [].


Process = fun process/2.
另一个解决方案:

process([RockA, FishA, TreeA, BarkA, DogA | TlA],
        [RockB, FishB, TreeB, BarkB, DogB | TlB]) ->
  case RockA of
    [0,0,0] -> [RockB, FishB, TreeB, BarkB, DogB | process2(TlA, TlB)];
    _       -> [RockA, FishA, TreeA, BarkA, DogA | process2(TlA, TlB)]
  end.

process2([CowA | TlA], [CowB | TlB]) ->
  [erlang:max(CowA, CowB) | process3(TlA, TlB)].

process3([HdA | TlA], [HdB | TlB]) ->
  [HdA + HdB | process3(TlA, TlB)];

process3([], []) -> [].


Process = fun process/2.

或者,根据Zed的回答,用功能从句替换case,我们可以做到以下几点。我们找到惯用的一个了吗?这在很大程度上是一个品味和审美的问题

process([[0,0,0], _, _, _, _ | TlA],
        [RockB, FishB, TreeB, BarkB, DogB | TlB]) ->
    [RockB, FishB, TreeB, BarkB, DogB | process2(TlA, TlB)];

process([RockA, FishA, TreeA, BarkA, DogA | TlA],
        [_, _, _, _, _ | TlB]) ->
    [RockA, FishA, TreeA, BarkA, DogA | process2(TlA, TlB)].

process2([CowA | TlA], [CowB | TlB]) ->
  [erlang:max(CowA, CowB) | process3(TlA, TlB)].

process3([HdA | TlA], [HdB | TlB]) ->
  [HdA + HdB | process3(TlA, TlB)];

process3([], []) -> [].


Process = fun process/2.

或者,根据Zed的回答,用功能从句替换case,我们可以做到以下几点。我们找到惯用的一个了吗?这在很大程度上是一个品味和审美的问题

process([[0,0,0], _, _, _, _ | TlA],
        [RockB, FishB, TreeB, BarkB, DogB | TlB]) ->
    [RockB, FishB, TreeB, BarkB, DogB | process2(TlA, TlB)];

process([RockA, FishA, TreeA, BarkA, DogA | TlA],
        [_, _, _, _, _ | TlB]) ->
    [RockA, FishA, TreeA, BarkA, DogA | process2(TlA, TlB)].

process2([CowA | TlA], [CowB | TlB]) ->
  [erlang:max(CowA, CowB) | process3(TlA, TlB)].

process3([HdA | TlA], [HdB | TlB]) ->
  [HdA + HdB | process3(TlA, TlB)];

process3([], []) -> [].


Process = fun process/2.

我不认为将子句从case语句移动到函数更为惯用。我只选择case语句,因为它“更具可读性”除此之外,我不认为“函数子句”方法更为惯用,我只是提出了另一种选择。我同意——我认为在这种情况下,您的原作更漂亮一些,尽管在大多数情况下,函数只包含一个case语句,我通常会将其重构为函数子句。这可能是一个例外规则,所以我给你+1。谢谢。我不认为将子句从case语句移动到函数更惯用。我只选择case语句,因为它“更具可读性”除此之外,我不认为“函数子句”方法更为惯用,我只是提出了另一种选择。我同意——我认为在这种情况下,您的原作更漂亮一些,尽管在大多数情况下,函数只包含一个case语句,我通常会将其重构为函数子句。这可能是一个例外为我规则,所以我给你+1。干杯