Similmente al meccanismo dei tre punti (...
) di Java, Scala permette di indicare che l’ultimo argomento di una funzione o di un costruttore può essere ripetuto, scrivendo *
dopo il tipo del parametro; ad esempio:
case class Person(name: String, isMale: Boolean, children: Person*)
Tale parametro prende il nome di repeated parameter, e permette all’utente di fornire una lista di argomenti variabile; ad esempio:
val lara = Person("Lara", false)
val bob = Person("Bob", true)
val julie = Person("Julie", false, lara, bob)
Nel codice, un repeated parameter di tipo T
è accessibile come una sequenza di tipo Seq[T]
.
Data la lista di persone
val persons = List(lara, bob, julie)
si vuole costruire la lista di tutte le coppie di nomi (madre, figlio/a) per tutte le madri contenute in persons
. Ciò può essere fatto usando i metodi all’ordine superiore di List
(ovvero di Seq
):
persons
per escludere i maschi, che non possono essere madrimap
per trasformare la sequenza di figli di una persona in una sequenza di coppie di nomi di madre e figlio/a, e ciò viene fatto per ogni persona nella lista filtrata usando flatMap
, in modo da ottenere complessivamente una singola sequenza di coppie invece che una sequenza di sequenze.persons filter (p => !p.isMale) flatMap (p =>
p.children map (c => (p.name, c.name))
) // res0: List[(String, String)] = List((Julie,Lara), (Julie,Bob))
Quest’esempio mostra che i metodi all’ordine superiore, seppur estremamente potenti, non sempre sono semplici da scrivere o da comprendere: la sematica delle operazioni effettuate qui è un po’ nascosta dall’interazione non banale tra i metodi filter
, flatMap
, e map
coinvolti nel presente frammento di codice.
L’uso dei metodi all’ordine superiore tende a diventare più facile con l’abitudine, ma comunque Scala fornisce dello zucchero sintattico che permette di esprimere in una forma più chiara combinazioni di map
, flatMap
e filter
: le for expression. Una for expression ha la forma generale
$$ \texttt{for (s) yield e} $$
oppure
$$ \texttt{for \{s\} yield e} $$
dove:
s
è una sequenza di generatori, definizioni e filtri, che devono essere separati da ;
(punto e virgola) nella versione della sintassi con le parentesi tonde, mentre nella versione con le parentesi graffe gli possono anche essere separati scrivendone uno per riga di testo, e in tal caso i ;
sono opzionali