我在理解上遇到了问题,如下所示:
def doSomething(): F[String] = {
for {
_ <- Future.traverse(items)(item => doSomeWork(item)) // Future[]
_ <- doSomeOtherWork(42) //F[]
} yield (())
}
Run Code Online (Sandbox Code Playgroud)
该函数doSomeWork看起来像:
def doSomeWork(item: Item): Future[Unit] =
// some work done inside a Future
)
Run Code Online (Sandbox Code Playgroud)
功能doSomeOtherWork工作如下:
def doSomeOtherWork(i : Int): F[Unit]
Run Code Online (Sandbox Code Playgroud)
因此,当我尝试编译时,遇到以下错误:
[error] found : F[Int]
[error] required: scala.concurrent.Future[?]
[error]
[error] ^
[error] type mismatch;
[error] found : scala.concurrent.Future[Nothing]
[error] required: F[Int]
Run Code Online (Sandbox Code Playgroud)
我不允许在这样的 for comp 中混合 F[] 和 Future 吗?
不,你不能。
A for comprehension只是调用& 的语法糖。而那些只适用于同一个 monad。flatMapmap
如果你不能改变doSomeWork返回一个F,你能做的最好的事情就是将你的期货转换Fs为 for。
这是您如何做到这一点的示例。
(我不得不发明很多细节,因为你的问题很模糊)
import cats.effect.{Async, ContextShift, Sync}
import cats.instances.list._ // Provides the Foldable[List] instance into scope.
import cats.syntax.flatMap._ // Provides the flatMap method (used in the for).
import cats.syntax.foldable._ // Provides the traverse_ method.
import cats.syntax.functor._ // Provides the map method (used in the for).
import scala.concurrent.Future
final case class Item(id: Int, name: String)
def doSomeWork(item: Item): Future[Unit] = ???
def doSomeOtherWork[F[_] : Sync](i: Int): F[Unit] = ???
def doSomething[F[_]](items: List[Item])(implicit F: Async[F], cs: ContextShift[F]): F[Unit] =
for {
_ <- items.traverse_(item => Async.fromFuture(F.delay(doSomeWork(item))))
_ <- doSomeOtherWork(42)
} yield ()
Run Code Online (Sandbox Code Playgroud)
用猫效果 测试2.0.0。