考虑到someLabels
它的类型Map[String, String]
,您的代码要么过多,要么只是为组合提供了错误的参数Optional
。如果我们简化composeOptional
in 方法的签名Lens[S, A]
,它会产生:
def composeOptional(other: Optional[A, B]): Optional[S, B]
Optional[A, B]
,在非常不精确的近似下,对应于允许:
- 查看类型的值
A
并获取其类型的组成部分B
(或者A
如果它丢失了它本身);
A
通过替换它的类型组件来构建一个新的类型对象B
(或者如果没有这样的组件,则只返回原始对象)。
labels composeOptional index("app")
产量Optional[Metadata, String]
。这显然行不通Map[String, String]
:它间接从Metadata
to Map[String, String]
(via labels
) 然后立即从Map[String, String]
to 它的String
元素 (via index("app")
),完全隐藏用户对地图的访问。如果您试图在someLabels
地图中的给定键处设置一个值,则使用以下内容就足够了index
:
val someLabels1 = Map("app" -> "any")
val someLabels2 = Map("unit" -> "any")
index("app").set("whatever")(someLabels1) // Map("app" -> "whatever")
index("app").set("whatever")(someLabels2) // Map("unit" -> "any")
Optional
另一方面,您的组合可以正常工作Metadata
:
case class Metadata(labels: Map[String, String])
val someLabels = Map("app" -> "any")
val meta = Metadata(someLabels)
(labels composeOptional index("app")).set("whatever")(meta)
// Metadata(Map("app" -> "whatever")
我已经用以下版本(在build.sbt
)检查了它:
scalaVersion := 2.12.3
libraryDependencies ++= Seq(
"com.github.julien-truffaut" %% "monocle-core" % "1.4.0",
"com.github.julien-truffaut" %% "monocle-macro" % "1.4.0"
)