czwartek, 21 kwietnia 2016

Erlang: Kilka słów o listach.


To pierwszy z serii artykułów Erlang: Kilka słów o ... .
Sam jeszcze zgłębiam tajniki Erlang'a ale ponieważ nie znalazłem zbyt dużo informacji w języku polskim postanowiłem coś napisać. Przy okazji mam nadzieje się nauczyć i zrozumieć więcej.

Podstawowy zapis listy w Erlang'u to:
[Element1, Element2, ...., ElementN]

Każdy z elementów może być różnego typu.
Taka lista [34,54,jakis_atom,{inny_atom,3,4}] jest jak najbardziej poprawna.

Każda lista ma swój element początkowy (ang. head) i resztę zwaną również "ogonem" (ang. tail).
Tworzymy nową listę.
1>NewList = [1,2,3,4].
[1,2,3,4]

Następnie wykorzystajmy konstrukcję [Head|Tail] i przypiszmy do tego stworzoną przed chwilą listę.
2>[Head|Tail] = NewList.
[1,2,3,4]

Użyty przez nas operator "|" to konstruktor.
A teraz przekonajmy się co jest elementem początkowym listy:
3>Head.
1
oraz resztą listy:
4>Tail.
[2,3,4]

Swoją drogą to samo możemy uzyskać z pomocą funkcji wbudowanych (ang. BIF - built-in functions) hd() oraz tl().

5>hd([1,2,3,4]
1
6>tl[1,2,3,4]
[2,3,4]

Listy można sklejać z użyciem operatora "++". Możemy również usuwać elementy listy z pomocą operatora "--".

7>[4,5,6] ++ [7,8].
[4,5,6,7,8]
8>[4,5,6,7,8] -- [4,5,6].
[7,8]

Kilka przykładowych funkcji z wykorzystaniem list (i nie tylko).
Sumowanie wszystkich elementów listy

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

Tworzenie listy liczb w zakresie od/do z podanym krokiem.

stworz_liste(Od,Do,Krok) when Od <= Do ->
   [Od|stworz_liste(Od + Krok,Do,Krok)];
stworz_liste(_Od,_Do,_Krok) ->
   [].

A teraz inna metoda pracy z listami. Chcemy z jednej listy stworzyć drugą listę, Każdy element drugiej listy ma być drugą potęgą odpowiadającego elementu z pierwszej listy.

Sposób pierwszy:

lista_kwadratow([]) ->
   [];
lista_kwadratow([H|T]) ->
   [H*H|lista_kwadratow(T).

Sposób drugi:

9>[N*N || N <- [1,2,3,4]].
[1,4,9,16]

Sposób drugi w  funkcji:

lista_kwadratow([H|T]) ->
   [X*X || X <- [H|T]].

A co jeśli chcielibyśmy jedynie podnieść do kwadratu liczby parzyste z danej listy - możemy dołożyć wyrażenie warunkowe.

10>[N*N || N <- [1,2,3,4], N rem 2 =:= 0].
[4,16]

Usuwanie elementu z listy:

remove(_X,[])->
    [];
remove(X,[X|Rest]) ->
    remove(X, Rest);
remove(X,[H|Rest]) ->
    [H|remove(X,Rest)].

Powyższy przykład (jak i pozostałe) można również wykonać wykorzystując funkcje z modułu lists. Listę funkcji dla tego modułu można znaleźć tutaj.

remove(X,[H,T]) ->
   lists:delete(X,[H|T]).

Artykuł na podstawie: Learn you some Erlang for great good.