Я не уверен, что семантика полностью изоморфна между Try[A]
и Either[Throwable, A]
.Например, мы можем изменить смещение 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
s фактически ожидаемый результат и, следовательно, хотел бы их на стороне Right
.Возможно, мы создаем некую чисто функциональную библиотеку тестирования, где мы хотим предоставить API для утверждения об исключениях.Можно представить кодирование этой семантики как Either[A, Throwable]
.
Другим потенциальным преимуществом Either
над Try
могут быть кошки, предоставляющие для него больше методов расширения.Например, рассмотрим все вкусности в import cats.syntax.either._
, пока я не знаю о подобных для Try
.Скажем, мы хотим накапливать все ошибки в списке вместо короткого замыкания, тогда мы можем просто traverse(_.toValidatedNec)
вот так
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
Я думаю, нам придется работать усерднее.