leftFlatMap
가장 가까운 것은 당신이 뭔가라는 leftFlatMap
(에서 기대할 수 정확히 서명이 MonadError
의 handleError
,하지만 당신은 EitherT
로 대체 동작을 변경하고 일정한 기능을 제공해야합니다 노트 그대로 전달하는 대신). 이 같은 직접 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)
또한 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)
나는이 두 번째 버전을 선호하는 것,하지만 그것은 스타일과 취향의 문제입니다.