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

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

问题描述

对于这个案例类:

case class People(names: Set[Int])

Travis Brown 在此解释了如何创建 PeopleReads: Reads[People]答案:

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)))

出现以下编译时错误:

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)))

我该如何解决这个错误?

How can I resolve this error?

另外,我如何编写 Format[People] 来获取/定义 ReadsWrites:

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,并且是一个函子——它有一个 map 方法,它接受一个 A =>B,用 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 是一个逆变函子,幸运的是 Play 知道这一点.当 F 是逆变函子时,F[A] 有一个方法 contramap[B](f: B => A) 而不是通常的map[B](f: A => 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)

这里 (__ 'names).write[Set[Int]] 是一个 Writes[Set[Int]](_.names) 是一个函数 People =>设置[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天全站免登陆