Defining `Reads` for JSON Set Type

半世苍凉 提交于 2019-12-29 01:49:09

问题


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)

回答1:


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.



来源:https://stackoverflow.com/questions/21461590/defining-reads-for-json-set-type

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