在Scala中要么尝试,要么相反

Mic*_*ael 23 scala

是否有任何转换EitherTry反之亦然在Scala的标准库?也许我错过了一些东西,但我找不到它们.

cmb*_*ter 17

据我所知,标准库中不存在这种情况.虽然a Either通常用于Left失败和Right成功,但它实际上是为了支持两种可能的返回类型的概念,其中一种不一定是失败的情况.我猜测人们期望存在的这些转换不存在,因为Either它并不是真的被设计为成功/失败的monad 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)
}
Run Code Online (Sandbox Code Playgroud)

  • 虽然这是一个很好的解决方案,但是从2018年开始,`toTry`和`toEither`都包含在scala 2.12中.可能值得在您的答案顶部添加编辑. (7认同)

fla*_*ian 14

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)
  }
}
Run Code Online (Sandbox Code Playgroud)


Mar*_*s K 10

在Scala 2.12.x中尝试使用toEither方法:http://www.scala-lang.org/api/2.12.x/​​scala/util/Try.html#toEither:scala.util.Either[Throwable,T ]

  • 2.12 还有一个 Either.toTry 方法http://www.scala-lang.org/api/2.12.0/scala/util/Either.html#toTry(implicitev:&lt;:&lt;[A,Throwable]):scala。 util.Try[B] (2认同)

Tod*_*wen 5

答案取决于如何转换FailureLeft(反之亦然).如果您不需要使用异常的详细信息,那么Try可以Either通过以下中间路由转换为Option:

val tried = Try(1 / 0)
val either = tried.toOption.toRight("arithmetic error")
Run Code Online (Sandbox Code Playgroud)

另一种方式的转换需要你构造一些Throwable.可以这样做:

either.fold(left => Failure(new Exception(left)), right => Success(right))
Run Code Online (Sandbox Code Playgroud)