这里有一个 Scalaz 地图镜头的例子:Dan Burton 称之为containsKey
,它的灵感来自 Edward Kmett 的演讲。Scalaz 7 中也有一些mapVPLens
对修改映射中的值很有用的东西。
我的问题是:如果我有一个用于修改 typeV
的镜头和一个用于 a 的镜头,我该Map[K,V]
如何构图?我一直在寻找一个很好的简单示例,但 Scalaz 中仍然缺乏示例。
我对 Scalaz 6 和 Scalaz 7 解决方案都感兴趣。
如果您尝试使用地图镜头构图的镜头是部分镜头,则可以使用compose
:
import scalaz._, Scalaz._, PLens._
def headFoo[A] = listHeadPLens[A] compose mapVPLens("foo")
接着:
scala> headFoo.get(Map("foo" -> List(42)))
res0: Option[Int] = Some(42)
scala> headFoo.get(Map("foo" -> Nil))
res1: Option[Nothing] = None
scala> headFoo.get(Map("bar" -> List(13)))
res2: Option[Int] = None
请注意,这是 Scalaz 7。
如果您要构图的镜头不是局部的,您可以使用~
:
scala> def firstFoo[A, B] = ~Lens.firstLens[A, B] compose mapVPLens("foo")
firstFoo: [A, B]=> scalaz.PLensFamily[Map[String,(A, B)],Map[String,(A, B)],A,A]
scala> firstFoo.get(Map("foo" -> (42, 'a)))
res6: Option[Int] = Some(42)
.partial
如果您不喜欢一元运算符,还有一种方法。