play json writes subclass gives ambiguous implicit values error

倖福魔咒の 提交于 2019-12-06 03:37:47

You are getting a collision because Writes has a contravariant type parameter A:

trait Writes[-A] extends AnyRef

It means that Writes[Base] is subclass of Writes[SubClass] - you can use Writes[Base] where Writes[SubClass] is required.

The problem is here:

val base: Base = new SubClass(...)
val jsBase = Json.toJson(base)

So Writes[Base] should be able to serialize an instance of SubClass. You could use ADT in this case:

sealed trait Base
object Base {
  implicit val baseWrites: Writes[Base] = 
    new Writes[Base]{
      def writes(o: Base): JsValue = o match {
        case s: SubClass => SubClass.writes.writes(s)
        case s: SubClass2 => SubClass2.writes.writes(s)
      }
    }
}

case class SubClass(...) extends Base
object SubClass {
  val writes: Writes[SubClass] = (...)(unlift(SubClass.unapply))
}

case class SubClass2(...) extends Base
object SubClass2 {
  val writes: Writes[SubClass2] = (...)(unlift(SubClass2.unapply))
}

With sealed keyword you'll get a warning in case match is not exhaustive.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!