I have an abstract class named Bdd
sealed abstract class Bdd (ident:Int) {
}
I’m using a sealed class in hopes of getting warnings on non-exhaustive pattern matching.
I’ve included (ident:Int)
in the initialization arguments because all the subclasses have such an initialization argument.
I’m trying to define an object of the same name Bdd
(perhaps that is mistake?)
But in this situation, IntelliJ complains of errors in the call to hash.get(...)
, and the compiler gives a similar error.
If I change the declaration from sealed abstract class Bdd
to sealed abstract case class
, then the type mismatch goes away, but I get a compiler error which InteliJ was not able to predict.
Error:(116, 12) case class BddNode has case ancestor Bdd, but case-to-case inheritance is prohibited. To overcome this limitation, use extractors to pattern match on non-leaf nodes.
case class BddNode(label:Int, positive:Bdd, negative:Bdd) extends Bdd(Bdd.nextCount()) {
I think there is some fundamental concept I’m missing. Since, I’ve declared positive
and negative
of type Bdd
, why doesn’t it know that positive.ident
is an Int
?
Here is the actual code.
object Bdd {
var count = 2
def nextCount():Int = {
count += 1
count - 1
}
val hash = mutable.Map.empty[(Int,Int,Int),BddNode]
def bdd(label:Int):Bdd = {
bdd(label,BddTrue,BddFalse)
}
def bdd(label:Int,positive:Bdd,negative:Bdd):Bdd = {
if (positive eq negative)
positive
else {
// Type mismatch: expected: (Int,Int,Int) actual: (Int,Any,Any)
hash.get((label, positive.ident, negative.ident)) match {
case Some(bdd: BddNode) => bdd
case None => {
val bdd = BddNode(label,positive,negative)
hash((label,positive.ident,negative.ident)) = bdd
bdd
}
}
}
}