Decomposição de correspondência Scala no operador de infix
-
06-07-2019 - |
Pergunta
Estou tentando entender a implementação de List
s em scala. Em particular, estou tentando entender como você pode escrever expressões de correspondência usando um operador de infix, por exemplo:
a match {
case Nil => "An empty list"
case x :: Nil => "A list without a tail"
case x :: xs => "A list with a tail"
}
Como a expressão de correspondência é permitida x :: xs
ao invés de List(x, xs)
?
Solução
A resposta de Jay Conrad está quase certa. O importante é que em algum lugar há um objeto nomeado ::
que implementa o unapply
Método, tipo de retorno Option[(A, List[A])]
. Assim:
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]
No caso de ::
e List
, esse objeto acontece do fato de que ::
é uma classe de caso que estende o List
característica. No entanto, como mostra o exemplo acima, não tenho ser uma aula de caso.
Outras dicas
Eu acredito :: é realmente uma aula (que é uma subclasse da lista), assim dizendo x :: xs
é principalmente equivalente a List(x, xs)
.
Você pode fazer isso com outras classes de caso que possuem nomes de operadores. Por exemplo:
case class %%%(x: Int, y: Int)
a match {
case x %%% y => x + y
}
Como a expressão de correspondência é permitida x :: xs em vez de list (x, xs)?
Para responder a esta pergunta:
Quando visto como um padronizar, uma operação de infix como P OP q é equivalente a OP (P, Q). Isto é, o operador de infix OP é tratado como um padrão construtor.
(Programação em Scala, 1ª ed., P. 331)
Veja também Questões de classes de casos scala