scala – 播放JSON InvariantFunctor
Play的
JSON
library包含一个Functor和Invariant Functor:
我之前见过Functor: trait Functor[M[_]] extends Variant[M] { def fmap[A,B](m: M[A],f: A => B): M[B] } 但是,从概念上讲,为什么有必要为InvariantFunctor提供函数f1和f2? trait InvariantFunctor[M[_]] extends Variant[M] { def inmap[A,f1: A => B,f2: B => A): M[B] } 解决方法
在
this answer中,我快速解释了为什么Writes不是一个仿函数,即为什么如果我们有一个Writes [A]和一个函数A => B我们不能以与Reads相同的方式创建Writes [B].
正如我在该答案中所指出的,Writes不是普通的(协变)仿函数,但它是一个逆变函子,这意味着如果我们有一个Writes [A]和一个函数B => A,我们可以创建一个Writes [B]. 格式包含Reads和Writes的功能,这意味着它既不是函子也不是逆变函子 – 但它是一个不变的函子(它实际上是唯一一个带有不变函子实例的类型,你将遇到它玩). 要知道为什么会这样,假设我们有以下两种类型: case class Foo(i: Int,s: String) case class Bar(s: String,i: Int) 假设我们有一个Foo的Format实例: import play.api.libs.json._ import play.api.libs.functional.syntax._ implicit val fooFormat = Json.format[Foo] 但无论出于何种原因,我们无法以相同的方式为Bar创建一个 – 我们希望从Foo中获取它.我们不知道如何从Foo创建Bar,反之亦然,但如果我们可以双向进行,我们可以使用格式的不变函子: implicit val barFormat = fooFormat.inmap[Bar]( foo => Bar(foo.s,foo.i),bar => Foo(bar.i,bar.s) ) 这是因为我们可以将Format视为一个双向管道,它允许我们放入一个JsValue并获得一些A,或者放入A并获得一个JsValue.如果我们想将双向管道格式[A]转换为双向管道格式[B],我们需要两侧的适配器(即A => B和B => A). (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |