3

Essentially, I am trying to do the following:

trait Foo[T] extends T {
  def json: Writes[T]
  def bar: String = {
    Json.toJson[T](this)(json).toString
  }
}

I want the compiler to enforce that any class using trait Foo is of type T. Unfortunatly, 'extends T' is not valid. Right now, the best I can do is the following:

trait Foo[T] extends T {
  def json: Writes[T]
  def bar: String = {
    Json.toJson(this.asInstanceOf[T])(json).toString
  }
}

But obviously, the compiler isn't enforcing anything. Is there anyway to achieve what I want?

Richard Shurtz
  • 1,641
  • 1
  • 15
  • 11
  • How does it make sense to have Foo[T] extends T, would you have e.g. Foo extends String in Java? Maybe I am missing something. – Lucia Pasarin Sep 21 '15 at 18:43

1 Answers1

5

You can use a self type to require that any class extending Foo[T] also be an instance of T:

import play.api.libs.json._

trait Foo[T] { self: T =>
  def json: Writes[T]
  def bar: String = Json.toJson[T](self)(json).toString
}

You can use whatever name you want in place of self (which is just a common convention).

Community
  • 1
  • 1
Travis Brown
  • 138,631
  • 12
  • 375
  • 680