Scala 将两个EitherT合并,如果成功,则首先返回,否则返回第二个

Scala 将两个EitherT合并,如果成功,则首先返回,否则返回第二个,scala,scala-cats,either,Scala,Scala Cats,Either,考虑以下代码段: def foo(x:String): EitherT[F, Throwable, String] = ??? def bar(x:String): EitherT[F, Throwable, String] = ??? 我希望: 在某些输入上,首先调用foo(s),如果“失败”,则返回bar(s)的输出,否则返回foo(s),而不调用bar(s)。我得出了以下结论 def foobar(s:String) = { val f = foo(s) // if f is s

考虑以下代码段:

def foo(x:String): EitherT[F, Throwable, String] = ???
def bar(x:String): EitherT[F, Throwable, String] = ???
我希望:

在某些输入上,首先调用
foo(s)
,如果“失败”,则返回
bar(s)
的输出,否则返回
foo(s)
,而不调用
bar(s)
。我得出了以下结论

def foobar(s:String) = {
  val f = foo(s)
  // if f is successful return f else return bar(s)
  f.biflatMap(_ => bar(s), _ => f)
}

有没有更好的方法来做我想做的事

是,
recoverWith

foo(s).recoverWith { _ =>
 bar(s)
}

许多其他错误处理monad都有类似的约定:
.recover
将错误类型转换为成功类型,而
.recoverWith
将错误类型转换为整个monad类型。有时它们分别被命名为
handle
handleWith
。不带
的方法总是进行纯值计算,带
的方法总是进行monad/包装类型计算。

是,
恢复带

foo(s).recoverWith { _ =>
 bar(s)
}

许多其他错误处理monad都有类似的约定:
.recover
将错误类型转换为成功类型,而
.recoverWith
将错误类型转换为整个monad类型。有时它们分别被命名为
handle
handleWith
。不带
With
的方法总是进行纯值计算,而带
With
的方法总是进行monad/包装类型计算。

以下是一些实现

  import cats.implicits._
  import import cats.data.EitherT


  foo("").biflatMap(
    err => bar(""),
    str => EitherT.fromEither[F](str.asRight[Throwable])
  )

  foo("").biflatMap(
    err => bar(""),
    str => EitherT.liftF(str.pure[F])
  )

  foo("").leftFlatMap(
    err => bar("")
  )

  foo("").recoverWith(err => bar(""))

  for {
    err <- foo("")
    x <- bar("")
  } yield x
导入cats.implicits_
导入cats.data.EitherT
foo(“”)双平面图(
err=>bar(“”),
str=>EitherT.from[F](str.asRight[Throwable])
)
foo(“”)双平面图(
err=>bar(“”),
str=>EitherT.liftF(str.pure[F])
)
foo(“”)。leftFlatMap(
err=>bar(“”)
)
foo(“”).recoverWith(err=>bar(“”)
为了{

err以下是一些实现

  import cats.implicits._
  import import cats.data.EitherT


  foo("").biflatMap(
    err => bar(""),
    str => EitherT.fromEither[F](str.asRight[Throwable])
  )

  foo("").biflatMap(
    err => bar(""),
    str => EitherT.liftF(str.pure[F])
  )

  foo("").leftFlatMap(
    err => bar("")
  )

  foo("").recoverWith(err => bar(""))

  for {
    err <- foo("")
    x <- bar("")
  } yield x
导入cats.implicits_
导入cats.data.EitherT
foo(“”)双平面图(
err=>bar(“”),
str=>EitherT.from[F](str.asRight[Throwable])
)
foo(“”)双平面图(
err=>bar(“”),
str=>EitherT.liftF(str.pure[F])
)
foo(“”)。leftFlatMap(
err=>bar(“”)
)
foo(“”).recoverWith(err=>bar(“”)
为了{

err看起来更好,在Scala 2.13中也可以正常工作,但在Scala cats.data.EitherT[Scala.concurrent.Future,Throwable,String]中出现了一个错误:PartialFunction[Throwable,cats.data.EitherT[Scala.concurrent.Future,Throwable,String]]
对于2.12,在您必须显式地将其变为部分函数之前-将
\uuu
替换为
case\uu1:Throwable
,您就可以开始了。对于较旧的scala版本,生成部分函数似乎也会产生问题。新的错误是
无法找到参数F:cats.Monad[scala.concurrent.Future]的隐式值recoverWith方法的参数不足:(隐式F:cats.Monad[scala.concurrent.Future])cats.data.EitherT[scala.concurrent.Future,Throwable,String].Unspecified value参数F.
:)您缺少
隐式定义ec:scala.concurrent.ExecutionContext
-see看起来更好,在scala 2.13中运行良好,但在scala cats.data.EitherT[scala.concurrent.Future,Throwable,String]中出现错误需要:PartialFunction[Throwable,cats.data.EitherT[scala.concurrent.Future,Throwable,String]]
对于2.12,在您必须显式地将其变为部分函数之前-将
\uuu
替换为
case\uu1:Throwable
,您就可以开始了。对于较旧的scala版本,生成部分函数似乎也会产生问题。新的错误是
无法找到参数F:cats.Monad[scala.concurrent.Future]的隐式值recoverWith方法的参数不足:(隐式F:cats.Monad[scala.concurrent.Future])cats.data.EitherT[scala.concurrent.Future,Throwable,String]。未指定值参数F.
:)缺少
隐式定义ec:scala.concurrent.ExecutionContext
-请参阅