Il y a vraiment deux questions ici:
- Pourquoi
x == y
typecheck dans votre REPL?
- Pourquoi sont-ils égaux?
x == y
parce ==
compile à Scala est de type pas en sécurité:
scala> "x" == 1
res4: Boolean = false
Alors pourquoi ils ne correspondraient l'autre? Un Option
Scala est conceptuellement similaire à un type de données dans Haskell Algébrique:
data Maybe a = Nothing | Just a
Mais si vous regardez le Option.scala source, vous verrez qu'un Option
est défini (un peu, simplifie) comme:
sealed abstract class Option[+A] extends Product with Serializable
final case class Some[+A](x: A) extends Option[A]
case object None extends Option[Nothing]
Du côté Some
, vous pouvez voir une classe de cas avec le type paramétré +A
- de sorte qu'un Option[Int]
devient Some[Int]
.
Cependant, du côté None
, vous voyez un objet Option[Nothing]
, donc un noneish Option[Int]
et un noneish Option[String]
deux deviennent un objet Option[Nothing]
, et par conséquent égale les uns des autres.
Comme @TravisBrown souligne, Scalaz attrape ce beaucoup plus tôt, au moment de la compilation:
scala> import scalaz._
scala> import Scalaz._
scala> val x: Option[String] = None
scala> val y: Option[Int] = None
scala> x === y
<console>:16: error: could not find implicit value for parameter F0: scalaz.Equal[Object]
x === y
scala> val z: Option[String] = None
scala> x === z
res3: Boolean = true
J'imagine que cela a aussi à voir avec l'effacement de type. Au moment de l'exécution, la JVM ne connaît rien au générique (sauf si vous faites des choses avec 'ClassTag' et ses semblables.) –