scala – 在EitherT上的左平面地图
发布时间:2020-12-16 10:07:06 所属栏目:安全 来源:网络整理
导读:假设我有返回Future的函数[要么[_,_],我想在失败的情况下应用其中的一些函数,这意味着只将它们应用于左侧.简化的例子是: def operation1: Future[Either[String,Int]] = Future.successful(Right(5))def operation2: Future[Either[String,Int]] = Future.s
假设我有返回Future的函数[要么[_,_],我想在失败的情况下应用其中的一些函数,这意味着只将它们应用于左侧.简化的例子是:
def operation1: Future[Either[String,Int]] = Future.successful(Right(5)) def operation2: Future[Either[String,Int]] = Future.successful(Left("error")) def operation2FallBackWork = Future.successful{ println("Doing some revert stuff") Left("Error happened,but reverting was successful") } val res = for { res1 <- EitherT.fromEither(operation1) res2 <- EitherT.fromEither(operation2)//.leftFlatMap(operation2FallBackWork) -???? } yield res1 + res2 Await.result(res.toEither,5 seconds) 怎么实现呢? 解决方法
与leftFlatMap最接近的是MonadError的handleError,它具有你所期望的称为leftFlatMap的签名(尽管请注意,你需要将回退操作更改为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(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,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) 您还可以使用MonadError提供的语法使其看起来像EitherT有一个handleError方法,尽管让Scala编译器认识到您的操作具有正确的形状需要更多的仪式: import scala.concurrent.{ Await,Scalaz._ type FE[x] = EitherT[Future,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) 我更喜欢第二个版本,但这是一个风格和品味的问题. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |