May 13, 2021 Erlang
In some scenarios, we may need to find the maximum temperature or minimum temperature. T herefore, it is useful to find the maximum or minimum value in the temperature value list. B efore the extender implements this feature, let's look at the method of finding the maximum value in the list:
-module(tut6).
-export([list_max/1]).
list_max([Head|Rest]) ->
list_max(Rest, Head).
list_max([], Res) ->
Res;
list_max([Head|Rest], Result_so_far) when Head > Result_so_far ->
list_max(Rest, Head);
list_max([Head|Rest], Result_so_far) ->
list_max(Rest, Result_so_far).
37> c(tut6).
{ok,tut6}
38> tut6:list_max([1,2,3,4,5,7,4,3,2,1]).
7
First note that the names of the two functions are exactly the same. H
owever, because they accept different numbers of arguments, they are treated as two completely different functions in Erlang. W
hen you need to use them, you can use the name/number of parameters, the name here is the name of the function, the number of parameters refers to the number of parameters of the function. I
n this example,
list_max/1
and
list_max/2
In this example, during traversing the middle element of the list, a value (maximum) is "carried", which
Result_so_far
list_max/1
the first element in the list as the maximum element, and then uses the remaining element as an argument
list_max/2
I
n the example above
list_max([2,3,4,5,6,7,4,3,2,1],1)
I
f you call
list_max/1
as an list_max or data of a non-list type, an error occurs. N
ote that Erlang's philosophy is not to deal with errors where they occur, but to deal with them in places that specialize in errors. W
e'll explain it in more detail later.
In
list_max/2
when head is
Head > Result_so_far
head is used instead
Result_so_far
the function continues to be called. W
hen used in front of the function is a special word that means that this part of the function will only be used if the test condition is true. T
his type of test is called guard. I
f the guard is false (that is, the guard test fails), skip this section and try to use the later part of the function. I
n this example, if Head is not greater
Result_so_far
be less than or equal to . S
o the guard test is not required in the next part of the function.
Operators that can be used in guard also include:
<
Less than
>
Greater than
==
Equals
>=
Is greater than or equal to
=<
Less than or equal to
/=
Not equal to
(See Guard Sequences for details)
It's easy to modify the program that looks
>
for the maximum above to find the minimum element, just
<
. (
However, it is a good idea to also modify the function
list_min
As we mentioned earlier, each variable can only be assigned once within its scope. A
s you can see from the example above,
Result_so_far
been assigned more than once. T
his is because every time a
list_max/2
is called, a new scope is created. I
n each of the different scopes,
Result_so_far
treated as completely different variables.
In addition, we can use the matching operator to create a variable and assign a value to it. T herefore, the variable M is created by M s 5 and is assigned a value of 5. I f you write M s 6 again in the same scope, an error will result. T ry it in the shell:
39> M = 5.
5
40> M = 6.
** exception error: no match of right hand side value 6
41> M = M + 1.
** exception error: no match of right hand side value 6
42> N = M + 1.
6
In addition to creating new variables, another use for matching operators is to separate the Erlang items.
43> {X, Y} = {paris, {f, 28}}.
{paris,{f,28}}
44> X.
paris
45> Y.
{f,28}
As above, the X value is paris, and the value of Y is .f, 28.
If you use X and Y again, you get an error:
46> {X, Y} = {london, {f, 36}}.
** exception error: no match of right hand side value {london,{f,36}}
Variables are used to improve the readability of the program. F
or example,
list_max/2
you can write something like this:
list_max([Head|Rest], Result_so_far) when Head > Result_so_far ->
New_result_far = Head,
list_max(Rest, New_result_far);
Writing this way makes the program clearer.