scala - Monocle 的 Optionals 与部分镜片相同吗?

标签 scala lenses monocle-scala

Monocle 的选项具有以下访问功能(适用于 Optional[C,A]):

getOption: C => Option[A]
set: A => C => C

这与(部分)非对称数据镜头的原始定义不一致。我希望:
getOption: C => Option[A]
setOption: A => C => Option[C]

这是什么原因?如何使用 Monocle 获得经典的局部镜片?在对镜头进行编程时,我发现确保设置的整体性比获取...的问题要多得多。

最佳答案

考虑以下用于按索引查找列表中的值的部分镜头(请注意,这只是一个教学示例,因为 monocle.std.list.listIndex 提供了现成的功能):

import monocle.Optional

def listIndexOptional[A](i: Int): Optional[List[A], A] =
  Optional[List[A], A](_.lift(i))(a => l =>
    if (l.isDefinedAt(i)) l.updated(i, a) else l
  )

现在我们可以定义一个 Optional指向字符串列表中的第三项:
val thirdString = listIndexOptional[String](2)

并像这样使用它:
scala> thirdString.set("0")(List("a", "b", "c"))
res4: List[String] = List(a, b, 0)

scala> thirdString.set("0")(List("a", "b"))
res5: List[String] = List(a, b)

请注意,如果没有第三项,则该操作仅返回未修改的列表。如果我们想知道 item 是否已经更新,我们可以使用 setOption :
scala> thirdString.setOption("0")(List("a", "b", "c"))
res6: Option[List[String]] = Some(List(a, b, 0))

scala> thirdString.setOption("0")(List("a", "b"))
res7: Option[List[String]] = None

事实证明Optional.apply方法将函数作为第二个参数 A => S => S部分是为了方便,因为我们经常想以这种方式定义部分镜头,部分原因是我们无法定义部分镜头,其中 getOptionsetOption不同意目标是否存在。

如果你真的想,你总是可以定义一个 OptionalA => S => Option[S] 方面setter 通过添加 getOrElse(s)最后。

关于scala - Monocle 的 Optionals 与部分镜片相同吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33725534/

相关文章:

scala - 为什么在 Akka Streams 中添加异步边界会消耗大量 CPU?

haskell - 递归型镜头

scala - 具有错误处理功能的镜头/棱镜

scala - 如何使用单片眼镜修改嵌套 map 和scala中的另一个字段

json - 如何解决此Scala/Play编译错误(返回错误的类型)?

scala - 管理可变状态的最佳方法是什么?

数值的标量总和列表

haskell - 功能性镜片

haskell - 如果索引列表遍历不匹配,则返回 ‘Nothing’

scala - 使用选项更新深层嵌套的案例类