Currently, I am doing this for some code that is a Seq[Either[L, R]]
, where converter
is a function of String => Checkout
where Checkout
is a custom case class
.
Using(Source.fromResource(str))(resource => resource.getLines()
.map(converter)
.filter(_.isRight)
.map(_.getOrElse(Checkout("", "", LocalDate.of(1971, 1, 1))))
.toSeq)
Another alternative would be:
Using(Source.fromResource(str))(resource => resource.getLines()
.map(converter)
.collect{case Right(x) => x}
.toSeq)
Both have a smell. The first particularly since I already filtered all the Right
and I don’t like that I have to create a dummy object with a getOrElse
to get the Right
objects and just have a list or other collections just with Right
elements. As for the collect
, it also seems a bit off, but better than the first.
A List[Option]
has a great feature of flatten
val xs = List(Some(3), None, Some(4), None)
xs.flatten
which results of course in
List(3, 4)
I would love to make my call above to be…
Using(Source.fromResource(str))(resource => resource.getLines()
.map(converter)
.flatten
.toSeq)
where flatten
for any collection would only keep the “positive” elements of a monadic type (Success
, Right
, etc) much in the same way it works with Option
. Currently, flatten
does not work with Either
.