function greet(Gender,Name) if Gender == male then print("Hello, Mr. %s!", Name) else if Gender == female then print("Hello, Mrs. %s!", Name) else print("Hello, %s!", Name) end
if then else
, pattern matching is used, you can save a bunch of sample code. This is how this function will look like on Erlang if you use pattern matching: greet(male, Name) -> io:format("Hello, Mr. ~s!", [Name]); greet(female, Name) -> io:format("Hello, Mrs. ~s!", [Name]).
io:format()
function is used for formatted output to the terminal. Here we used pattern matching in the description of the function argument list. This allowed us to simultaneously assign input values and select the part of the function to be executed. Why first assign values, and then compare them in the function body, if you can do it at the same time and in a “more declarative” style? fnct_name(X) -> Extpression; fnct_name(Y) -> Expression; fnct_name(_) -> Expression.
;
), followed by the next one. After the last part of the set point.greet()
function and specify an unintended floor? We will get an exception that the input parameters do not match any of the samples: 1> chapter03:greet(someOther, "Haru"). ** exception error: no function clause matching chapter03:greet(someOther, "Haru")
greet(male, Name) -> io:format("Hello, Mr. ~s!", [Name]); greet(female, Name) -> io:format("Hello, Mrs. ~s!", [Name]); greet(_, Name) -> io:format("Hello, ~s!", [Name]).
first([X|_]) -> X. second([_,X|_) -> X.
same(X,X) -> true; same(_,_) -> false.
true
if its arguments are the same, otherwise it returns false
. How it works? When calling the function chapter03::same(one, two).
the variable X
assigned the value one
, then an attempt is made to assign the same variable to the value two
. Because the value has already been assigned, the attempt fails and the template is rejected as inappropriate. Since in the second case we do not explicitly indicate which variables need to be assigned values, the template is suitable and the function returns false
. If we pass the same values to the function, chapter03:same(3, 3).
then the first template will do, and the function will return true
. bmi_tell(Bmi) when Bmi =< 18.5 -> "You're underweight."; bmi_tell(Bmi) when Bmi =< 25 -> "You're supposedly normal."; bmi_tell(Bmi) when Bmi =< 30 -> "You're fat."; bmi_tell(_) -> "You're very fat.".
when
( Bmi =< 18.5
). If this expression returns true
, the corresponding code branch will be executed. Otherwise, the next condition is checked and so on until the end. And here we also added a condition to the end under which any value would fit. fnct_name(Arg_1, Arg_1, ..., Arg_n) when rule_1 -> Expression; fnct_name(Arg_1, Arg_1, ..., Arg_n) when rule_2 -> Expression.
andalso
) to pass the check, a comma ( ,
) is put between them. lucky_number(X) when 10 < X, X > 20 -> true; lucky_number(_) -> false.
orelse
), they are separated by a semicolon ( ;
). lucky_atom(X) when X == atom1; X == anot2 -> true; lucky_atom(_) -> false.
Y
not zero: safe_division(X, Y) when is_integer(X), is_integer(Y), Y /= 0 -> X / Y; safe_division(_, _) -> false.
if
if
branching operator. Let's rewrite our bmi_tell()
function using this operator. if_bmi_tell(Bmi) -> if Bmi =< 18.5 -> "You're underweight."; Bmi =< 25 -> "You're supposedly normal."; Bmi =< 30 -> "You're fat."; true -> "You're very fat." end.
if
branching if
looks like this: if Rule_1 -> Expression; Rule_2 -> Expression; ... true -> Expression end.
rule_1
and rule_2
are one or more conditions. If the condition is successful, the Expression
code block (may contain one or several commands) following it will be executed. Such logical branches can be any number.true -> "You're very fat.
What is this condition? This is an alternative to the orelse
operator. The code block following it will be executed if no condition passes the test. It is important to remember that this operator is mandatory. After all as we remember, in Erlang, any expression must return a result. If you do not describe this block, the module will compile, but when the execution thread checks all conditions and does not detect the block true
, an exception will be generated. ** exception error: no true branch found when evaluating an if expression in function chapter03:if_bmi_tell/1
case ... of
operatorif
, Erlang has another branching operator - case of
. And this operator is like an entire function inserted into another function. It allows you to make a choice not only on the basis of the condition, but also makes it possible to use pattern matching and guard expressions. In general, it looks like this: case Rule of Val_1 -> Expression; Val_2 -> Expression ... Val_n -> Expression
Rule
is a variable or expression whose result will be checked. Next are the condition-expression blocks already known to us ( Val_1 -> Expression;
). You can use pattern matching and guard expressions in the condition, which makes this design incredibly flexible. assessment_of_temp(Temp) -> case Temp of {X, celsius} when 20 =< X, X =< 45 -> 'favorable'; {X, kelvin} when 293 =< X, X =< 318 -> 'scientifically favorable'; {X, fahrenheit} when 68 =< X, X =< 113 -> 'favorable in the US'; _ -> 'not the best tempperature' end.
Temp
variable, then a pattern will be found under which this tuple will fit. Then it will be checked by security expressions, and if it is passed, the function will return the corresponding string.case of
almost completely can be moved to the scope of the function declaration. So where is the best place to post conditions? The answer is simple: where you like more. The differences between these two designs are minimal. Therefore, use the option that is easier for you to read.Source: https://habr.com/ru/post/211815/
All Articles