Question

J'essaie de comprendre la mise en oeuvre de List dans Scala. En particulier, j'essaie de comprendre comment vous pouvez écrire des expressions de correspondance à l'aide d'un opérateur infixe, par exemple:

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

Comment l'expression de correspondance est-elle autorisée à être x :: xs plutôt que List (x, xs) ?

Était-ce utile?

La solution

La réponse de Jay Conrad est presque exacte. L’important est que quelque part se trouve un objet nommé :: qui implémente la méthode unapply , renvoyant le type Option [(A, Liste [A])] . Ainsi:

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]

Dans le cas de :: et de List , cet objet découle du fait que :: est une classe de cas qui étend le trait List . Cependant, comme le montre l'exemple ci-dessus, il n'est pas obligé d'être une classe de cas.

Autres conseils

Je crois que :: est en fait une classe (qui est une sous-classe de List ), en disant x :: xs est généralement équivalent à List (x, xs) .

Vous pouvez le faire avec d'autres classes de cas ayant des noms d'opérateur. Par exemple:

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

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

Comment l'expression de correspondance est-elle autorisée à être x :: xs plutôt que List (x, xs)?

Pour répondre à cette question:

  

Vu comme un motif , un infixe   une opération telle que p op q est équivalente   sur op (p, q) . C'est-à-dire l'infix   opérateur op est traité comme un    modèle de constructeur .

(Programmer en Scala, 1re éd., p. 331)

Voir aussi les questions sur les cas-clés scala

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top