Подтвердить что ты не робот

Либо попробовать, либо наоборот в Scala

Есть ли какие-либо преобразования из Either в Try и наоборот в стандартной библиотеке Scala? Может быть, я что-то упустил, но я не нашел их.

4b9b3361

Ответ 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)
  }
}

Ответ 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))