Does Cats provide flattening akin to
implicit class FlattenListOfEither[L, R](l: List[Either[L, R]]) {
def flattenM: List[R] = l collect { case Right(v) => v }
}
such that
val l1: List[Either[String, Int]] = List(Right(1), Right(2), Left("error"), Right(4))
l1.flattenM
outputs
List(1, 2, 4)
similar to how vanilla Scala flattens list of options
val l2: List[Option[Int]] = List(Some(1), Some(2), None, Some(4))
l2.flatten
which outputs
List(1, 2, 4)
separate
gives the following syntax
import cats.implicits._
val (_, rights) = l1.separate
rights
which outputs
List(1, 2, 4)
however does there exist out-of-the-box flatten
-like extension method which returns just the rights instead of the tuple?
I think the easiest is to use mapFilter
provided by the FunctorFilter
typeclass. It looks like this:
def mapFilter[A, B](fa: F[A])(f: (A) ⇒ Option[B]): F[B]
Where F[A]
could be List[A]
, or Vector[A]
or any other type that allows filtering.
If we apply this function to your list, we just need to turn the Either[A, B]
s into Option[B]
s. This is as easy as calling toOption
. With that the full solution looks like this:
import cats.implicits._
val l1: List[Either[String, Int]] = List(Right(1), Right(2), Left("error"), Right(4))
l1.mapFilter(_.toOption)
// List(1, 2, 4)
I just wanted to remark that
listOfEithers.flatMap(_.toOption)
with plain vanilla Scala-collection methods seems to do what you want:
val x = List(Right(1), Right(2), Left("error"), Right(4))
x.flatMap(_.toOption) // res0: List[Int] = List(1, 2, 4)
What about partitionMap
in Scala 2.13
? (note sure what you mean by shorter
):
val l1: List[Either[String, Int]] = List(Right(1), Right(2), Left("error"), Right(4))
val (_, rights) = l1.partitionMap(identity)
println(rights)
// Displays
// List(1, 2, 4)
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.