Scala 猫 EitherT 和 foreach
Scala Cats EitherT and foreach
我正在尝试实现类似于以下代码的东西
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])
解决这个问题的好方法是什么?
由于您要查找所有用户,因此您将有多个用户及其各自的朋友,因此我将您的 return 值修改为 return List
of Response
相反。那么也许你想做这样的事情:
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
.
我正在尝试实现类似于以下代码的东西
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])
解决这个问题的好方法是什么?
由于您要查找所有用户,因此您将有多个用户及其各自的朋友,因此我将您的 return 值修改为 return List
of Response
相反。那么也许你想做这样的事情:
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
.