Coding style 惯用的Erlang帮助
我这里有一个Erlang片段,我想将其转换成更地道的Erlang,而不是一个粗糙的Python翻译 该过程获取一对全等列表并将其组合。一些元素需要根据其属性从一个列表或另一个列表中获取,而其余元素需要求和。它工作正常,但我觉得它不是惯用语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,
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。干杯