创建案例类的写作和格式 [英] Create Writes and Format of Case Class

查看:97
本文介绍了创建案例类的写作和格式的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

对于此案例类:

case class People(names: Set[Int])

特拉维斯·布朗解释了如何在此PeopleReads: Reads[People] .com/questions/21461590/defining-reads-for-json-set-type/21461939?noredirect = 1#comment32835638_21461939.>答案:

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

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

但是,我正在尝试实现PeopleWrites: Writes[People]:

But, I'm trying to implement PeopleWrites: Writes[People]:

 implicit val PeopleWrites: Writes[People] = 
    (JsPath \  "names").write[Set[Int]].map(unlift(x => Some((x.names)))

,出现以下编译时错误:

with the following compile-time error:

scala> People( Set(1,2,3))
res5: People = People(Set(1, 2, 3))

scala>  implicit val PeopleWrites: Writes[People] = 
      (JsPath \  "names").write[Set[Int]].map(unlift(x => Some((x.names))))
<console>:21: error: value map is not a member of 
                play.api.libs.json.OWrites[Set[Int]]
              implicit val PeopleWrites: Writes[People] = 
                (JsPath \  "names").write[Set[Int]].
                                      map(unlift(x => Some((x.names)))

如何解决此错误?

此外,如何在Format[People]Writes都定义/定义的地方写Format[People]:

Also, how can I write Format[People] where I get/define both Reads and Writes:

val peopleFormat: Format[People] = ...?

推荐答案

好问题!之所以不能使用map,是因为Writes不是函子.

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

您可以将Writes[A]视为A => JsValue之类的东西.但是假设我有一个A => JsValue和一个A => B.尝试提出一些构成这些函数的方法以获得B => JsValue-只是不可能.

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]类似于JsValue => A,并且是一个函子-它具有采用A => Bmap方法,并由Reads[A]/JsValue => A组成,并返回Reads[B]/JsValue => B.

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 contravariant 函子,幸运的是

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)

此处(__ \ 'names).write[Set[Int]]Writes[Set[Int]],而(_.names)是函数People => Set[Int].将它们与contramap结合在一起可以得到Writes[People].

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].

这篇关于创建案例类的写作和格式的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆