4

私は scala.concurrent.Future で Scalaz eitherT を使用しようとしています。for-comprehension で使用しようとすると、次のようになります。

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

2

このエラーは、ExecutionContext が見つからないためではなく (必要ですが)、Scala Future がファンクターでもモナドでもないためです。

受け入れられた解決策は、ExecutionContext のためではなく、Scalaz からすべての暗黙をインポートするために機能します。

これは、問題を実際に修正する行です。

import Scalaz._

また、グローバル実行コンテキストを使用してもテストには問題ありませんが、運用環境では使用しないでください。

このソリューションの問題点は、ライブラリで定義されたすべての Implicit をインポートすると、IDE が少し遅くなる可能性があることです。

バージョン 7 の Scalaz では、 package を使用して、必要なものだけをインポートするオプションが提供されています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 に答える