summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorcchantep <chantepie@altern.org>2014-10-29 17:25:01 +0100
committerAdriaan Moors <adriaan.moors@typesafe.com>2015-04-07 16:28:43 -0700
commitf10dcc76dff4aa9146cd1ec4052fe136f597a260 (patch)
tree80a69dfd9ddf9b4f246d1b475c832825de0c9eb5
parent293625e7bb685514ce82a0400bbd7ba5708d6553 (diff)
downloadscala-f10dcc76dff4aa9146cd1ec4052fe136f597a260.tar.gz
scala-f10dcc76dff4aa9146cd1ec4052fe136f597a260.tar.bz2
scala-f10dcc76dff4aa9146cd1ec4052fe136f597a260.zip
SI-8336: add `fold` & `toEither` to `util.Try`
`res.fold(fa, fb)` evaluates to `fa(e)` if `res` is a `Failure(e)`, or `fb(value)` if `res` is a `Success(value)`. (If `fb` throws an exception `e` when applied, `fa(e)`.)
-rw-r--r--src/library/scala/util/Try.scala30
-rw-r--r--test/files/jvm/try-type-tests.scala43
2 files changed, 73 insertions, 0 deletions
diff --git a/src/library/scala/util/Try.scala b/src/library/scala/util/Try.scala
index 1e6ae6c591..c807677119 100644
--- a/src/library/scala/util/Try.scala
+++ b/src/library/scala/util/Try.scala
@@ -174,6 +174,31 @@ sealed abstract class Try[+T] extends Product with Serializable {
* `s` if this is a `Success`.
*/
def transform[U](s: T => Try[U], f: Throwable => Try[U]): Try[U]
+
+ /**
+ * Returns `Left` with `Throwable` if this is a `Failure`, otherwise returns `Right` with `Success` value.
+ */
+ def toEither: Either[Throwable, T]
+
+ /**
+ * Applies `fa` if this is a `Failure` or `fb` if this is a `Success`.
+ * If `fb` is initially applied and throws an exception,
+ * then `fa` is applied with this exception.
+ *
+ * @example {{{
+ * val result: Try[Throwable, Int] = Try { string.toInt }
+ * log(result.fold(
+ * ex => "Operation failed with " + ex,
+ * v => "Operation produced value: " + v
+ * ))
+ * }}}
+ *
+ * @param fa the function to apply if this is a `Failure`
+ * @param fb the function to apply if this is a `Success`
+ * @return the results of applying the function
+ */
+ def fold[U](fa: Throwable => U, fb: T => U): U
+
}
object Try {
@@ -208,6 +233,8 @@ final case class Failure[+T](exception: Throwable) extends Try[T] {
try { if (pf isDefinedAt exception) pf(exception) else this } catch { case NonFatal(e) => Failure(e) }
override def failed: Try[Throwable] = Success(exception)
override def toOption: Option[T] = None
+ override def toEither: Either[Throwable, T] = Left(exception)
+ override def fold[U](fa: Throwable => U, fb: T => U): U = fa(exception)
}
@@ -236,4 +263,7 @@ final case class Success[+T](value: T) extends Try[T] {
override def recoverWith[U >: T](@deprecatedName('f) pf: PartialFunction[Throwable, Try[U]]): Try[U] = this
override def failed: Try[Throwable] = Failure(new UnsupportedOperationException("Success.failed"))
override def toOption: Option[T] = Some(value)
+ override def toEither: Either[Throwable, T] = Right(value)
+ override def fold[U](fa: Throwable => U, fb: T => U): U =
+ try { fb(value) } catch { case NonFatal(e) => fa(e) }
}
diff --git a/test/files/jvm/try-type-tests.scala b/test/files/jvm/try-type-tests.scala
index 962afbd30f..b3926020f0 100644
--- a/test/files/jvm/try-type-tests.scala
+++ b/test/files/jvm/try-type-tests.scala
@@ -118,6 +118,44 @@ trait TryStandard {
assert(f.transform(succ, fail).get == 0)
}
+ def testSuccessEither(): Unit = {
+ val t = Success(1)
+ assert(t.toEither.isRight)
+ }
+
+ def testFailureEither(): Unit = {
+ val t = Failure(new Exception("foo"))
+ assert(t.toEither.isLeft)
+ }
+
+ def testFoldSuccess(): Unit = {
+ val t = Success(1)
+ val res = t.fold("Throws " + _, "Returns " + _)
+ assert(res == "Returns 1")
+ }
+
+ def testFoldFailure(): Unit = {
+ val t = Failure(new Exception("foo"))
+ val res = t.fold("Throws " + _, "Returns " + _)
+ assert(res == "Throws java.lang.Exception: foo")
+ }
+
+ def testFoldSuccessFailure(): Unit = {
+ val t = Success(1)
+ val res = t.fold("Throws " + _, _ => throw new Exception("foo"))
+ assert(res == "Throws java.lang.Exception: foo")
+ }
+
+ def testFoldFailureFailure(): Unit = {
+ val t = Failure(new Exception("foo"))
+ val res = try {
+ t.fold(_ => throw new Exception("bar"), "Returns " + _)
+ } catch {
+ case e: Throwable => "Throws " + e
+ }
+ assert(res == "Throws java.lang.Exception: bar")
+ }
+
testForeachSuccess()
testForeachFailure()
testFlatMapSuccess()
@@ -136,6 +174,11 @@ trait TryStandard {
testFailedFailure()
testSuccessTransform()
testFailureTransform()
+ testSuccessEither()
+ testFailureEither()
+ testFoldSuccess()
+ testFoldFailure()
+ testFoldSuccessFailure()
}
object Test