Идиоматическая помощь Erlang - PullRequest
1 голос
/ 24 июня 2010

У меня есть фрагмент 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.

Ответы [ 4 ]

4 голосов
/ 24 июня 2010

Еще одно решение:

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.
3 голосов
/ 24 июня 2010

Вероятно, не самая эффективная версия из-за архивирования и добавления списков, но, если они не становятся намного длиннее, это не должно быть заметно в большинстве программ по сравнению с увеличением читаемости.

Также обратите внимание на отсутствие предложения catch-all, когда вызов функции не совпадает.Не пишите защитный код.Позвольте этому терпеть крах и попросите, чтобы наблюдатель позаботился об этом.Написание защитного кода только усложняет отладку на языке, где сбой не является смертельным приговором в вашей программе.

1 голос
/ 24 июня 2010

Или, взяв ответ Зеда и заменив регистр функциональными предложениями, мы могли бы сделать следующее. Мы уже нашли идиоматическую? Во многом это вопрос вкуса и эстетики.

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.
1 голос
/ 24 июня 2010

Вот несколько предложений.Но это вопрос вкуса, нравится ли вам промежуточные назначения переменных.Просто помните, что «case» и «if» - это выражения, которые всегда что-то оценивают.Я также удалил "(, ) -> ok" перехватить все;кажется, что это защитное программирование, которое не рекомендуется в Erlang.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...