使用选项更新深度嵌套的案例类



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

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

我了解如何使用一些用于理解或flatMap链(另一个选项对象中的 Scala Option 对象)从中获取深度嵌套字段,我也了解如何使用镜头库更新它,但我想弄清楚如何更新字段,即使树中的某些内容None,如果它们尚不存在,也自动制作Some字段。

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

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

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

谢谢

我不确定你为什么使用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))))))

最新更新