skip to main |
skip to sidebar
Let's try to run the following even/1 function code that I had taken from page 86 (paper) or 62 (pdf) of Erlang Programming book:
-module(example).
-export([even/1]).
even([]) -> [];
even([H|T]) when H rem 2 == 0 -> [H | even(T)];
even([_|T]) -> even(T).
surprise that the function doesn’t produce desired result:
1> example:even([10,11,12]).
"\n\f"
the result should be [10,12] not "\n\f". Let's try typing the following line into Erlang shell:
2> [10,12].
"\n\f"
It's shows you that there is nothing wrong with the result. Erlang prints the value of a list as a string, but only if all the integers in the list represent printable characters. The example of integers that printed without any conversion are 1, 2, 3, 4, 5, 6, and 7. A list with an unprintable character is printed without conversion. If your list is [1,10,12] you will get [1,10,12] not "1\n\f".
So I modify the codes into following. The result will be a tuple rather than a list.
-module(example).
-export([even/1]).
even(L) -> list_to_tuple(get_even(L)).
get_even([]) -> [];
get_even([H|T]) when H rem 2 == 0 -> [H | get_even(T)];
get_even([_|T]) -> get_even(T).
Let's compile and run the modified module:
3> example:even([10,11,12]).
{10,12}
If you want to convert a tuple to a list, use tuple_to_list() BIF.
I am reading Erlang Programming book. This is the solution of Exercise 2-3: Simple Pattern Matching. Following is the original question: Write a module boolean.erl that takes logical expressions and Boolean values (represented as the atoms true and false) and returns their Boolean result. The functions you write should include b_not/1, b_and/2, b_or/2, and b_nand/2. You should not use the logical constructs and, or, and not, but instead use pattern matching to achieve your goal.
Test your module from the shell. Some examples of calling the exported functions in your module include:
bool:b_not(false) => true
bool:b_and(false, true) => false
bool:b_and(bool:b_not(bool:b_and(true, false)), true) => true
The notation foo(X) => Y means that calling the function foo with parameter X will result in the value Y being returned. Keep in mind that and, or, and not are reserved words in Erlang, so you must prefix the function names with b_.
Hint: implement b_nand/2 using b_not/1 and b_and/2.
The solution is:-module(bool).
-export([b_not/1, b_and/2, b_or/2, b_nand/2]).
b_not(X) -> X == false.
b_and(X,Y) -> {true, true} == {X,Y}.
b_or(X,Y) -> b_not({false, false} == {X,Y}).
b_nand(X,Y) -> b_not(b_and(X,Y)).
Any better solutions?