0

(Caveat - I'm a scala noob) Given a sequence of Eithers, viz

theResults : Seq[Either[Error, String]]

I am trying to extract all the Errors by using a map on the left(s)

theResults match {
  case r if r.exists(_.isLeft)  => {
    val errors = theResults.map(r => r.left)
    ...
  }

However, this returns

Seq[Either.LeftProjection[ErrorResponse, String]]

Instead of the Seq[ErrorResponse] as I was hoping for.

Please put me out of my misery?

StuartLC
  • 104,537
  • 17
  • 209
  • 285

2 Answers2

1

The easiest option would probably be:

val lefts = theResults.map(_.left.toOption).flatten

which will return a sequence of Error (or whatever the left type is).

Personally, I think that scalaz Either is nicer to work with, as it's right-biased...

Patryk Ćwiek
  • 14,078
  • 3
  • 55
  • 76
  • Thanks - the end result typing is correct, but is there a way to do this more directly, i.e. to avoid going through `Option`? – StuartLC May 26 '14 at 09:20
  • 1
    @StuartLC Of course, you can filter the sequence to only include left values, then map over the sequence and `.get` them. It's subjective, but I don't really see how that would improve the clarity of expression (e.g. `theResults.filter(_.isLeft).map(_.left.get)`). – Patryk Ćwiek May 26 '14 at 09:26
  • Thanks - I was simply missing `.left.get`. Will definitely look at using the option / flatten mechanism in future. – StuartLC May 26 '14 at 09:38
  • 3
    I find `.collect { case Left(e) => e }` more idiomatic. Also why not just `.flatMap(_.left.toOption)` if you're going this route? – Travis Brown May 26 '14 at 12:43
-2

How about this?

val lefts = theResults.filter(_.isLeft).map(_.asInstanceOf[Left].a)
cloud
  • 1,057
  • 7
  • 12