Create Writes and Format of Case Class

后端 未结 1 1630
[愿得一人]
[愿得一人] 2020-12-21 22:45

For this case class:

case class People(names: Set[Int])

Travis Brown explained how to create PeopleReads: Reads[People] at this ans

相关标签:
1条回答
  • 2020-12-21 23:25

    Good question! The reason you can't use map is because Writes isn't a functor.

    You can think of Writes[A] as something kind of like A => JsValue. But suppose I've got a A => JsValue and a A => B. Try to come up with some way of composing those functions to get a B => JsValue—it's just not possible.

    Reads[A], on the other hand, is kind of like JsValue => A, and is a functor—it has a map method that takes a A => B, composes it with the Reads[A] / JsValue => A, and returns a Reads[B] / JsValue => B.

    Writes is, however, a contravariant functor, and luckily enough Play knows that. When F is a contravariant functor, F[A] has a method contramap[B](f: B => A) instead of the usual map[B](f: A => B). So you can just write this:

    case class People(names: Set[Int])
    
    import play.api.libs.json._
    import play.api.libs.functional.syntax._
    
    implicit val PeopleWrites: Writes[People] =
      (__ \ 'names).write[Set[Int]].contramap(_.names)
    

    Here (__ \ 'names).write[Set[Int]] is a Writes[Set[Int]] and (_.names) is a function People => Set[Int]. Combining them with contramap gives us a Writes[People].

    0 讨论(0)
提交回复
热议问题