【问题标题】:Scala Cats EitherT and foreachScala Cats EitherT 和 foreach
【发布时间】:2019-04-09 03:54:36
【问题描述】:

我正在尝试实现类似以下代码的功能

def getUsers: EitherT[Future, String, Response] = {
  for {
    users <- EitherT(userRepository.findAll) // this method would retrieve a Future[Either[String, Seq[User]]]
    user <- users
    friends <- EitherT(userRepository.findFriends(user.id))
  } yield new Response(user, friends)
}

我知道这是不可能的,因为EitherT 不管理foreach

case class User(id: Long, name: String, email: String)

case class Response(user: User, friends: Seq[User])

解决这个问题的好方法是什么?

【问题讨论】:

  • @erip 感谢您的阅读,我更新了这个问题试图解释我的想法。
  • user &lt;- users 没有做任何事情。即使这样做,您也会为每个用户创建一个朋友列表。似乎您的函数只想返回一个响应每个用户

标签: scala scala-cats either


【解决方案1】:

由于您要查找所有用户,因此您将有多个用户及其各自的朋友,因此我修改了您的返回值以返回 Responses 中的 List。那么也许你想做这样的事情:

import cats.data.EitherT
import cats.syntax.traverse._
import cats.instances.list._
import cats.instances.future._
import scala.concurrent.Future

def getUsers: EitherT[Future, String, List[Response]] = {
  EitherT(userRepository.findAll).flatMap { users =>
    users.toList.traverse(user => EitherT(userRepository.findFriends(user.id)).map(Response(user, _)))
  }
}

确保您在范围内具有隐式 ExecutionContext 或导入 scala.concurrent.ExecutionContext.Implicits.global

【讨论】:

  • 我正要添加相同的答案。不错。
  • @Lasf 谢谢你的回答。我正在尝试类似的东西,但我需要的是遍历。我最终做了一个 for yield 并用过滤器嵌套了另一个 for yield。
  • @agusgambina 对于它的价值,traverse 本质上是一个map,后跟一个sequence
猜你喜欢
  • 2022-01-22
  • 1970-01-01
  • 2021-12-28
  • 1970-01-01
  • 1970-01-01
  • 2019-05-19
  • 2021-02-25
  • 2018-10-08
  • 2019-08-29
相关资源
最近更新 更多