Reputation: 753
I'm curious why scala.util.Try
has no type parameter for the exception type like
abstract class Try[+E <: Throwable, +T] {
recoverWith[U >: T](f: PartialFunction[E, Try[E, U]]): Try[E, U]
...
}
Would help with documentation, e.g
def parseInt(s: String): Try[NumberFormatException, Int]
Still won't be able to express disjoint exception types like throws SecurityException, IllegalArgumentException
, but at least one step in this direction.
Upvotes: 4
Views: 993
Reputation: 38217
This might be what you're looking for:
import scala.util.control.Exception._
import scala.util.{ Success, Failure }
def foo(x: Int): Int = x match {
case 0 => 3
case 1 => throw new NumberFormatException
case _ => throw new NullPointerException
}
val Success(3) = catching(classOf[NumberFormatException]).withTry(foo(0))
val Failure(_: NumberFormatException) = catching(classOf[NumberFormatException]).withTry(foo(1))
// val neverReturns = catching(classOf[NumberFormatException]).withTry(foo(2))
See scala.util.control.Exception$
However, there's no way to specialize Try[T]
to something like the hypothetical Try[ExcType, T]
; in order for that to work you'll need something like Either
(but possibly something more sophisticated such as scalaz.\/
, or, for more than 1 exception class, Shapeless' Coproduct
):
def bar(x: Int): Either[NumberFormatException, Int] = {
catching(classOf[NumberFormatException]).withTry(foo(x)) match {
case Success(x) => Right(x)
case Failure(exc) => Left(exc.asInstanceOf[NumberFormatException])
}
}
println(bar(0)) // Right(3)
println(bar(1)) // Left(java.lang.NumberFormatException)
// println(bar(2)) // throws NullPointerException
It should be possible to generalize that into a generic helper that works with any number of exception types. You'd definitely have to work with Shapeless' Coproduct
and facilities for abstracting over arity in that case. Unfortunately, it's a non-trivial exercise and I don't have the time to implement that for you right now.
Upvotes: 3