I have a class and two case subclasses:
abstract class C
case class C1(left: C, right: C, weight: Int) extends C
case class C2(weight: Int) extends C
I want to implement something like the following:
def weight(t: C): Int = {
t match {
case c1: C1 => l.weight
case c2: C2 => c2.left.weight + c1.right.weight //this line doesn't let the code compile
}
}
The above code does not compile. says left and right do not have attribute weight. I am seeing this because C does not have a weight defined for it. Only c1 and c2 do. However, the class instances that I pass to the weight function would be either c1 or c2 and would definitely have weight.
It is actually a recursive weight summation on a tree that I can achieve with the following:
def weight(t: C): Int = {
t match {
case c1: C1 => l.weight
case c2: C2 => weight(c2.left) + weight(c1.left)
}
}
But, I do not want to recurse and I do not think I should have to if the weight information is simply there available in the instance that I am passing in.
It is an assignment question that I am trying to solve and the signature of classes C, C1 and C2 are sacrosanct. I have tried modifying
abstract class C
to
abstract class C:
val weight: Int = ???
However, this then starts raising issues with the weight variable in the C1 and C2 signatures and asks me to override it.
The one solution I tried and thought would work was creating a companion object:
abstract class CodeTree
object CodeTree:
val weight: Int = ???
case class Fork(left: CodeTree, right: CodeTree, chars: List[Char], weight: Int) extends CodeTree
case class Leaf(char: Char, weight: Int) extends CodeTree
But I think the companion objects are not inherited by the subclasses
- How do I achieve the desired outcome without having to recurse?
- More broadly, How do I endow an abstract class with -- this particular field would always be available in the subclasses that inherit from me and hence it should be available statically with me and not fail compilation?
You should add member
weight: InttoCThen you can match typed patterns
or constructor patterns
Why do we have a need for separate case identifiers in case of type only matching in scala?
Normally abstract members are
defs and overriden withdef/val/lazy val(varif necessary) in implementations.