如何使用遍历 运行 效果列表
How To Use Traverse To Run A List of Effects
我有这样的功能:
def getFile(url: String): EitherT[Future, Error, ByteString]
这是使用猫 EitherT。
我使用另一个函数调用此函数,如下所示:
def getAllFiles(urls: List[String]): EitherT[Future, Error, List[ByteString]] = {
urls.map(f => getFile(f).value)
}
这不起作用,因为我发现类型不匹配:
found : List[scala.concurrent.Future[Either[Error,akka.util.ByteString]]]
[error] required: cats.data.EitherT[scala.concurrent.Future,Error,List[akka.util.ByteString]]
无论我尝试什么,我都无法编译。基本上我想做的是 运行 为每个 URL getFile 并在 Bytestring.
中下载文件
这个有效:
import cats.data.EitherT
import cats.effect.IO
import cats.implicits._
type Error = String
type ByteString = Array[Byte]
def getFile(url: String): EitherT[IO, Error, ByteString] = ???
def getAllFiles(urls: List[String]): EitherT[IO, Error, List[ByteString]] =
urls.traverse(getFile)
但这不是:
def getFile(url: String): EitherT[Future, Error, ByteString] = ???
def getAllFiles(urls: List[String]): EitherT[Future, Error, List[ByteString]] =
urls.traverse(getFile)
原因是 traverse
期望来自嵌套效果的 Applicative,cats 为 IO
但不适用于 Future
.
所以,原因是由于 Future 的急切和缓存性质,我们无法真正推断其行为。所以 cats 没有为它提供实例。
您可以为 Future
提供自己的 Applicative...但是,恕我直言,使用 IO.fromFuture
和 io.unsafeToFuture()
调整代码会更容易
我有这样的功能:
def getFile(url: String): EitherT[Future, Error, ByteString]
这是使用猫 EitherT。
我使用另一个函数调用此函数,如下所示:
def getAllFiles(urls: List[String]): EitherT[Future, Error, List[ByteString]] = {
urls.map(f => getFile(f).value)
}
这不起作用,因为我发现类型不匹配:
found : List[scala.concurrent.Future[Either[Error,akka.util.ByteString]]]
[error] required: cats.data.EitherT[scala.concurrent.Future,Error,List[akka.util.ByteString]]
无论我尝试什么,我都无法编译。基本上我想做的是 运行 为每个 URL getFile 并在 Bytestring.
中下载文件这个有效:
import cats.data.EitherT
import cats.effect.IO
import cats.implicits._
type Error = String
type ByteString = Array[Byte]
def getFile(url: String): EitherT[IO, Error, ByteString] = ???
def getAllFiles(urls: List[String]): EitherT[IO, Error, List[ByteString]] =
urls.traverse(getFile)
但这不是:
def getFile(url: String): EitherT[Future, Error, ByteString] = ???
def getAllFiles(urls: List[String]): EitherT[Future, Error, List[ByteString]] =
urls.traverse(getFile)
原因是 traverse
期望来自嵌套效果的 Applicative,cats 为 IO
但不适用于 Future
.
所以,原因是由于 Future 的急切和缓存性质,我们无法真正推断其行为。所以 cats 没有为它提供实例。
您可以为 Future
提供自己的 Applicative...但是,恕我直言,使用 IO.fromFuture
和 io.unsafeToFuture()
调整代码会更容易