I have to deal with classes defined in a lib like this (can't change it):
trait parent {
def joke: String
}
trait accountant {
def number: Int
}
case class Person1(val joke: String, val number: Int, val age: Int, val isSmart: Boolean) extends parent with accountant
case class Person2(val joke: String, val number: Int, val age: Int, val isStrong: Boolean) extends parent with accountant
case class Person3(val joke: String, val age: Int, val isTall: Boolean) extends parent
I will need to do some calculation based on the fields value and emit a signal defined in the API like this (can't change it):
trait MySignal
case class GotPerson1() extends MySignal
case class GotPerson2() extends MySignal
Keep in mind that this is a scaled-down example, there is around 10 different PersonX, there is some common calculation to be done to some pairs/group of these Person types:
class DoingWork(message: parent) {
type WithAge = {def age: Int, def number: Int}
def dispatcher(msg: parent) = {
msg match {
case something: Person1 => doSomeMapping(something)
case something: Person2 => doSomeMapping(something)
case something: Person3 => doSomethingElse(something)
}
}
def doSomeMapping(msg: WithAge): MySignal = {
// do some common cal based on WithAge fields
if(msg.number > 10 && msg.isInstanceOf[Person1]) GotPerson1()
else if(msg.number > 10 && msg.isInstanceOf[Person2]) GotPerson2()
else throw new RuntimeException()
}
def doSomethingElse(msg: Person3): Unit = println("blah")
}
To avoid replicating the code of common calculation, I introduced type WithAge but because I have to emit different signals based on the type, I have to test for type.
How can I avoid the isInstanceOf test in doSomeMapping?
Can I pass the MySignal subtype as parameter in doSomeMapping to allow the function to instantiate it?