问题描述
很久以前,我们团队内部就使用 Try [A]
与 Ether [Throwable,A]
进行了长时间的辩论,最终我们选择了 Try [A]
,因为当 Ether
的左侧为 Throwable
时,它们在语义上是相同的.那时我正在搜索使用 Either [Throwable,A]
的代码库,但找不到任何代码.
Long time back we had long debate within our team on using Try[A]
vs Either[Throwable, A]
and we ended up choosing Try[A]
because those are semantically same when left side of Either
is Throwable
. That time I was searching for a codebase where Either[Throwable, A]
is used but I couldn't find any.
但是今天,在观看Fabio Labella在上的讲话时,纤维如何工作?幕后偷看,签名让我印象深刻
But today while watching Fabio Labella's talk on How do Fibers Work? A Peek Under the Hood, following signature struck my mind
def async[A](k: (Either[Throwable, A] => Unit) => Unit): F[A]
所以我的问题是,使用 Ether [Throwable,A]
而不是 Try [A]
有什么特殊的原因吗?推荐哪一个?
So my question is, Is there any specific reason for using Either[Throwable, A]
instead of Try[A]
? Which one is recommended?
推荐答案
我不确定 Try [A]
和 Either [Throwable,A]
.例如,我们可以更改 Either
I am not sure semantics are entirely isomorphic between Try[A]
and Either[Throwable, A]
. For example, we can change the bias of Either
val e: Either[Throwable, Int] = Left(new Exception("boom"))
for (s <- e.left) yield s.getMessage.length
res5: scala.util.Either[Int,Int] = Left(4)
或交换双方
e.swap
res6: scala.util.Either[Int,Throwable] = Right(java.lang.Exception: boom)
考虑一些不常见的情况,我们认为 Throwable
实际上是 expected 的结果,因此希望它们在 Right
端.也许我们正在构建一些纯功能的测试库,我们想在其中提供一个用于断言异常的API.可以想象将这些语义编码为 Either [A,Throwable]
.
Consider some unusual scenario where we consider Throwable
s to actually be the expected result and hence would want them on the Right
side. Perhaps we are building some pure-functional testing library where we want to provide an API for asserting on exceptions. One could imagine encoding these semantics as Either[A, Throwable]
.
与 Try
相比, Ething
的另一个潜在优势可能是猫为它提供了更多扩展方法.例如,考虑 import cats.syntax.about ._
中的所有好东西,而我不知道 Try
的相似之处.假设我们要在列表中累积所有错误,而不是短路,那么我们可以像这样简单地 traverse(_.toValidatedNec)
Another potential advantage of Either
over Try
might be cats providing more extension methods for it. For example, consider all the goodies in import cats.syntax.either._
whilst I am not aware of similar for Try
. Say we want to accumulate all the errors in a list instead of short-circuit, then we can simply traverse(_.toValidatedNec)
like so
import cats.syntax.either._
import cats.instances.list._
import cats.syntax.traverse._
val l: List[Either[Throwable, Int]] = List(Right(1), Right(2), Left(new RuntimeException("boom")), Right(3), Left(new RuntimeException("crash")))
l.traverse(_.toValidatedNec)
res0: cats.data.ValidatedNec[Throwable,List[Int]] = Invalid(Chain(java.lang.RuntimeException: boom, java.lang.RuntimeException: crash))
要实现与 Try
类似的功能,我认为我们必须更加努力.
To achieve similar with Try
I think we would have to work harder.
这篇关于为什么猫的效果异步签名使用Either [Throwable,A]而不使用Try [A]?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!