我有一个使用默认值创建的嵌套案例类的结构:
case class Alpha(text: String = "content")
case class Beta(alpha: Alpha = Alpha())
case class Gamma(beta: Option[Beta] = None)
我想用默认值创建整个东西,然后使用 Monocle 特别修改需要非默认的元素。
用iso很容易。我可以使用组合指定导航,然后使用 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(...)
)
object Gamma {
val betaI: Iso[Gamma, Option[Beta]] = GenIso[Gamma, Option[Beta]]
val betaP: Prism[Gamma, Beta] = Prism[Gamma, Beta](_.beta)(a => Gamma(Some(a)))
}
val navigateToText: Prism[Gamma, String] = Gamma.betaP composeIso Beta.alphaI composeIso Alpha.textI
navigateToText.set("foo")(Gamma(None)) shouldBe Gamma(None)
navigateToText.set("foo")(Gamma(Some(Beta()))) shouldBe Gamma(Some(Beta(Alpha("foo"))))
到目前为止,我想出的最好的方法是使用组合光学设置Some()
路径的每个可选元素,然后一直使用组合光学设置我们感兴趣的元素。
(Gamma.betaI.set(Some(Beta())) andThen navigateToText.set("foo")) (Gamma()) shouldBe Gamma(Some(Beta(Alpha("foo"))))
理想情况下,我希望组合的每个构建块都将可选值设置为Some(defaultValue)
如果它们最初是None
. 显然,需要定义构建块,包括路径步骤的适当默认值。有什么建议么?