Monocle的Optionals和partial Lenses一样吗?
Are Monocle's Optionals the same as partial Lenses?
Monocle 的选项具有以下访问函数(对于 Optional[C,A]
):
getOption: C => Option[A]
set: A => C => C
这与(部分)非对称数据镜头的原始定义不一致。我希望:
getOption: C => Option[A]
setOption: A => C => Option[C]
这是什么原因?如何使用 Monocle 获得经典的局部镜片?在编程镜头时,我发现确保 set 的完整性比 get 更成问题 ...
考虑以下用于按索引在列表中查找值的部分镜头(请注意,这只是一个教学示例,因为 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)
请注意,如果没有第三项,操作只是 returns 列表未修改。如果我们想知道该项目是否已更新,我们可以使用 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
作为第二个参数这一事实部分是为了方便,因为我们经常希望以这种方式定义部分镜头,部分是为了我们可以' 定义部分镜头,其中 getOption
和 setOption
不同意目标是否存在。
如果你真的想,你总是可以根据 A => S => Option[S]
setter 定义 Optional
,方法是在末尾加上 getOrElse(s)
。
Monocle 的选项具有以下访问函数(对于 Optional[C,A]
):
getOption: C => Option[A]
set: A => C => C
这与(部分)非对称数据镜头的原始定义不一致。我希望:
getOption: C => Option[A]
setOption: A => C => Option[C]
这是什么原因?如何使用 Monocle 获得经典的局部镜片?在编程镜头时,我发现确保 set 的完整性比 get 更成问题 ...
考虑以下用于按索引在列表中查找值的部分镜头(请注意,这只是一个教学示例,因为 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)
请注意,如果没有第三项,操作只是 returns 列表未修改。如果我们想知道该项目是否已更新,我们可以使用 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
作为第二个参数这一事实部分是为了方便,因为我们经常希望以这种方式定义部分镜头,部分是为了我们可以' 定义部分镜头,其中 getOption
和 setOption
不同意目标是否存在。
如果你真的想,你总是可以根据 A => S => Option[S]
setter 定义 Optional
,方法是在末尾加上 getOrElse(s)
。