Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/scala/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Scala:如何在Monocle中增加字段值_Scala_Monocle Scala - Fatal编程技术网

Scala:如何在Monocle中增加字段值

Scala:如何在Monocle中增加字段值,scala,monocle-scala,Scala,Monocle Scala,鉴于monocle项目中存在的问题,我想创建一个镜头,其中set调用将替换键/值对中的值,或者创建键/值对(如果它不存在) 然而,这似乎用索引(可以组成类型安全的)或at(不属于类型安全的)来表示 //for replacing: (jsObject composeOptional index("age") composePrism jsNumber).set(45) //for creating: (jsObject composeLens at("age")).set(JsNumber(4

鉴于monocle项目中存在的问题,我想创建一个镜头,其中set调用将替换键/值对中的值,或者创建键/值对(如果它不存在)

然而,这似乎用索引(可以组成类型安全的)或at(不属于类型安全的)来表示

//for replacing:
(jsObject composeOptional index("age") composePrism jsNumber).set(45)

//for creating:
(jsObject composeLens at("age")).set(JsNumber(45)) <- will accept any old json
如果“nested”的键/值对还不存在,它将在nested处创建对象,然后添加字段

n(JsObject(Map.empty)) -> JsObject(Map("nested" -> JsObject("age" -> JsNumber(45)))

现在图书馆里有很多书

当您使用一些
Iso
Prism
编写
Optional
时,它会将右侧参数降级为
POptional
,这就是问题所在

Iso[A,B]
Prism[A,B]
不同于
Lens[A,B]
Optional[A,B]
的意义在于
reverseGet
可以完全从
B
创建
A
的元素,而
set
需要
A
的原始值

因此,对于
Optional
Lens
而言,完全可以合法地修改部分值,而在原始
Map
JsObject
中没有此值,对于
Iso
Prism
而言,您可以定义另一种行为

在等待讨论时,您可以使用以下变通方法

implicit class POptStrictComposition[S, T, A, B](self: POptional[S, T, A, B]) {
  def sComposePrism[C, D](other: PPrism[A, B, C, D]) = new POptional[S, T, C, D] {
    def getOrModify(s: S): T \/ C =
      self.getOrModify(s).flatMap(a => other.getOrModify(a).bimap(self.set(_)(s), identity))

    def set(d: D): S => T =
      self.set(other.reverseGet(d))

    def getOption(s: S): Option[C] =
      self.getOption(s) flatMap other.getOption

    def modifyF[F[_] : Applicative](f: C => F[D])(s: S): F[T] =
      self.modifyF(other.modifyF(f))(s)

    def modify(f: C => D): S => T =
      self.modify(other.modify(f))
  }

  def ^!<-?[C, D](o: PPrism[A, B, C, D]) = sComposePrism(o)

  def sComposeIso[C, D](other: PIso[A, B, C, D]) = sComposePrism(other.asPrism)

  def ^!<->[C, D](o: PIso[A, B, C, D]) = sComposeIso(o)
}

并报告它是否有帮助

目前图书馆里有很多

当您使用一些
Iso
Prism
编写
Optional
时,它会将右侧参数降级为
POptional
,这就是问题所在

Iso[A,B]
Prism[A,B]
不同于
Lens[A,B]
Optional[A,B]
的意义在于
reverseGet
可以完全从
B
创建
A
的元素,而
set
需要
A
的原始值

因此,对于
Optional
Lens
而言,完全可以合法地修改部分值,而在原始
Map
JsObject
中没有此值,对于
Iso
Prism
而言,您可以定义另一种行为

在等待讨论时,您可以使用以下变通方法

implicit class POptStrictComposition[S, T, A, B](self: POptional[S, T, A, B]) {
  def sComposePrism[C, D](other: PPrism[A, B, C, D]) = new POptional[S, T, C, D] {
    def getOrModify(s: S): T \/ C =
      self.getOrModify(s).flatMap(a => other.getOrModify(a).bimap(self.set(_)(s), identity))

    def set(d: D): S => T =
      self.set(other.reverseGet(d))

    def getOption(s: S): Option[C] =
      self.getOption(s) flatMap other.getOption

    def modifyF[F[_] : Applicative](f: C => F[D])(s: S): F[T] =
      self.modifyF(other.modifyF(f))(s)

    def modify(f: C => D): S => T =
      self.modify(other.modify(f))
  }

  def ^!<-?[C, D](o: PPrism[A, B, C, D]) = sComposePrism(o)

  def sComposeIso[C, D](other: PIso[A, B, C, D]) = sComposePrism(other.asPrism)

  def ^!<->[C, D](o: PIso[A, B, C, D]) = sComposeIso(o)
}

并报告它是否有帮助

让我们看看
索引
处的
JsObject的签名

def at(field: String): Lens[JsObject, Option[Json]]
def index(field: String): Optional[JsObject, Json]
at
是一个
镜头
,因此其目标('Option[Json])始终存在。这意味着我们可以在
JsonObject
的任何字段中
添加
删除
更新
Json
元素

import argonaut._, Argonaut._
import monocle.function._

(jObjectPrism composeLens at("name")).set(Some(jString("John")))(Json())
> res0: argonaut.Json = {"name":"John"}

(jObjectPrism composeLens at("name")).set(Some(jString("Robert")))(res0)
> res1: argonaut.Json = {"name":"Robert"}

(jObjectPrism composeLens at("name")).set(None)(res0)
> res2: argonaut.Json = {}
另一方面,
索引
是一个
可选的
,因此它是目标(
Json
)可能存在也可能不存在。这意味着
索引
只能
更新
值,但不能
添加
删除

(jObjectPrism composeLens index("name")).set(jString("Robert"))(Json())
> res3: argonaut.Json = {}

(jObjectPrism composeLens index("name")).set(jString("Robert"))(res0)
> res4: argonaut.Json = {"name":"Robert"}

因此,回到您原来的问题,如果您想
在特定字段添加
更新
值,您需要在
处使用
,并将
Json
包装在
部分
(请参见
res1
)中,它将覆盖或创建该字段中的
Json

让我们看看
索引和
处的
签名
JsObject

def at(field: String): Lens[JsObject, Option[Json]]
def index(field: String): Optional[JsObject, Json]
at
是一个
镜头
,因此其目标('Option[Json])始终存在。这意味着我们可以在
JsonObject
的任何字段中
添加
删除
更新
Json
元素

import argonaut._, Argonaut._
import monocle.function._

(jObjectPrism composeLens at("name")).set(Some(jString("John")))(Json())
> res0: argonaut.Json = {"name":"John"}

(jObjectPrism composeLens at("name")).set(Some(jString("Robert")))(res0)
> res1: argonaut.Json = {"name":"Robert"}

(jObjectPrism composeLens at("name")).set(None)(res0)
> res2: argonaut.Json = {}
另一方面,
索引
是一个
可选的
,因此它是目标(
Json
)可能存在也可能不存在。这意味着
索引
只能
更新
值,但不能
添加
删除

(jObjectPrism composeLens index("name")).set(jString("Robert"))(Json())
> res3: argonaut.Json = {}

(jObjectPrism composeLens index("name")).set(jString("Robert"))(res0)
> res4: argonaut.Json = {"name":"Robert"}

因此,回到您原来的问题,如果您想
在特定字段添加
更新
值,您需要在
处使用
,并将
Json
包装在
部分
(请参见
res1
)中,它将覆盖或创建该字段中的
Json

如果您还提供
jsObject
jsNumber
Index
实例的定义,那就太好了。问题似乎出在以可选类型实现
compose…
。它通过
modify
方法进行处理。如果原始值为
None
我已经提出了一个问题,如果您还提供了
jsObject
jsNumber
Index
实例的定义,那就太好了。问题似乎出在以可选类型实现
compose…
。它通过
modify
方法进行处理。如果原文是
None
我已经提出了一个@JPullar,实际上我强烈建议接受朱利安·特鲁法特的答案。写下这个答案后,我已经阅读了朱利安的解释,并得出结论,我的方法是错误的。接受这个答案可能会导致对图书馆意识形态的误解。@JPullar实际上,我强烈建议接受朱利安·特鲁福的答案。在写下这个答案后,我已经阅读了Jullien在这里和讨论中的解释,并得出结论,我的方法是错误的。接受这个答案可能会导致对图书馆意识形态的误解。因此我最终使用at(也有在设置时删除字段的功能)(无).为了维护类型安全,我只使用了一个非组合棱柱.set(prism.reverseGet())所以我最终使用了at(还具有在设置(None)时删除字段的功能)。为了维护类型安全,我只使用了一个非组合棱柱.set(prism.reverseGet())来维护类型安全