Monocle的选项与部分镜头相同吗?

时间:2015-11-15 21:51:18

标签: 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获得经典的局部镜片?在对镜头进行编程时,我发现确保整体设置比获取镜头要困难得多......

1 个答案:

答案 0 :(得分:6)

考虑以下部分镜头,用于按索引查找列表中的值(请注意,这只是一个教学示例,因为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)

请注意,如果没有第三项,则操作只返回未修改的列表。如果我们想知道该项目是否已更新,我们可以使用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作为其第二个参数的事实部分是方便的,因为我们经常希望以这种方式定义部分镜头,部分是因为我们可以&#39 ; t定义部分镜头,其中getOptionsetOption不同意目标是否存在。

如果您真的想要,可以通过在最后添加Optional来定义A => S => Option[S] getOrElse(s) // these are the first code lines in the file #include <cstdlib> #include <iostream> #include <fstream> #include <string> // No problem with these #include <math.h> #include <stdbool.h>