Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the difference between Try and Either?

Tags:

According to the documentation:

The Try type represents a computation that may either result in an exception, or return a successfully computed value. It's similar to, but semantically different from the scala.util.Either type.

The docs do not go into further detail as to what the semantic difference is. Both seem to be able to communicate successes and failures. Why would you use one over the other?

like image 310
Peter Bratton Avatar asked Apr 21 '15 17:04

Peter Bratton


People also ask

Is try a Monad?

Show activity on this post. With unit = Try , Try is not a monad, because the left unit law fails.

What is try in Scala?

The Try type represents a computation that may either result in an exception, or return a successfully computed value. It's similar to, but semantically different from the scala. util. Either type. Instances of Try[T] , are either an instance of scala.

What is either in Scala?

In Scala Either, functions exactly similar to an Option. The only dissimilarity is that with Either it is practicable to return a string which can explicate the instructions about the error that appeared.


2 Answers

I covered the relationship between Try, Either, and Option in this answer. The highlights from there regarding the relationship between Try and Either are summarized below:

Try[A] is isomorphic to Either[Throwable, A]. In other words you can treat a Try as an Either with a left type of Throwable, and you can treat any Either that has a left type of Throwable as a Try. It is conventional to use Left for failures and Right for successes.

Of course, you can also use Either more broadly, not only in situations with missing or exceptional values. There are other situations where Either can help express the semantics of a simple union type (where value is one of two types).

Semantically, you might use Try to indicate that the operation might fail. You might similarly use Either in such a situation, especially if your "error" type is something other than Throwable (e.g. Either[ErrorType, SuccessType]). And then you might also use Either when you are operating over a union type (e.g. Either[PossibleType1, PossibleType2]).

The standard library does not include the conversions from Either to Try or from Try to Either, but it is pretty simple to enrich Try, and Either as needed:

object TryEitherConversions {     implicit class EitherToTry[L <: Throwable, R](val e: Either[L, R]) extends AnyVal {         def toTry: Try[R] = e.fold(Failure(_), Success(_))     }      implicit class TryToEither[T](val t: Try[T]) extends AnyVal {         def toEither: Either[Throwable, T] = t.map(Right(_)).recover(PartialFunction(Left(_))).get     } } 

This would allow you to do:

import TryEitherConversions._  //Try to Either Try(1).toEither //Either[Throwable, Int] = Right(1) Try("foo".toInt).toEither //Either[Throwable, Int] = Left(java.lang.NumberFormatException)  //Either to Try Right[Throwable, Int](1).toTry //Success(1) Left[Throwable, Int](new Exception).toTry //Failure(java.lang.Exception) 
like image 178
Ben Reich Avatar answered Oct 13 '22 00:10

Ben Reich


To narrowly answer your question: "What's the semantic difference":

This probably refers to flatMap and map, which are non-existent in Either and either propagate failure or map the success value in Try. This allows, for instance, chaining like

for {     a <- Try {something}     b <- Try {somethingElse(a)}    c <- Try {theOtherThing(b)} } yield c 

which does just what you'd hope - returns a Try containing either the first exception, or the result.

Try has lots of other useful methods, and of course its companion apply method, that make it very convenient for its intended use - exception handling.

If you really want to be overwhelmed, there are two other classes out there which may be of interest for this kind of application. Scalaz has a class called "\/" (formerly known as Prince), pronounced "Either", which is mostly like Either, but flatMap and map work on the Right value. Similarly, and not, Scalactic has an "Or" which is also similar to Either, but flatMap and map work on the Left value.

I don't recommend Scalaz for beginners.

like image 30
Ed Staub Avatar answered Oct 13 '22 00:10

Ed Staub