Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/joomla/2.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 在使用组合光学元件构建的路径中定义可选值_Scala_Lenses_Monocle Scala - Fatal编程技术网

Scala 在使用组合光学元件构建的路径中定义可选值

Scala 在使用组合光学元件构建的路径中定义可选值,scala,lenses,monocle-scala,Scala,Lenses,Monocle Scala,我使用默认值创建了嵌套案例类的结构: case class Alpha(text: String = "content") case class Beta(alpha: Alpha = Alpha()) case class Gamma(beta: Option[Beta] = None) 我想用默认值创建整个东西,然后使用Monocle修改需要非默认的元素 使用isos很容易。我可以使用composition指定导航,然后使用set修改内部元素: object Beta { val al

我使用默认值创建了嵌套案例类的结构:

case class Alpha(text: String = "content")
case class Beta(alpha: Alpha = Alpha())
case class Gamma(beta: Option[Beta] = None)
我想用默认值创建整个东西,然后使用Monocle修改需要非默认的元素

使用isos很容易。我可以使用composition指定导航,然后使用set修改内部元素:

object Beta {
  val alphaI: Iso[Beta, Alpha] = GenIso[Beta, Alpha]
}
object Alpha {
  val textI: Iso[Alpha, String] = GenIso[Alpha, String]
}

(Beta.alphaI composeIso Alpha.textI).set("foo")(Beta()) shouldBe Beta(Alpha("foo"))
不幸的是,使用prims时,它似乎没有那么优雅,因为
set
/
modify
只会在定义了导航过程中的所有选项时修改内部元素(
Some(…)

到目前为止,我想到的最好的方法是使用合成光学设置路径的每个可选元素,然后使用合成光学设置我们感兴趣的元素

(Gamma.betaI.set(Some(Beta())) andThen navigateToText.set("foo")) (Gamma()) shouldBe Gamma(Some(Beta(Alpha("foo"))))
理想情况下,我希望合成的每个构建块将可选值设置为
Some(defaultValue)
,如果它们最初是
None
。显然,需要定义构建块,包括路径步骤的适当默认值。 有什么建议吗


完整代码,包括导入:

您可以使用
Prism中的
下面的
,例如光学组件中匹配的类型:

import monocle.macros.GenIso
import scalaz.std.option._
case class Alpha(text: String = "content")
case class Beta(alpha: Alpha = Alpha())
case class Gamma(beta: Option[Beta] = None)

val navigateToText = GenIso[Gamma, Option[Beta]] composePrism
  GenIso[Beta, Alpha].asPrism.below[Option] composePrism
  GenIso[Alpha, String].asPrism.below[Option]

navigateToText.set(Some("foo"))(Gamma(None))                     // Gamma(Some(Beta(Alpha(foo))))
navigateToText.set(Some("foo"))(Gamma(Some(Beta(Alpha("bar"))))) // Gamma(Some(Beta(Alpha(foo))))

太好了,效果很好!当有可选孩子的父母有其他孩子时,它也适用于镜头。(我无法在这里正确格式化代码,但我尝试了使用镜头的合成)不幸的是,我无法使用
monocle 2.1.0
scalaz core 7.3.3
编译此代码<代码>未找到:值
找不到选项
的遍历实例是错误消息
import monocle.macros.GenIso
import scalaz.std.option._
case class Alpha(text: String = "content")
case class Beta(alpha: Alpha = Alpha())
case class Gamma(beta: Option[Beta] = None)

val navigateToText = GenIso[Gamma, Option[Beta]] composePrism
  GenIso[Beta, Alpha].asPrism.below[Option] composePrism
  GenIso[Alpha, String].asPrism.below[Option]

navigateToText.set(Some("foo"))(Gamma(None))                     // Gamma(Some(Beta(Alpha(foo))))
navigateToText.set(Some("foo"))(Gamma(Some(Beta(Alpha("bar"))))) // Gamma(Some(Beta(Alpha(foo))))