Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
809 views
in Technique[技术] by (71.8m points)

scala - Defining `Reads` for JSON Set Type

How can I create a play.api.libs.Reads for my People case class?

scala> type Id = Long
defined type alias Id

scala> case class People(names: Set[Id])
defined class People

scala>   implicit val PeopleReads: Reads[People] = (
     |     (__  "names").read[Set[Id]])(People)
<console>:21: error: overloaded method value read with alternatives:
  (t: Set[Id])play.api.libs.json.Reads[Set[Id]] <and>
  (implicit r: play.api.libs.json.Reads[Set[Id]])play.api.libs.json.Reads[Set[Id]]
 cannot be applied to (People.type)
           (__  "names").read[Set[Id]])(People)
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

The (...)(People) syntax is designed for when you've built up a list of arguments (well, technically it's a Builder, not a list) with and and want to lift the People constructor into the applicative functor for Reads so that you can apply it to those arguments.

For example, if your People type looked like this:

case class People(names: Set[Id], home: String)

You could write:

implicit val PeopleReads: Reads[People] = (
  (__  "names").read[Set[Id]] and
  (__  "home").read[String]
)(People)

In your case, though, the constructor for People has a single argument, and you haven't used and, so you don't have a Builder[Reads[Set[Id] ~ String], you've just got a plain old Reads[Set[Id]].

This is nice, because it means you don't need the weird applicative functor syntax—all you need is map:

implicit val PeopleReads = (__  "names").read[Set[Id]].map(People)

And you're done.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...