Estoy tratando de entender lo que Scala hace con Case Classes que los hace de alguna manera inmunes a las advertencias de borrado de tipo.Scala: clase de caso unapply vs una implementación manual y tipo de borrado
Digamos que tenemos la siguiente estructura de clase simple. Se trata básicamente de un Either
:
abstract class BlackOrWhite[A, B]
case class Black[A,B](val left: A) extends BlackOrWhite[A,B]
case class White[A,B](val right: B) extends BlackOrWhite[A,B]
y que está tratando de utilizar de esta manera:
object Main extends App {
def echo[A,B] (input: BlackOrWhite[A,B]) = input match {
case Black(left) => println("Black: " + left)
case White(right) => println("White: " + right)
}
echo(Black[String, Int]("String!"))
echo(White[String, Int](1234))
}
Todo compila y se ejecuta sin ningún problema. Sin embargo, cuando intento implementar el método unapply
, el compilador lanza una advertencia. He utilizado la siguiente estructura de clases con la misma clase Main
arriba:
abstract class BlackOrWhite[A, B]
case class Black[A,B](val left: A) extends BlackOrWhite[A,B]
object White {
def apply[A,B](right: B): White[A,B] = new White[A,B](right)
def unapply[B](value: White[_,B]): Option[B] = Some(value.right)
}
class White[A,B](val right: B) extends BlackOrWhite[A,B]
Compilación de que con los temas bandera -unchecked
la siguiente advertencia:
[info] Compiling 1 Scala source to target/scala-2.9.1.final/classes...
[warn] src/main/scala/Test.scala:41: non variable type-argument B in type pattern main.scala.White[_, B] is unchecked since it is eliminated by erasure
[warn] case White(right) => println("White: " + right)
[warn] ^
[warn] one warning found
[info] Running main.scala.Main
Ahora, entiendo el tipo de borrado y yo he tratado de evitar la advertencia con Manifests
(en vano hasta ahora), pero ¿cuál es la diferencia entre las dos implementaciones? ¿Las clases de casos están haciendo algo que necesito agregar? ¿Se puede eludir esto con Manifests
?
Incluso he intentado ejecutar la implementación de la clase caso a través del compilador de Scala con la bandera -Xprint:typer
activada, pero el método unapply
ve muy parecido a lo que esperaba:
case <synthetic> def unapply[A >: Nothing <: Any, B >: Nothing <: Any](x$0: $iw.$iw.White[A,B]): Option[B] = if (x$0.==(null))
scala.this.None
else
scala.Some.apply[B](x$0.right);
Gracias de antemano
¿Estás Usando la última versión de Scala, no puedo reproducir su problema, y esta pregunta relacionada de hace unos meses determinó un problema similar al suyo como un error del compilador. Consulte http://stackoverflow.com/questions/7008428/difference -entre-home-made-extractor-and-case-class-extractor – Destin
Estoy usando 2.9.1.final (En Xubuntu 11.10, si es importante) – Nycto