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?
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, MonadPlus f => f (g a b) -> (f a), (f b)
. Specifically: [Either a b] -> ([a], [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))
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With