3

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

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

我了解如何使用一些用于理解或链flatMap另一个 Option 对象中的 Scala Option 对象)从中获得深度嵌套的字段,并且我也了解如何使用镜头库对其进行更新,但我想弄清楚如何更新即使树中的某些东西是字段,并且如果它们尚不存在,它们也会None自动生成它们。Some

例如,我将如何处理我想添加到keys列表但用户尚未设置任何内容的情况settings?从某种意义上说,是否有可能自动创建一个Some(settings)字段和一个Some(keys)字段?

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

这可以单独使用镜头库吗?我在这里读到这可能是不可能的:https ://github.com/julien-truffaut/Monocle/issues/215就 Monocle 而言,它无法更新Option一个None. 也许我需要以另一种方式考虑这个问题?

谢谢

4

1 回答 1

2

我不确定你为什么使用Option[List[KeySet]]. None和 empty之间有重要区别List吗?

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

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))))))
于 2018-04-11T19:17:22.697 回答