I have a class which gets serialized and deserialized in a session, and I need to perform pattern matching on inner classes. I am having problems with the identity of the inner classes:
class Tree(val id: Int) {
override def hashCode = id
override def equals(that: Any) = that.isInstanceOf[Tree] &&
that.asInstanceOf[Tree].id == id
case object EmptyValue
}
val t1 = new Tree(33)
val t2 = new Tree(33)
t1 == t2 // ok
t1.EmptyValue == t2.EmptyValue // wrong -- reports 'false'
What is an elegant way to fix the identity for EmptyValue to not ‘escape path dependency’ so to speak. I have code like the following which breaks when serialization is taking place:
def insert(point: Point, leaf: Leaf): Unit = {
val qidx = hyperCube.indexOf(point)
child(qidx) match {
case EmptyValue => ...
...
}
}
That is, although the compiler says my match is exhaustive, I get a runtime MatchError when using serialization (I am having custom code that writes to/reads from byte arrays). For example, I am calling from within the tree having Tree$EmptyValue$@4636 and retrieve a Tree$EmptyValue$@3601 and they don’t match.
EDIT
I have conducted further tests, because I would really like to avoid having to move the inner types out, as they will need to have type parameters and thus break all pattern matching code. It looks as if the problem only occurs with that particular case object:
class Tree {
sealed trait LeftChild
case object EmptyValue extends LeftChild
sealed trait LeftNonEmpty extends LeftChild
final case class LeftChildBranch() extends LeftNonEmpty
def testMatch1(l: LeftChild) = l match {
case EmptyValue => "empty"
case LeftChildBranch() => "non-empty"
}
def testMatch2(l: LeftChild) = l match {
case EmptyValue => "empty"
case n: LeftNonEmpty => "non-empty"
}
}
val t1 = new Tree
val t2 = new Tree
t1.testMatch1(t2.LeftChildBranch().asInstanceOf[t1.LeftChild]) // works!!!
t1.testMatch2(t2.LeftChildBranch().asInstanceOf[t1.LeftChild]) // works!!!
t1.testMatch1(t2.EmptyValue.asInstanceOf [t1.EmptyValue.type]) // fails
Existential type could express this.
Bytecode for
equals: