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