abatyuk
abatyuk

Reputation: 1342

Reference to self type in parameterized trait

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

Answers (1)

wingedsubmariner
wingedsubmariner

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

Related Questions