tags:

views:

130

answers:

3

if a scala function is

def A(): Either[Exception, ArrayBuffer[Int]] = { ... }

what should be the right way to process the returned result? val a = A() and ?

+8  A: 

The easiest way is with pattern matching

val a = A()

a match{
case Left(exception) => // do something with the exception
case Right(arrayBuffer) => // do something with the arrayBuffer
}

Alternatively, there a variety of fairly straightforward methods on Either, which can be used for the job. Here's the scaladoc http://www.scala-lang.org/api/rc/scala/Either.html

Dave Griffith
+2  A: 

One way is

val a = A();
for (x <- a.left) {
  println("left: " + x)
}
for (x <- a.right) {
  println("right: " + x)
}

Only one of the bodies of the for expressions will actually be evaluated.

michid
Ok, this works, but in my opinion this is misusing `for` in an ugly way. If you see a `for`, you expect a loop, but here it's used as a kind of `if` statement. Pattern matching (see answer by Dave Griffith) is much cleaner and easier to understand.
Jesper
Well it depends. In Scala for expressions have broader semantics than looping. Basically everything which has map/flatmap can be used with for. This is convenient i.e. in the case of Option.
michid
+6  A: 

I generally prefer using fold. You can use it like map:

scala> def a: Either[Exception,String] = Right("On")

a.fold(l => Left(l), r => Right(r.length))
res0: Product with Either[Exception,Int] = Right(2)

Or you can use it like a pattern match:

scala> a.fold( l => {
     |   println("This was bad")
     | }, r => {
     |   println("Hurray! " + r)
     | })
Hurray! On

Or you can use it like getOrElse in Option:

scala> a.fold( l => "Default" , r => r )
res2: String = On
Rex Kerr
I should mention that if you _only_ want to use it to map the right-hand side, `a.right.map(_.length)` is less typing and does what you want. Generally, the `.right` and `.left` methods make `Either` work a lot like option, except instead of preserving `None` as the other case like `Option` does, it preserves whatever the opposite side of the `Either` is. Likewise, `a.right.getOrElse` is simpler than `fold`. What I like about `fold` is that you can do all of these things at once and combine them.
Rex Kerr