将Future和F []混合在一起以便理解

问题描述 投票:0回答:2

我在理解上遇到了问题,如下:


  def doSomething(): F[String] = {

    for {
      _ <- Future.traverse(items)(item => doSomeWork(item)) // Future[]
      _ <- doSomeOtherWork(42)  //F[]
    } yield (())

  }

函数doSomeWork看起来像:

  def doSomeWork(item: Item): Future[Unit] =
         // some work done inside a Future
    )

并且函数doSomeOtherWork的工作类似于:

    def doSomeOtherWork(i : Int): F[Unit]

因此,当我尝试编译时,出现以下错误:

[error]  found   : F[Int]
[error]  required: scala.concurrent.Future[?]
[error]       
[error]         ^
[error] type mismatch;
[error]  found   : scala.concurrent.Future[Nothing]
[error]  required: F[Int]

我不允许在这样的comp中混合F []和Future吗?

scala scala-cats
2个回答
0
投票

不,这是不可能的。因为for理解只是map和flatMap调用的语法糖,所以您的程序实际上如下所示:

(_: Future[Int]).flatMap(doSomeOtherWork).map(())

并且由于Future.flatMap期望函数再次返回Future,所以程序将被编译器拒绝。


0
投票

不,你不能。用于理解只是用于调用flatMapmap糖语法。而那些只能在同一单子上工作。

[如果无法更改doSomeWork以返回F,您可以做的最好的就是将您的期货转换为上的Fs

这里是您可能如何执行此操作的示例。((我不得不发明许多细节,因为您的问题非常含糊)

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 ()

使用cats-effect 2.0.0测试。

© www.soinside.com 2019 - 2024. All rights reserved.