leftFlatMap
に最も近いものは、あなたがEitherT
にフォールバック操作を変更し、一定の機能を提供する必要がありますleftFlatMap
(ただし、ノートと呼ばれるものから期待正確に署名を持っているMonadError
さんhandleError
、ありますそのまま渡すのではなく)。あなたは直接このようEitherT
インスタンスを使用することができます。
import scala.concurrent.{ Await, Future }
import scala.concurrent.ExecutionContext.Implicits.global
import scala.concurrent.duration._
import scalaz._, Scalaz._
def operation1: Future[Either[String, Int]] = Future.successful(Right(5))
def operation2: Future[Either[String, Int]] = Future.successful(Left("error"))
def operation2FallBack: EitherT[Future, String, Int] = EitherT(
Future.successful {
println("Doing some revert stuff")
"Error happened, but reverting was successful".left
}
)
val E: MonadError[({ type L[x] = EitherT[Future, String, x] })#L, String] =
implicitly
val res = for {
a <- EitherT.fromEither(operation1)
b <- E.handleError(EitherT.fromEither(operation2))(_ => operation2FallBack)
} yield a + b
Await.result(res.toEither, 5.seconds)
それがScalaのコンパイラを取得するには、もう少し式典がかかりますが、あなたはまた、EitherT
はhandleError
メソッドを持っているようにそれが見えるようにMonadError
が提供する構文を使用することができます
import scala.concurrent.{ Await, Future }
import scala.concurrent.ExecutionContext.Implicits.global
import scala.concurrent.duration._
import scalaz._, Scalaz._
type FE[x] = EitherT[Future, String, x]
def operation1: FE[Int] = EitherT(Future.successful(5.right))
def operation2: FE[Int] = EitherT(Future.successful("error".left))
def operation2FallBack: FE[Int] = EitherT(
Future.successful {
println("Doing some revert stuff")
"Error happened, but reverting was successful".left
}
)
val res = for {
a <- operation1
b <- operation2.handleError(_ => operation2FallBack)
} yield a + b
Await.result(res.toEither, 5.seconds)
私はこの2番目のバージョンが好きですが、それはスタイルと趣味の問題です。