4

我正在尝试将 Scalaz EitherT 与 scala.concurrent.Future 一起使用。当试图在理解中使用它时:

import scalaz._
import Scalaz._

val et1:EitherT[Future, String, Int] = EitherT(Future.successful(1.right))

val et2:EitherT[Future, String, String] = EitherT(Future.successful("done".right))

val r:EitherT[Future, String, String] = for {
    a <- et1
    b <- et2
} yield (s"$a $b")

我收到以下缺少 Functor 和 Monad 实例的错误:

could not find implicit value for parameter F: scalaz.Functor[scala.concurrent.Future]
b <- et2
  ^
could not find implicit value for parameter F: scalaz.Monad[scala.concurrent.Future]
a <- et1

scalaz 是否为 Future 定义 Functor 和 Monad 的实例?如果没有,是否有任何其他库提供这些实例,或者我是否需要编写它们?

4

2 回答 2

16

你需要一个隐含ExecutionContext的范围。import ExecutionContext.Implicits.global将为您提供全局执行上下文

完整示例:

  import scala.concurrent.ExecutionContext.Implicits.global

  import scalaz._
  import Scalaz._

  val et1:EitherT[Future, String, Int] = EitherT(Future.successful(1.right))

  val et2:EitherT[Future, String, String] = EitherT(Future.successful("done".right))

  val r:EitherT[Future, String, String] = for {
    a <- et1
    b <- et2
  } yield s"$a $b"

  val foo = Await.result(r.run, 1 seconds)
  // => \/-("1 done")
于 2015-12-22T02:22:23.690 回答
2

该错误不是因为缺少 ExecutionContext(尽管它是必需的),而是因为 Scala Future 不是 Functor 也不是 Monad。

公认的解决方案之所以有效,不是因为 ExecutionContext,而是因为它从 Scalaz 导入了所有隐式。

这是真正解决问题的行:

import Scalaz._

另请注意,使用全局执行上下文可以进行测试,但不应在生产部署中使用。

该解决方案的问题在于您导入了库中定义的所有隐式,并且可能会使您的 IDE 有点慢。

在版本 7 上,Scalaz 提供了使用包仅导入您需要的选项的选项scalaz.syntax

与具体进口相同的先前解决方案:

import scala.concurrent.duration._
import scala.concurrent.ExecutionContext.Implicits.global
import scala.concurrent._

import scalaz._
import scalaz.std.scalaFuture._
import scalaz.syntax.either._

val et1:EitherT[Future, String, Int] = EitherT(Future.successful(1.right))

val et2:EitherT[Future, String, String] = EitherT(Future.successful("done".right))

val r:EitherT[Future, String, String] = for {
  a <- et1
  b <- et2
} yield s"$a $b"

val foo = Await.result(r.run, 1 seconds)
foo: String \/ String = \/-(1 done)
于 2019-06-22T15:39:06.227 回答