Sebastien Lorber
Sebastien Lorber

Reputation: 92130

Try recoverWith with for-comprehension syntax?

Is there another way to write the following code?:

val graph: Try[Rdf#Graph] = readGraph(MimeType("text/turtle"),body,url) recoverWith {
  case e: Exception => {
    readGraph(MimeType("application/rdf+xml"),body,url) recoverWith {
      case e: Exception => {
        readGraph(MimeType("text/n3"),body,url)
      }
    }
  }
}

I'd like some syntax with less nested blocks because I may need to try many different mime types. Is there a way to do the same thing using for-comprehension?

Upvotes: 3

Views: 948

Answers (1)

som-snytt
som-snytt

Reputation: 39577

Maybe just orElse?

scala> import util._
import util._

scala> Try(???) orElse Try(7)
res0: scala.util.Try[Int] = Success(7)

I don't think "first success orElse first failure" generalizes nicely; there are similar questions about futures.

If you want the first failure while validating a bunch of values, then use scalaz.\/.

Or briefly:

  implicit class `try lacks toeither`[A](t: Try[A]) {
    def toEither: Either[Throwable, A] = Either.cond(t.isSuccess, t.get, t.failed.get)
  }
  implicit class `either lacks orelse try`[A](e: Either[Throwable, A]) {
    def orElse(default: =>Try[A]): Either[Throwable, A] = {
      def trymore(t: Throwable): Either[Throwable, A] = (default orElse Failure(t)).toEither
      e fold (trymore, _ => e)
    }
  }
  Console println {
    Try(null.toString).toEither orElse Try("ok") orElse Try("tried too hard")
  }
  Console println {
    Try(null.toString).toEither orElse Try(throw new RuntimeException("not ok"))
  }

//Right(ok)
//Left(java.lang.NullPointerException)

I can't tell offhand how grotesque that is.

Upvotes: 4

Related Questions