Pergunta

Estou tentando entender a implementação de Lists 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)?

Foi útil?

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

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top