This question was previously asked in scala-user mailing-list without a confirmed answer.
scala> val T = new Pair(1, 2){
override def equals(obj:Any) = obj.isInstanceOf[(Int, Int)] && obj.asInstanceOf[(Int, Int)]._1 == this._1}
}
T: (Int, Int) = (1,2)
scala> T match {
case (1, 1) => println("matched")
case _ => println("not matched")
}
not matched
scala> (1, 1) match {
case T => println("matched")
case _ => println("not matched")
}
not matched
scala> T == (1, 1)
res15: Boolean = true
I thought a constant(val) pattern matching result depends on the return value of “equals”, but the results show that it is not the case, then what is the criteria?
Someone had suggested that case (1, 1) => is an extractor pattern and uses Tuple2.unapply instead. so I tried these:
scala> Pair.unapply(T)
res1: Option[(Int, Int)] = Some((1,2))
scala> Pair.unapply(T).get == (1, 1)
res2: Boolean = true
Can anyone please explain why == get true but I cannot make them match?
With the resolution of #3888, I can give a final answer to this question.
T match { case (1, 1) =>No, it has nothing to do with
unapply. As extempore mentioned,case (1,1) =>is a ‘Tuple Pattern’, an alias for ‘Constructor Pattern” of case class Tuple2, It only matches value constructed as Tuple2(1, 1) or Pair(1, 1).What really concerns
unapplyis the ‘Extractor Pattern’:You get “matched”. Notice the
()in the case clause(1, 1) match { case T => ...according to scala spec, section 8.1.5, this is a ‘Stable Identifier Pattern’,
case Tmatches any value v such that T == v. So we SHOULD get “matched”. The “not matched” resultsare just caused by the bug in current compiler implementation.