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
-请参阅