juanchito
juanchito

Reputation: 519

Parametric polymorphism breaks when an implicit is expected in Scala

I get

No Json serializer found for type T. Try to implement an implicit Writes or Format for this type.

in

import play.api.libs.json._

trait A[T] {
  def foo(t: T) = bar(Json.toJson(t))
}

I will have a Writes for the actual parameter type but I don't see that that would clear up the compilation error. After some googling, I feel like there may be something fundamental missing in my understanding on the subject. Any help is appreciated.

Upvotes: 1

Views: 87

Answers (2)

Nagarjuna Pamu
Nagarjuna Pamu

Reputation: 14825

Provide implicit def writes

import play.api.libs.json._

trait A[T] {
  implicit def writes: Writes[T]
  def foo(t: T) = bar(Json.toJson(t))
}

or provide writes as implicit parameter to foo

import play.api.libs.json._

trait A[T] {
  def foo(t: T)(implicit writes: Writes[T]): JsValue = bar(Json.toJson(t))
}

Upvotes: 0

Travis Brown
Travis Brown

Reputation: 139038

The error message isn't very clear in this case—you don't need to implement a Writes for this type, you just need to prove to the compiler that you have one:

import play.api.libs.json._

trait A[T] {
  def foo(t: T)(implicit w: Writes[T]) = bar(Json.toJson(t))
}

This will work as expected. You could also have an implicit def w: Writes[T] in the trait, which would require instantiators to provide an instance, which is more restrictive in that you can't instantiate an A without an instance, but it's syntactically a little cleaner if you have a lot of methods like this, and you may actually want the restriction to kick in earlier, rather than after you've already got an A instantiated and you're trying to call foo on it.

Upvotes: 2

Related Questions