Scala选项和flatMap

时间:2012-01-05 09:57:30

标签: scala monads

我正试图抓住“Scala方式”的工作,所以我想知道下面的代码是不是在这种情况下应该怎么做。

所以我有实体User和Company(用LiftWeb映射器映射)。用户具有包含选项[用户]的currentUser,而公司具有当前公司,其是选项[公司]。为了比较当前用户是否是当前公司的所有者,我正在做类似的事情:

Company.currentCompany.map{_.owner.get == User.currentUser.map{_.id.get}.openOr(-1) }.openOr(false)

它有效但不知何故感觉有点冗长。好吗?不是吗?有更好的想法吗? 谢谢!

3 个答案:

答案 0 :(得分:10)

您是否看过使用for-comprehensions?您可以执行以下操作:

for(
  company <- Company.currentCompany.map{_.owner};
  user <- User.currentUser.map{_.id}
) yield (company == user).getOrElse(false)

如果Company.currentCompany为Some [value],User.currentCompany为Some [value],company.owner == user.id,则返回true。

我觉得应该有一些方法可以在最后摆脱getOrElse,并直接返回未解包的布尔值,希望其他人可能会对此有所了解!

答案 1 :(得分:6)

使用for-comprehension绝对是解决方案,实际上......或flatMap但不太可读

使用Monadic flatMap的{​​{1}}函数调用每个生成器绑定,除了映射的最后一个(如任何Optionfor)。这是一个关于底层概念Monad

的精彩幻灯片

因此for comprehension用于传递所有步骤,而它们未在失败状态下编码(yieldNone)。

以下是每个选项(for和flatMap)的四个测试(四个基本情况)的完整示例

Option

答案 2 :(得分:0)

假设:

Case class user(name:String)
Case class company(owner:Option[User])

Val currentcompany=company(Some("Karl"))
Val currentuser=Some(user("Karl"))

可能的解决方案:

currentcompany.foldLeft(false) { 
  case (a,b) => currentuser.isDefined && b.owner == currentUser.get
}