Есть ли какие-либо преобразования из Either
в Try
и наоборот в стандартной библиотеке Scala? Может быть, я что-то упустил, но я не нашел их.
Либо попробовать, либо наоборот в Scala
Ответ 1
Насколько мне известно, этого не существует в стандартной библиотеке. Хотя Either
обычно используется, когда Left
является сбойным, а Right
- успешным, он действительно был разработан для поддержки концепции двух возможных типов возврата, причем один из них не обязательно является случаем сбоя. Я предполагаю, что эти преобразования, которых можно было бы ожидать, не существуют, потому что Either
не был предназначен для того, чтобы быть монахом успеха/неудачи, например Try
. Сказав, что было бы очень легко обогатить Either
себя и добавить эти преобразования. Это может выглядеть примерно так:
object MyExtensions {
implicit class RichEither[L <: Throwable,R](e:Either[L,R]){
def toTry:Try[R] = e.fold(Failure(_), Success(_))
}
implicit class RichTry[T](t:Try[T]){
def toEither:Either[Throwable,T] = t.transform(s => Success(Right(s)), f => Success(Left(f))).get
}
}
object ExtensionsExample extends App{
import MyExtensions._
val t:Try[String] = Success("foo")
println(t.toEither)
val t2:Try[String] = Failure(new RuntimeException("bar"))
println(t2.toEither)
val e:Either[Throwable,String] = Right("foo")
println(e.toTry)
val e2:Either[Throwable,String] = Left(new RuntimeException("bar"))
println(e2.toTry)
}
Ответ 2
import scala.util.{ Either, Failure, Left, Right, Success, Try }
implicit def eitherToTry[A <: Exception, B](either: Either[A, B]): Try[B] = {
either match {
case Right(obj) => Success(obj)
case Left(err) => Failure(err)
}
}
implicit def tryToEither[A](obj: Try[A]): Either[Throwable, A] = {
obj match {
case Success(something) => Right(something)
case Failure(err) => Left(err)
}
}
Ответ 3
В Scala 2.12.x в Try есть метод toEither: http://www.scala-lang.org/api/2.12.x/scala/util/Try.html#toEither:scala.util.Either[Throwable,T].
Ответ 4
Ответ зависит от того, как преобразовать Failure
в Left
(и наоборот). Если вам не нужно использовать детали исключения, то Try
можно преобразовать в Either
, пройдя промежуточный маршрут Option
:
val tried = Try(1 / 0)
val either = tried.toOption.toRight("arithmetic error")
Преобразование другим способом требует от вас создания Throwable. Это можно сделать следующим образом:
either.fold(left => Failure(new Exception(left)), right => Success(right))