我有一个3级嵌套案例类模型,其中包含一组表示数据库中某些数据的选项。它基本上是:
case class User(settings: Option[Settings])
case class Settings(keys: Option[List[KeySet]])
case class KeySet(privateKey: String, publicKey: String)
我理解如何使用一些用于flatMap
(Scala Option object inside another Option object)的理解或链来获取深度嵌套的字段,我也理解如何使用镜头库更新它,但我想弄明白如何更新字段,即使树中的某些内容是None
,如果它们还不存在,也会自动生成Some
个字段。
例如,我如何处理我想要添加到keys
列表但用户尚未设置任何settings
的情况?在某种意义上,是否可以自动创建Some(settings)
字段和Some(keys)
字段?
我知道如何通过大量的模式匹配来实现它,但这似乎是错误的,因为1.向右漂移代码和2.不使用map
或flatMap
非常选项。
这是否可以单独使用镜头库?我在这里读到可能无法实现:https://github.com/julien-truffaut/Monocle/issues/215与Monocle一样,它无法更新Option
None
。也许我需要以另一种方式思考这个问题?
由于
答案 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))))))