parent
e05f92d764
commit
46c5fafa4f
|
@ -0,0 +1,23 @@
|
||||||
|
%% chapter 5: maps and records
|
||||||
|
-module(chapter5).
|
||||||
|
-include("records.hrl").
|
||||||
|
-export([make_urgent/1, count_characters/1]).
|
||||||
|
|
||||||
|
%% Maps are defined with a #{ Key => Value, ... } syntax
|
||||||
|
%% =>: update existing key or add new key
|
||||||
|
%% :=: update existing key
|
||||||
|
|
||||||
|
make_urgent(M) ->
|
||||||
|
M#{status := urgent}.
|
||||||
|
|
||||||
|
%% Valid: make_urgent(#{status => reminder, who => kyle}).
|
||||||
|
%% Invalid: make_urgent(#{who => kyle}).
|
||||||
|
|
||||||
|
count_characters(Str) ->
|
||||||
|
count_characters(Str, #{}).
|
||||||
|
count_characters([H|T], #{ H := N }=X) ->
|
||||||
|
count_characters(T, X#{H := N + 1});
|
||||||
|
count_characters([H|T], X) ->
|
||||||
|
count_characters(T, X#{H => 1});
|
||||||
|
count_characters([], X) -> X.
|
||||||
|
|
|
@ -0,0 +1,45 @@
|
||||||
|
-module(error_test).
|
||||||
|
-export([generate_exc/1, demo1/0, demo2/0, demo3/0, catcher/1]).
|
||||||
|
|
||||||
|
generate_exc(1) -> a;
|
||||||
|
generate_exc(2) -> throw(a);
|
||||||
|
generate_exc(3) -> exit(a);
|
||||||
|
generate_exc(4) -> {'EXIT', a};
|
||||||
|
generate_exc(5) -> error(a).
|
||||||
|
|
||||||
|
demo1() ->
|
||||||
|
[catcher(I) || I <- lists:seq(1, 5)].
|
||||||
|
|
||||||
|
demo2() ->
|
||||||
|
[{I, (catch generate_exc(I))} || I <- [1,2,3,4,5]].
|
||||||
|
|
||||||
|
catcher(N) ->
|
||||||
|
try generate_exc(N) of
|
||||||
|
Val -> {N, normal, Val}
|
||||||
|
catch
|
||||||
|
throw:X -> {N, caught, thrown, X};
|
||||||
|
exit:X -> {N, caught, exited, X};
|
||||||
|
error:X -> {N, caught, error, X}
|
||||||
|
end.
|
||||||
|
|
||||||
|
|
||||||
|
%% NB: catch _ -> ... assumes default tag throw, need to specify
|
||||||
|
%% catch _:_ -> ...
|
||||||
|
|
||||||
|
demo3() ->
|
||||||
|
try generate_exc(5)
|
||||||
|
catch
|
||||||
|
error:X ->
|
||||||
|
{X, erlang:get_stacktrace()}
|
||||||
|
end.
|
||||||
|
|
||||||
|
%% In Erlang, when an error is detected internally by the system or is
|
||||||
|
%% detected by program logic, the correct approach is to crash
|
||||||
|
%% immediately and generate a meaningful error message. We crash
|
||||||
|
%% immediately so as not to make matters worse. The error message should
|
||||||
|
%% be written to a permanent error log and be sufficiently detailed so
|
||||||
|
%% that we can figure out what went wrong later.
|
||||||
|
%%
|
||||||
|
%% Second, fail politely means that only the programmer should see the
|
||||||
|
%% detailed error messages produced when a program crashes. A user of the
|
||||||
|
%% program should never see these messages.
|
|
@ -0,0 +1,32 @@
|
||||||
|
-module(math_functions).
|
||||||
|
-export([even/1, odd/1, filter/2, split/1, splitacc/1]).
|
||||||
|
|
||||||
|
even(N) ->
|
||||||
|
N rem 2 == 0.
|
||||||
|
|
||||||
|
odd(N) ->
|
||||||
|
N rem 2 /= 0.
|
||||||
|
|
||||||
|
filter(F, [H|T]) ->
|
||||||
|
case F(H) of
|
||||||
|
true -> [H | filter(F, T)];
|
||||||
|
false -> filter(F, T)
|
||||||
|
end;
|
||||||
|
filter(_, []) ->
|
||||||
|
[].
|
||||||
|
|
||||||
|
split(L) ->
|
||||||
|
{filter(fun (N) -> even(N) end, L),
|
||||||
|
filter(fun (N) -> odd(N) end, L)}.
|
||||||
|
|
||||||
|
splitacc_inner([], Even, Odd) -> {Even, Odd};
|
||||||
|
splitacc_inner([H|T], Even, Odd) ->
|
||||||
|
case even(H) of
|
||||||
|
true ->
|
||||||
|
splitacc_inner(T, [H|Even], Odd);
|
||||||
|
false ->
|
||||||
|
splitacc_inner(T, Even, [H|Odd])
|
||||||
|
end.
|
||||||
|
|
||||||
|
|
||||||
|
splitacc(L) -> splitacc_inner(L, [], []).
|
|
@ -0,0 +1 @@
|
||||||
|
-record(todo, {status=reminder, who=kyle, text}).
|
Loading…
Reference in New Issue