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