How to fix an ambiguous reference to the Overloaded apply () method during Json deserialization

Given the following case class, which needs to be serialized / deserialized to / from JSON ...

import play.api.libs.json
import play.api.libs.functional.syntax._

trait MyTrait(s1: String, s2: String)

case class MyClass(s1: String, s2: String) extends MyTrait {

  def this(t: MyTrait) = this(t.s1, t.s2)
}

object MyClass {

  def apply(t: MyTrait) = new MyClass(t)

  implicit val myClassJsonWrite = new Writes[MyClass] {
    def writes(c: MyClass): JsValue = {
      Json.obj(
        "s1" -> c.s1,
        "s2" -> c.s2
      )
    }
  }

  implicit val myClassJsonRead = (
    (__ \ 's1).read[String] ~
    (__ \ 's2).read[String]
  )(MyClass.apply _)
}

... I always get the following error message:

[error] /home/j3d/Projects/test/app/models/MyClass.scala:52: ambiguous reference to overloaded definition,
[error] both method apply in object MyClass of type (s1: String, s2: String)models.MyClass
[error] and  method apply in object MyClass of type (t: MyTrait)models.MyClass
[error] match expected type ?
[error]   )(MyClass.apply _)
[error]             ^

... why does the compiler not make the correct method apply? How can I fix this error? Any help could be helpful. Thank.

+5
source share
1 answer

You can select the correct method as follows:

MyClass.apply(_: String, _: String)

The compiler cannot infer the correct type because it refers to a method apply. Since you explicitly reference them, the compiler will not make this choice for you.

To make the syntax more readable, you can change the definition of a companion

object MyClass extends ((String, String) => MyClass) {

- apply

implicit val myClassJsonRead = (
  (__ \ 's1).read[String] ~
  (__ \ 's2).read[String])(MyClass)
+4

All Articles