Fajne rzeczy w Scali: zwracanie funkcji

namiekko.pl 6 lat temu

Kontynuuję kurs programowania w języku Scala, o którym wspominałam w poprzednim wpisie. Zgodnie z obietnicą, pokazuję kolejną fajną rzecz, której się nauczyłam.

Funkcje, które zwracają funkcje!

W Scali funkcje są tzw. obywatelami pierwszej kategorii (ang. first class citizens). Inaczej, funkcje są pierwszoklasowe. Oznacza to, iż można z nimi robić wszystko to, co można robić z “normalnymi” typami danych, to jest: przekazywać jako argumenty, przypisywać do zmiennych, zwracać z funkcji, tworzyć je na bieżąco.

W szczególności, jedna funkcja może zwrócić inną. Poniżej przykład.

type Set = Int => Boolean def singletonSet(elem: Int): Set = (elem2: Int) => { elem == elem2 }

Na początku tworzymy alias o nazwie Set. Reprezentuje on typ funkcyjny: wszystkie funkcje pobierające parametr typu Int i zwracające wartość typu Boolean. W ten sposób chcemy, na potrzeby przykładu, reprezentować zbiory: jako funkcję, która dla każdej podanej liczby całkowitej powie nam, czy liczba ta należy do tego zbioru.

Jeśli nasz zbiór ma być zbiorem jednoelementowym (ang. singleton), to w zależności od tego, jaki to element, musielibyśmy utworzyć (nieskończenie) wiele funkcji sprawdzających, przynależność do zbioru – dla wszystkich możliwego elementu zbioru jednostkowego. Osobno dla zbioru zawierającego tylko liczbę 1, osobno dla liczby 2 itp. Dzięki możliwości zwracania funkcji, mamy tylko jedną funkcję, która tworzy i zwraca funkcję badającą przynależność do zbioru jednostkowego zawierającego wybrany element – przekazany jako parametr do funkcji singletonSet.

Jak to działa w praktyce?

test("singleton"){ val single = singletonSet(4) assert(single(4), "singleton contains") assert(!single(1), "singleton does not contain") }

Na początku testu tworzymy zbiór jednoelementowy zawierający liczbę całkowitą 4. Nasz zbiór – czyli funkcję pobierającą argument Int, zwróconą z funkcji singletonSet – przypisujemy do zmiennej (hm, stałej adekwatnie) single.

Następnie, wywołując funkcję przypisaną do zmiennej single, sprawdzamy, czy do zbioru {4} należą odpowiednio liczby 4 oraz 1. Zgodnie z oczekiwaniami, dla 4 otrzymujemy wartość true, dla 1 wartość false.

Idź do oryginalnego materiału