ByerN
ByerN

Reputation: 123

Scala - refer child class in parent (generics)

I am trying to refer to child class in trait in case of generics. It is probably not possible but I will be glad if someone knows solution for this problem. More info in example below.


object TestMain {
  trait A {
    def doSomething(objects: Seq[A]): A // can I put something here instead of A to make it work?
  }
  case class B() extends A {
    override def doSomething(objects: Seq[B]): B = {
      objects.head
    }
  }
  case class C() extends A {
    override def doSomething(objects: Seq[C]): C = {
      objects.head
    }
  }

  def main(args: Array[String]): Unit = {
    B().doSomething(Seq(B(), B())) //ok
    C().doSomething(Seq(C(), C())) //ok
    B().doSomething(Seq(B(), C())) //I want compile time error
  }
}

I want A and B class accept only collections of themselves on compile time to not make checks in each of these classes. Is it possible?

Upvotes: 2

Views: 582

Answers (1)

gianluca aguzzi
gianluca aguzzi

Reputation: 1724

As stated by @user you could use F-bounded polymorphism to implement what you want.

Given your example, I applied the F-bounded as:

object TestMain {
  trait A[Me <: A[Me]]{
    def doSomething(objects: Seq[Me]): A[Me] // can I put something here instead of A to make it work?
  }
  case class B() extends A[B] {
    override def doSomething(objects: Seq[B]): B = {
      objects.head
    }
  }
  case class C() extends A[C] {
    override def doSomething(objects: Seq[C]): C = {
      objects.head
    }
  }

  def main(args: Array[String]): Unit = {
    B().doSomething(Seq(B(), B())) //ok
    C().doSomething(Seq(C(), C())) //ok
    B().doSomething(Seq(B(), C())) //now this thrown a compile time error
  }
}

Upvotes: 2

Related Questions