DennisVDB DennisVDB - 5 months ago 28
Scala Question

Future[List[Error \/ Double]] to Future[[List[Error] \/ List[Double]] in Scala

I'm playing around with Scala(z) to learn functionnal programming.

I have a value of type

Future[List[Error \/ Double]]
and want to transform it to something with the type
Future[[List[Error] \/ List[Double]]

The goal is to group the lefts and rights.

I currently have the following:

val foo: Future[List[Error] \/ List[Double]] = {
for {
results <- resultsF
} yield
results.foldLeft(\/[List[Error], List[Double]])({
case (acc, v) if v.isRight => v :: \/-(acc)
case (acc, v) if v.isLeft => v :: -\/(acc)

However, I get an error on the
which is due to the fact that my accumulator is not a list (from the outside)
\/[List[Error], List[Double]]
. How should it be done?

Ven Ven

This function in Haskell would be partitionEithers: [Either a b] -> ([a], [b]).

(you don't actually want Either [a] [b], that wouldn't really make sense. I'm guessing you want this function instead because of the text in your description...)

Scalaz doesn't have it as-is. However, it has a more general separate:

/** Generalized version of Haskell's `partitionEithers` */
def separate[G[_, _], A, B](value: F[G[A, B]])(implicit G: Bifoldable[G]): (F[A], F[B])

Which is basically Bifoldable g -> f (g a b) -> (f a), (f b). You can simply call it on your list (where g = \/ (or Either), f = List).

In action:

scala> import scalaz._, Scalaz._
scala> List(\/-(3), -\/("a")).separate
res1: (List[String], List[Int]) = (List(a),List(3))