我正在尝试将Scalaz EitherT与scala.concurrent.Future一起使用。当试图在for-comprehension中使用它时:
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
我得到以下缺少的Functor和Monad实例错误:
days = WebtmsDay.arel_table
other_days = days[:day].not_in(['Monday', 'Tuesday', 'Thursday'])
WebtmsClass.where(WebtmsDay.where(other_days).exists.not)
scalaz是否定义了Functor和Monad for Future的实例?如果没有提供这些实例的其他库或我是否需要编写它们?
答案 0 :(得分:15)
您需要在范围内隐式ExecutionContext
。 import ExecutionContext.Implicits.global
将为您提供global execution context。
完整示例:
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")
答案 1 :(得分:0)
该错误不是由于缺少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)