考慮以下部分鏡頭用於通過索引查找列表中的值(請注意,這僅僅是一個教學示例,因爲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
部分是爲了方便,因爲我們經常要定義部分這樣,部分是因爲我們無法定義一個部分鏡頭,其中getOption
和setOption
不同意目標是否存在。
如果您確實想要,您可以始終根據A => S => Option[S]
定義一個Optional
,最後加上getOrElse(s)
。
Monocle在'Optional'上提供'setOption'方法,提供您正在查找的操作。如果沒有匹配,'set'只返回給定的'C'。 –
那麼可選的setter可以來自一個可選的getter和一個完整的setter? –
在檢查了'setOption'的源代碼之後,在我看來,它永遠不會產生'None',所以用這種方式製作一個部分透鏡似乎不可行,是嗎? –