使用选项

时间:2018-04-11 14:59:52

标签: scala lenses monocle-scala

我有一个3级嵌套案例类模型,其中包含一组表示数据库中某些数据的选项。它基本上是:

case class User(settings: Option[Settings])
case class Settings(keys: Option[List[KeySet]])
case class KeySet(privateKey: String, publicKey: String)

我理解如何使用一些用于flatMapScala Option object inside another Option object)的理解或链来获取深度嵌套的字段,我也理解如何使用镜头库更新它,但我想弄明白如何更新字段,即使树中的某些内容是None,如果它们还不存在,也会自动生成Some个字段。

例如,我如何处理我想要添加到keys列表但用户尚未设置任何settings的情况?在某种意义上,是否可以自动创建Some(settings)字段和Some(keys)字段?

我知道如何通过大量的模式匹配来实现它,但这似乎是错误的,因为1.向右漂移代码和2.不使用mapflatMap非常选项。

这是否可以单独使用镜头库?我在这里读到可能无法实现:https://github.com/julien-truffaut/Monocle/issues/215与Monocle一样,它无法更新Option None。也许我需要以另一种方式思考这个问题?

由于

1 个答案:

答案 0 :(得分:2)

我不确定您使用Option[List[KeySet]]的原因。 None和空List之间是否存在重要区别?

无论如何,在使用选项时,我发现fold是一个方便的工具。

def updateUser(u :User, ks :KeySet) :User = {
  u.copy(settings =
    Some(u.settings.fold(Settings(Some(ks::Nil))) (stngs =>
      stngs.copy(keys = Some(stngs.keys.fold(ks::Nil) (ks::_))))))
}

val pat = updateUser(User(None), KeySet("a","b"))
//pat: User = User(Some(Settings(Some(List(KeySet(a,b))))))

val upat = updateUser(pat, KeySet("c","d"))
//upat: User = User(Some(Settings(Some(List(KeySet(c,d), KeySet(a,b))))))