I’m currently wondering about composing an object/class/trait that conforms to one trait for multiple type parameters.
Let’s say I have
trait Dependent[T]{
def observeCritereaChanged(oldValue:T, newValue:T):Unit
}
I would like to be able to define some trait that implements Dependent for two different type parameters, for example
trait IntStrDependent extends Dependent[Int] with Dependent[String]
So that instances of my IntStrDependent trait would have to define the observeCritereaChanged for both types:
class MyDependent extends IntStrDependent {
def observeCritereaChanged(oldValue:Int, newValue:Int) = //...
def observeCritereaChanged(oldValue:String, newValue:String) = //...
}
So far my efforts have been met with a compile error when trying to create the IntStrDependent trait:
scala> trait IntStrDependent extends Dependent[Int] with Dependent[String]
<console>:8: error: illegal inheritance;
self-type IntStrDependent does not conform to Dependent[Int]'s selftype Dependent[Int]
trait IntStrDependent extends Dependent[Int] with Dependent[String]
^
<console>:8: error: illegal inheritance;
self-type IntStrDependent does not conform to Dependent[String]'s selftype Dependent[String]
trait IntStrDependent extends Dependent[Int] with Dependent[String]
^
So my question is: Is there a way to do what I’m trying to do (if so, how) or is this a lost cause because Scala isn’t built to do this kind of thing?
Good question. I don’t think you can do what you want directly.
One alternative approach is
trait IntStrDependent extends Dependent[Either[Int, String]]but that doesn’t quite solve the problem. Maybe a variant of Miles Sabin’s encoding of union types allows something fancier to be done.I think the best option is to keep it simple,
To use
MyDependent, one must explicitly select theIntorStringvariant, as inIn my opinion, making the type dependence explicit is a good thing anyway.