Looking at a simple Scala Play JSON example (from the Play docs ) to validate JSON (type JsValue
) against a case class
:
import play.api.libs.json._
import play.api.libs.functional.syntax._
import play.api.data.validation.ValidationError
scala> implicit val creatureReads: Reads[Creature] = (
| (__ \ "name").read[String] and
| (__ \ "isDead").read[Boolean])
<console>:17: error: type mismatch;
found : play.api.libs.functional.FunctionalBuilder[play.api.libs.json.Reads]
#CanBuild2[String,Boolean]
required: play.api.libs.json.Reads[Creature]
(__ \ "name").read[String] and
^
Then, eventually call this:
scala> val creature = Json.obj( "name" -> "zombie", "isDead" -> true )
creature: play.api.libs.json.JsObject = {"name":"zombie","isDead":true}
scala> creature.validate[Creature]
...
But, how can I resolve the type mismatch
I'm seeing?
You're almost there—all you need to do is apply your CanBuild2
to the Creature
constructor:
implicit val creatureReads: Reads[Creature] = (
(__ \ "name").read[String] and (__ \ "isDead").read[Boolean]
)(Creature)
And everything will work as expected. This syntax is a little convoluted, but you can think of it as "lifting" the constructor into the applicative functor for Reads
, which allows you to apply it to the two Reads
values for the fields. My answer here refers to Scalaz's applicative builder syntax instead of Play's, but they're essentially the same—just read |@|
as and
:
One part of the weirdness is that
xs |@| ys
xs |@| ys
doesn't really mean anything on its own—it's essentially an argument list that's waiting to be applied to a function that it will lift into its applicative functor and apply to itself.
See also my answer here and blog post here for additional discussion.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.