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