当用单个字段写为contramap
的{{1}}时,我无法理解case class
的工作原理。
说我有一个案例类,我想创建它的json
json
我将其case class SomeThingContainer (something:SomeThing)
编写如下:
write
如果我有以下模型, val somethingContainerVariable = SomethingContainer(something)
在应用程序中的某个地方,我将调用 implicit val somethingContainerWrites:Writes[SomeThingContainer] = (
(JsPath \ "something").write[Something]
).contramap{(somethingContainer:SomeThingContainer)=>somethingContainer.something}
将模型转换为toJson[SomeThingContainer]
。这将寻找隐含的Json
,该隐含的Writes[SomeThingContainer]
。从这里开始如何创建somethingContainerWrites
?如果有多个字段,我可以有点理解JSON
的工作原理,但是我无法理解unapply _
是如何发挥作用的。
答案 0 :(得分:1)
contramap
用于组成函子。
Writes
是(反)函子X => JsValue
。 (它知道如何从给定的X创建JsValue)
显然,您已经在某个位置定义了Writes[Something]
(因为您正在调用JsPath.write[Something]
隐式需要它)。
在括号内,创建一个新的Writes[Something]
,它仅使用前者将Something
写入JSON对象中的其他路径。
现在,要能够从JsValue
创建SomeThingContainer
,您需要做的就是将SomeThingContainer
转换为Something
-因为您已经拥有一个Writes[Something]
-并使用它。
这就是对位图调用的作用:您已经定义了Writes[Something]
,它创建了一个新的Writes[SomeThingContainer]
,当给定SomeThingContainer
时,它首先调用给定的“转换函数”,从而产生Something
。然后,它以此调用Writes[Something]
。
为了说明,contramap的作用:
Writes[X]: Functor[X => JsValue]
C: Y => X
Writes[X].contramap(C) <==> Writes[Y]: Functor[Y => X => JsValue]