Pregunta

Estoy tratando de entender la implementación de List s en Scala. En particular, estoy tratando de entender cómo puedes escribir expresiones de coincidencia utilizando un operador infijo, por ejemplo:

a match {
  case Nil => "An empty list"
  case x :: Nil => "A list without a tail"
  case x :: xs => "A list with a tail"
}

¿Cómo se permite que la expresión de coincidencia sea x :: xs en lugar de List (x, xs) ?

¿Fue útil?

Solución

La respuesta de Jay Conrad es casi correcta. Lo importante es que en algún lugar hay un objeto llamado :: que implementa el método unapply , devolviendo el tipo Option [(A, Lista [A])] . Por lo tanto:

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]

En el caso de :: y List , este objeto resulta del hecho de que :: es una clase de caso que extiende el rasgo List . Sin embargo, como muestra el ejemplo anterior, no tiene que ser una clase de caso en absoluto.

Otros consejos

Creo que :: es en realidad una clase (que es una subclase de Lista ), por lo que decir x :: xs es mayormente equivalente a List (x, xs) .

Puede hacer esto con otras clases de casos que tienen nombres de operador. Por ejemplo:

case class %%%(x: Int, y: Int)

a match {
  case x %%% y => x + y
}
  

¿Cómo se permite que la expresión de coincidencia sea x :: xs en lugar de List (x, xs)?

Para responder esta pregunta:

  

Cuando se ve como un patrón , un infijo   operación como p op q es equivalente   a op (p, q) . Es decir, el infijo   El operador op se trata como un    patrón constructor .

(Programación en Scala, 1ª ed., p. 331)

Consulte también preguntas sobre las clases de casos de scala

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top