Reputation: 1342
I have the following problem: I would like to have an 'instance' (parameterized trait) and 'configuration', and the latter is parameterized by the instance type:
trait Kind
trait Kind1 extends Kind
trait Kind2 extends Kind
trait Instance[T <: Kind] {
def configuration: InstanceConfiguration[Instance[_]]
}
trait InstanceConfiguration[+T <: Instance[_]] {
}
class AInstance extends Instance[Kind1] {
override def configuration: AConfiguration = ???
}
class AConfiguration extends InstanceConfiguration[AInstance] {
}
class BInstance extends Instance[Kind1] {
override def configuration: AConfiguration = ???
}
So, the issue is that InstanceConfiguration[Instance[Kind2]]
cannot be used as a configuration for Instance[Kind1]
, but now it is too generic, and I'd like compiler to give out error on BInstance.configuration
.
So how do I change definition of configuration in the Instance trait to reference the concrete InstanceConfiguration of the concrete type?
Upvotes: 1
Views: 651
Reputation: 13667
You need to use F-Bounded polymophism. I recommend reading the section in Twitter's Scala School, but in brief, Instance
needs to take the concrete type as a type parameter:
trait Kind
trait Kind1 extends Kind
trait Kind2 extends Kind
trait Instance[A <: Instance[A, T], T <: Kind] {
self: A =>
def configuration: InstanceConfiguration[A]
}
trait InstanceConfiguration[+T <: Instance[_, _]] {
}
class AInstance extends Instance[AInstance, Kind1] {
override def configuration: AConfiguration = ???
}
class AConfiguration extends InstanceConfiguration[AInstance] {
}
class BInstance extends Instance[BInstance, Kind1] {
override def configuration: AConfiguration = ???
}
Upvotes: 2