Как написать "a == b? X: Y" на Erlang? - PullRequest
8 голосов
/ 23 мая 2011

Есть ли хороший способ написать такой код на Erlang?

A == B ? X : Y

ниже код в стиле ruby ​​

Ответы [ 6 ]

35 голосов
/ 23 мая 2011

Объяснение

Причина, по которой троичный оператор _ ? _ : _ существует во многих языках, связана с тем, что у них есть два синтаксических класса: операторы и выражения.Поскольку конструкции if-then-else обычно принадлежат классу операторов, нет способа заставить это работать, когда вы вводите выражение.Следовательно, вы добавляете оператор _ ? _ : _ в класс выражений.

Как говорится в другом сообщении, вы можете взять a == b ? true : false и просто написать a == b, но это не объясняет общий случай, когда мы можем иметь a == b ? X : Y для произвольных выражений X и Y.Также обратите внимание, что a == b всегда является false в Erlang, поэтому вы можете утверждать, что реальная вещь, которую нужно сделать, это заменить все выражение на false.

К счастью, Erlang, как в случае сбольшинство функциональных языков имеют только один синтаксический класс, выражения.Следовательно, вы можете использовать case a == b of X -> ...; Y -> ... end в любом месте функции, включая другие выражения.Другими словами, троичный оператор _ ? _ : _ является избыточным в Erlang, поскольку case уже работает.

Пример:

Предположим, мы должны вернуть простой проплист и у нас есть некоторые вычислениянам нужно сделать

  f() ->
    case a == b of
          true -> 
           [{a, 3},
            {b, <<"YE">>},
            {c, 7}];
          false ->
           [{a, 3},
            {b, <<"YE">>},
            {c, "HELLO!!!"}];
    end.

Но поскольку конструкция case является выражением, мы можем просто вставить его в строку:

  f() ->
    [{a, 3},
     {b, <<"YE">>},
     {c, case a == b of
          true -> 7;
          false -> "HELLO!!!"
         end}].

и покончить с этим.

Почему я не защищаю использование IF

, конструкция if .. end в Эрланге обычно не то, что вы хотите.В этом случае вы хотите изучить значение a == b, и оно может дать один из двух выходных данных true или false.В этом случае выражение case является более прямым.if лучше использовать, если вам нужно проверить несколько разных тестов и выбрать первое совпадение, тогда как у нас здесь есть только один тест.

6 голосов
/ 24 июля 2011

Мы используем такой макрос:

-define(IF(Cond,E1,E2), (case (Cond) of true -> (E1); false -> (E2) end)).

Затем в вашем коде вы пишете:

io:format("~s~n", [?IF(a==b, "equal", "not equal")]).
5 голосов
/ 23 мая 2011

Если вы спрашиваете, как написать что-то вроде A == B ? X : Y в виде if выражения, это

if
    A == B ->
        X;
    true ->    % "true" means "else" here
        Y
end

Вы также можете написать это как case выражение:

case A == B of
    true ->
        X;
    _Else ->
        Y
end

или

case A == B of
    true ->
        X;
    false ->
        Y
end
4 голосов
/ 23 мая 2011

Поскольку a == b ? true : false отображается на a == b, вы также можете использовать a == b в Erlang.

1 голос
/ 23 мая 2011

Вы можете использовать 'если' вот так

foo(A,B) ->
    [1,
     2,
     (if A == B -> 3; true -> 4 end), % A == B ? 3 : 4
     5,
     6].

special?: Форма не нужна.Конечно, вы можете использовать true / false в качестве возвращаемого значения, но я думаю, что вы имели в виду более общую форму, так как она будет бесполезной (A == B выполняет ту же работу).

0 голосов
/ 13 октября 2014

@ ответ Гейба является наиболее кратким и (насколько я могу судить) идиоматическим. Выражение C ((A==B) ? X : Y) отображается непосредственно на выражение Erlang

case A == B of
    true -> X;
    false -> Y
end

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

iff(true, X, Y) -> X;
iff(false, X, Y) -> Y.

Тогда ваше выражение C становится просто iff(A == B, X, Y). Однако, будьте осторожны! , так же как и С, Эрланг охотно оценивает аргументы функции. Если X или Y имеют побочные эффекты или являются дорогостоящими для оценки, то iff не будет эквивалентен встроенному выражению case.

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