合并两个 EitherT,return first if it succeeds else return second
Combining two EitherT, return first if it succeeds else return second
考虑以下片段:
def foo(x:String): EitherT[F, Throwable, String] = ???
def bar(x:String): EitherT[F, Throwable, String] = ???
我想要以下内容:
在某些输入 s
上,首先调用 foo(s)
如果它 "fails" return bar(s)
的输出,否则 return 输出的 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
。没有With
的方法总是进行纯值计算,而有With
的方法总是进行monad/wrapper类型的计算。
下面是一些实现
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
希望对您有所帮助
考虑以下片段:
def foo(x:String): EitherT[F, Throwable, String] = ???
def bar(x:String): EitherT[F, Throwable, String] = ???
我想要以下内容:
在某些输入 s
上,首先调用 foo(s)
如果它 "fails" return bar(s)
的输出,否则 return 输出的 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
。没有With
的方法总是进行纯值计算,而有With
的方法总是进行monad/wrapper类型的计算。
下面是一些实现
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
希望对您有所帮助