erang wokshop ii

32
Erlang/OTP Workshop Programowanie funkcyjne w Erlangu 19.01.2011r. Arek Flinik [email protected] Wrocławska grupa użytkowników Erlanga KNSI PPT środa, 19 stycznia 2011

Upload: knsi

Post on 12-May-2015

447 views

Category:

Technology


0 download

TRANSCRIPT

Page 1: Erang wokshop II

Erlang/OTP WorkshopProgramowanie funkcyjne w Erlangu 19.01.2011r.

Arek Flinik [email protected]

Wrocławska grupa użytkowników Erlanga

KNSIPPT

środa, 19 stycznia 2011

Page 2: Erang wokshop II

Ściągawka

W pliku: -module(przyklad). -compile(export_all).

W shellu: Eshell V5.7.21>c(przyklad).{ok,test}2>

środa, 19 stycznia 2011

Page 3: Erang wokshop II

Programowanie funkcyjneAlonzo Church1930rachunek lambda

alewolimy myśleć jak o funkcjach matematycznych

środa, 19 stycznia 2011

Page 4: Erang wokshop II

Programowanie funkcyjne

silnia(N) -> if

N=:=0 -> 1; N > 0 -> N*silnia(N-1)

end

silnia(x) = { 1 jeśli n=0n*silnia(n-1) jeśli n>0

środa, 19 stycznia 2011

Page 5: Erang wokshop II

Funkcje w Erlangu

function(X) ->Expression.

Pattern Matchingfunction(X) ->Expression;function(Y) ->Expression;function(_) ->Expression.

środa, 19 stycznia 2011

Page 6: Erang wokshop II

Guard (czyli strażnik)

sprzedaj_piwo(Wiek) when Wiek >= 18 -> true;sprzedaj_piwo(_) -> false.

środa, 19 stycznia 2011

Page 7: Erang wokshop II

If-Then-Elseczyli da się inaczej

sprzedaj_piwo(Wiek) -> if Wiek >= 18 -> tak; Wiek >= 15 -> moze; true -> nie end.

środa, 19 stycznia 2011

Page 8: Erang wokshop II

If-Then-Elseczyli da się inaczej

sprzedaj_piwo2(Wiek) -> if Wiek >= 15 -> moze; Wiek >= 18 -> tak; true -> nie end. 1>sprzedaj_piwo2(20).moze

co się stanie?

środa, 19 stycznia 2011

Page 9: Erang wokshop II

If-Then-Elseczyli da się inaczejsprzedaj_piwo(Wiek) -> if Wiek >= 18 -> tak; Wiek >= 15 -> moze; true -> nie end.

sprzedaj_piwo3(Wiek) -> if Wiek >= 18 -> tak; Wiek >= 15 -> moze; Wiek < 15 -> nie end.

Lepiej:

środa, 19 stycznia 2011

Page 10: Erang wokshop II

Guard expressionsMożemy używać tylko:

porównań zmiennych, operatorów logicznych, wyrażeń arytmetycznych

Oraz BIFów:is_atom/1, is_binary/1, is_bitstring/1, is_float/1, is_function/1, is_function/2, is_integer/1, is_list/1, is_number/1, is_pid/1, is_port/1, is_record/2,

is_record/3, is_reference/1, is_tuple/1,abs(Number), bit_size(Bitstring), byte_size

(Bitstring), element(N, Tuple), float(Term), hd(List), length(List), node(), node(Pid|Ref|Port), round(Number), self(), size(Tuple|Bitstring), tl

(List), trunc(Number), tuple_size(Tuple),

środa, 19 stycznia 2011

Page 11: Erang wokshop II

Case

na_plazy(Temperatura) ->case Temperatura of {celsius, N} when N >= 18, N =< 45 -> 'jest ok'; {kelvin, N} when N >= 293, N =< 318 -> 'jest ok'; {fahrenheit, N} when N >= 68, N =< 113 -> 'jest ok... w USA'; _ -> 'lepiej tam nie isc'end.

środa, 19 stycznia 2011

Page 12: Erang wokshop II

Casea co gdy chcemy sprawdzić warunek za pomocą funkcji, która nie należy do dozwolonych?wiek_ok(Wiek) when Wiek > 17 -> true;wiek_ok(_) -> false. sprzedaj_piwo(Wiek) when wiek_ok(Wiek) -> ... * 1: illegal guard expression

sprzedaj_piwo(Wiek) -> Ok = wiek_ok(Wiek), case Ok of false -> nie; true -> tak end.

środa, 19 stycznia 2011

Page 13: Erang wokshop II

Przypomnienie: listy

Lista = [1,2,3,5][H|T] = ListaH = 1T = [2,3,5]

środa, 19 stycznia 2011

Page 14: Erang wokshop II

Przypomnienie: listy

Lista = [1,2,3,5][H|T] = ListaH = 1T = [2,3,5]

Lista2 = [a][H2|T2] = Lista2H2 = aT2 =[]

środa, 19 stycznia 2011

Page 15: Erang wokshop II

Przypomnienie: listy

Konkatenacja: operator ++

1>[1,2,3] ++ [4,5]. [1,2,3,4,5]

Uwaga: działa wolno, więc unikamy gdzie tylko to możliwe!

środa, 19 stycznia 2011

Page 16: Erang wokshop II

Rekurencja

factorial(0) -> 1;factorial(N) -> N * factorial(N-1).

środa, 19 stycznia 2011

Page 17: Erang wokshop II

Rekurencja - efektywność?tail recursion

int fact(int n){ if(n>1){ return n*fact(n-1); } else{ return 1; }}

int fact2(int n, int acc){ if(n>1){ return fact2(n-1, acc*n); } else{ return acc; }}

środa, 19 stycznia 2011

Page 18: Erang wokshop II

Rekurencja - efektywność?tail recursion

Podobnie w erlangu:

factorial(0) -> 1;factorial(N) -> N * factorial(N-1).

factorial(1, Acc) -> Acc;factorial(N, Acc) -> factorial(N-1, N*Acc).

factorial(N) -> factorial(N,1).

środa, 19 stycznia 2011

Page 19: Erang wokshop II

Jak operujemy na listach?

int suma = 0;for (i=0;i<10; i++) { suma += tab[i];}

środa, 19 stycznia 2011

Page 20: Erang wokshop II

Jak operujemy na listach? int suma = 0;for (i=0;i<10; i++) { suma += tab[i];}

sum([]) -> 0; sum([H|T]) -> H + sum(T).

środa, 19 stycznia 2011

Page 21: Erang wokshop II

Ćwiczenie: reverseDane: lista T np: [3,1,4,1,5]

Wynik: odwrócona lista T np: [5,1,4,1,3]

Eshell V5.7.21>reverse([a,b,c,d,e]).[e,d,c,b,a].2>

środa, 19 stycznia 2011

Page 22: Erang wokshop II

Ćwiczenie: reverse

reverse([]) -> [];reverse([H|T]) -> reverse(T) ++ [H].

środa, 19 stycznia 2011

Page 23: Erang wokshop II

Ćwiczenie: reverse

reverse([]) -> [];reverse([H|T]) -> reverse(T) ++ [H].

Da się lepiej!

środa, 19 stycznia 2011

Page 24: Erang wokshop II

Ćwiczenie: reverse

reverse([]) -> [];reverse([H|T]) -> reverse(T) ++ [H].

reverse([], Acc) -> Acc;reverse([H|T], Acc) -> reverse(T, [H|Acc]).

reverse(List) -> reverse(List, []).

środa, 19 stycznia 2011

Page 25: Erang wokshop II

List Comprehensions

{3×n : n ∈ {1,2,3,4} } = {3,6,9, 12}

1> [3*N || N <- [1,2,3,4]].[3,6,9,12]2> [2*X-Y || X <- [1,2,3,4], Y <- [1,0]]. [1,2,3,4,5,6,7,8]

środa, 19 stycznia 2011

Page 26: Erang wokshop II

List Comprehensionstrochę trudniejszy przykład

qsort([Pivot|T]) ->qsort([ X || X <- T, X < Pivot]) ++[Pivot] ++qsort([ X || X <- T, X >= Pivot]);qsort([]) -> [].

środa, 19 stycznia 2011

Page 27: Erang wokshop II

List Comprehensionstrochę trudniejszy przykład

qsort([Pivot|T]) ->sort([ X || X <- T, X < Pivot]) ++[Pivot] ++sort([ X || X <- T, X >= Pivot]);qsort([]) -> [].

Znaczniekrócej

niż w

C/C#/

Javie...

środa, 19 stycznia 2011

Page 28: Erang wokshop II

Zadanie!

Napiszmy prostą bazę danych operującą na liście krotek. Przykładowa baza:[{zygfryd, 505123456}, {zuza, 661009988}, {alarm, 911}]

środa, 19 stycznia 2011

Page 29: Erang wokshop II

Zadanie!Napiszmy prostą bazę danych operującą na liście krotek. Przykładowa baza:[{zygfryd, 505123456}, {zuza, 661009988}, {alarm, 911}]

Zaimplementuj funkcje:create/1 create(Pair) -> {ok,NewDb}insert/2 insert(Db, Pair) -> NewDb find/2 find(Db, Key) -> {Key, Value}delete/2 delete(Db, Key) -> {NewDb, {Key, Value}}update/3 update(Db, Key, Value) -> NewDB

gdzie: Db, NewDb - to baza taka jak zdefiniowana powyżej, pair - {Key, Value}

środa, 19 stycznia 2011

Page 30: Erang wokshop II

Zadanie domowe!Zmodyfikujmy bazę, aby mogła przechowywać kilka par z takim samym kluczem.

Zaimplementuj funkcje używając list comprehensions:

find_all/2 (zwraca listę krotek o danym kluczu)find_all(Db, Key) -> [{Key, Value}, {Key, Value2}...]

delete_all/2 (usuwa wszystkie krotki o danym kluczu)delete_all(Db, Key) -> {NewDb, [{Key, Value}, {Key, Value2}, ...]}

środa, 19 stycznia 2011

Page 31: Erang wokshop II

Zadanie domowe!Zmodyfikujmy bazę, aby mogła przechowywać kilka par z takim samym kluczem.

Dla ambitnych!

update_all/3 update_all(Db, Key, Function) -> NewDB

Trzecim argumentem jest funkcja, która powinna być zaaplikowana do

wszystkich krotek z pasującym kluczem. update_all([{a,4}, {b,3}, {a,6}], a, fun(X) -> 2*X end).[{a,8}, {b,3}, {a,12}]

środa, 19 stycznia 2011

Page 32: Erang wokshop II

Dziękuję!

[email protected]@gmail.com

środa, 19 stycznia 2011