加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

scala – 要么是选项,要么是理解

发布时间:2020-12-16 18:40:48 所属栏目:安全 来源:网络整理
导读:我正在为一个理解编码,并想知道一些事情: def updateUserStats(user: User): Either[Error,User] = for { stampleCount - stampleRepository.getStampleCount(user).right userUpdated - Right(copyUserWithStats(user,stampleCount)).right // ????????? u
我正在为一个理解编码,并想知道一些事情:

def updateUserStats(user: User): Either[Error,User] = for {
  stampleCount <- stampleRepository.getStampleCount(user).right
  userUpdated <- Right(copyUserWithStats(user,stampleCount)).right // ?????????
  userSaved <- userService.update(userUpdated).right
} yield userSaved


def copyUserWithStats(user: User,stamples: Long): User = {
  val newStats = user.userStats.copy(stamples = stamples)
  user.copy(userStats = newStats)
}

似乎使用copyUserWithStats不返回Either不能直接用于for comprehension,因为它没有map / flatMap方法.

所以我想知道,在这种情况下,它是使用Right(copyUserWithStats(user,stampleCount))的合适解决方案.

它似乎至少起作用……

顺便说一句,我也尝试过选择但它没有用,有人可以解释为什么吗?

def updateUserStats(user: User): Either[Error,User] = for {
  stampleCount <- stampleRepository.getStampleCount(user).right
  userUpdated <- Some(copyUserWithStats(user,stampleCount))
  userSaved <- userService.update(userUpdated).right
} yield userSaved

谢谢

解决方法

在理解中,所有单子都必须是同一种.这意味着你不能混合RightProjection和Option,因为输出必须是Either.这是因为for-comprehension被转换为嵌套的flatMap / map构造.您的示例如下所示:

def updateUserStats(user: User): Either[Error,User] =
  stampleRepository.getStampleCount(user).right.flatMap { stampleCount =>
    Some(copyUserWithStats(user,stampleCount)).flatMap { userUpdated =>
      userService.update(userUpdated).right.map { userSaved =>
        userSaved
      }
    }
  }

如果我们现在看一下RightProjection.flatMap的签名,那就是def
flatMap [A??A>:A,Y](f:(B)?[AA,Y]):我们看到[AA,Y],结果必须是Either,但是Option的flatMap具有签名flatMap [B](f:(A)?选项[B]):选项[B].它返回一个Option,并且没有合理的方法将Option转换为Either.

编辑:以下示例不会为Either安静工作,请参阅huynhjl链接以获取更多信息

但是,除了在for-comprehension中从monad中提取值之外,还可以创建变量,因此您的示例可以重写为:

def updateUserStats(user: User): Either[Error,User] = for {
  stampleCount <- stampleRepository.getStampleCount(user).right
  userUpdated = copyUserWithStats(user,stampleCount)
  userSaved <- userService.update(userUpdated).right
} yield userSaved

这为我们节省了不必要的分配,也使代码更具可读性.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读