11.3. Funkcja jako argument
Skoro funkcje są wartościami, to można je przekazywać jako argumenty metod lub innych funkcji.
Plik Functions5.scala: def filter(f: (Int) => Boolean, list: List[Int]): List[Int] = (if (list.isEmpty) list else if(f(list.head)) list.head :: filter(f, list.tail) else filter(f, list.tail))
Metoda filter, zdefiniowana w pliku Functions5.scala, ma dwa parametry. Pierwszym parametrem jest funkcja przyjmująca argument typu Int i zwracająca wartość logiczną. Drugim parametrem jest lista wartości typu Int. Metoda wywołuje funkcję dla każdej wartości na liście i zwraca nową listę, zawierającą tylko te elementy z oryginalnej listy, dla których funkcja zwróciła wartość true. Poniższe polecenia tworzą funkcję porównującą liczbę z wartością 5 oraz używają tej funkcji w wywołaniu metody filter.
scala> :load Functions5.scala Loading Functions5.scala... filter: (f: Int => Boolean, list: List[Int])List[Int] scala> val above5 = (x: Int) => x > 5 above5: Int => Boolean = <function1> scala> filter(above5, List(3,4,5,6,7,8)) res0: List[Int] = List(6, 7, 8)
Wywołując metodę filter możemy jej przekazać funkcję zdefiniowaną bezpośrednio w wywołaniu, bez konieczności wcześniejszego przypisywania tej funkcji do jakiejś wartości, a więc funkcję anonimową.
scala> filter((x: Int) => x > 5, List(3,4,5,6,7,8)) res1: List[Int] = List(6, 7, 8)
Funkcja przekazywana do metody filter musi mieć odpowiedni typ. Następująca próba wywołania metody filter kończy się błędem z powodu złego typu funkcji przekazanej tej metodzie.
scala> filter((x: Long) => x > 5, List(3,4,5,6,7,8))
<console>:12: error: type mismatch;
found : Long => Boolean
required: Int => Boolean
filter((x: Long) => x > 5, List(3,4,5,6,7,8))
^
Metoda filter wymaga funkcji jednoargumentowej, która przyjmuje argument typu Int. Wobec tego próba przekazania jej funkcji przyjmującej argument typu Long zakończyła się błędem.
Plik Functions5.scala:
def filter(f: (Int) => Boolean, list: List[Int]): List[Int] =
(if (list.isEmpty) list
else if(f(list.head)) list.head :: filter(f, list.tail)
else filter(f, list.tail))
