Search code examples
scalagenerics

Scala trait with generic self type


I have a trait that defines an action which is a glorified version of .copy(). which looks like this:

trait Optimize[T] {
    def optimize: T
}

and a bunch of classes that extend it like:

case class Account(field: String) extends Optimize[Account] {
    def optimize = this.copy(field = field.intern())
}

Is there a way to define a trait that requires a method optimize return the same type as self but doesn't require specifying a type when extending it? So I'd be able to write:

case class Account(field: String) extends Optimize {
    def optimize = this.copy(field = field.intern())
}

Solution

  • Short answer: You can't.

    One way or another (abstract types) you need to tell Optimize what the return type of that function is.

    Why? Because Optimize can be used in a type expression without specifying the concrete class, and there's no way for the compiler to know what type it will produce:

    def someOtherMethod (a: Optimize) {
      val result = a.optimize // what is the type?
    }
    

    (in the case of an abstract type, the return type would be a.T or Optimize#T ... not very useful)