Decomposizione partita Scala su operatore infisso
-
06-07-2019 - |
Domanda
Sto cercando di capire l'implementazione di List
in Scala. In particolare sto cercando di capire come è possibile scrivere espressioni di corrispondenza usando un operatore infix, ad esempio:
a match {
case Nil => "An empty list"
case x :: Nil => "A list without a tail"
case x :: xs => "A list with a tail"
}
In che modo è possibile che l'espressione della corrispondenza sia x :: xs
anziché List (x, xs)
?
Soluzione
La risposta di Jay Conrad è quasi giusta. L'importante è che da qualche parte vi sia un oggetto chiamato ::
che implementa il metodo unpply
, restituendo il tipo Option [(A, lista [A])]
. Questa convenzione:
object :: {
def unapply[A](ls: List[A]): Option[(A, A)] = {
if (ls.empty) None
else Some((ls.head, ls.tail))
}
}
// case objects get unapply for free
case object Nil extends List[Nothing]
Nel caso di ::
e List
, questo oggetto sembra derivare dal fatto che ::
è una classe case che estende il tratto List
. Tuttavia, come mostra l'esempio sopra, non deve essere affatto una classe case.
Altri suggerimenti
Credo che :: è in realtà una classe (che è una sottoclasse dell'elenco ), quindi dire x :: xs
equivale in gran parte a List (x, xs)
.
Puoi farlo con altre classi di casi che hanno nomi di operatori. Ad esempio:
case class %%%(x: Int, y: Int)
a match {
case x %%% y => x + y
}
In che modo è possibile che l'espressione della corrispondenza sia x :: xs anziché List (x, xs)?
Per rispondere a questa domanda:
Se visto come un modello , un infisso un'operazione come p op q è equivalente su op (p, q) . Cioè, l'informazione l'operatore op è trattato come a modello di costruzione .
(Programmazione in Scala, 1a ed., p. 331)
Vedi anche domande sulle classi di scala case