Max
Max

Reputation: 2552

Scala warning: abstract type pattern Z is unchecked since it is eliminated by erasure

I've taken a look to the answers about this topic, but I just haven't got how to fix the problem in this snippet:

object MyObj {

  def validate[Z](json: JsValue)(implicit rds: Reads[Z]): Either[Error,Z] = {
    json.validate[Z].map{ 
      case r: Z => Right(r)  // Type Erasure here....
    }.recoverTotal{
      e => Left(JsonParsingError(JsError.toFlatJson(e).toString))
    }
  }

}

Any help?

Upvotes: 1

Views: 1275

Answers (1)

acjay
acjay

Reputation: 36511

I think all you really have to do to kill that error is drop the type ascription : Z. You already know it will be a Z if validate gives you a JsSuccess in the first place. Otherwise you'll end up in recoverTotal.

I think you want:

object MyObj {
  def validate[Z](json: JsValue)(implicit rds: Reads[Z]): Either[Error,Z] = {
    json.validate[Z].map(Right _).recoverTotal{ e => 
      Left(JsonParsingError(JsError.toFlatJson(e).toString))
    }
  }
}

Although what you may really want is:

implicit def readsEither[Z](implicit rds: Reads[Z]): Reads[Either[Error, Z]] = Reads { json =>
  rds.reads(json).map(Right(_)).recoverTotal { e => 
    JsSuccess(Left(JsonParsingError(JsError.toFlatJson(e).toString)))
  }
}

This latter example is nice because it defines a Reads, which composes nicely.

I haven't tested any of this, and can't really, since I don't have a JsonParsingError, but this should more or less solve your problem.

Edit: given the fact that your code requires an implicit Reads[Z] already, you might also try:

def jsonAsEither(json: JsValue)(implicit rds: Reads[Z]) =
  Json.fromJson(json).asEither.left.map( /* ... */ ).e

Upvotes: 1

Related Questions