From ce0f24b57b429580aa0cd43b7e8d0b99a736f485 Mon Sep 17 00:00:00 2001 From: zainab-ali Date: Mon, 24 Oct 2016 22:42:40 +0100 Subject: [PATCH] Adding sequenceM method to Traverse (#1394) * Adding sequenceM method to Traverse * renaming sequenceM to traverseM * Changing traverseM to flatTraverse and sequenceA to flatSequence --- core/src/main/scala/cats/Traverse.scala | 22 +++++++++++++++++-- .../test/scala/cats/tests/SyntaxTests.scala | 2 +- 2 files changed, 21 insertions(+), 3 deletions(-) diff --git a/core/src/main/scala/cats/Traverse.scala b/core/src/main/scala/cats/Traverse.scala index 7e34eef82b..32e83215cb 100644 --- a/core/src/main/scala/cats/Traverse.scala +++ b/core/src/main/scala/cats/Traverse.scala @@ -58,11 +58,11 @@ import simulacrum.typeclass * scala> import cats.implicits._ * scala> def parseInt(s: String): Option[Int] = Either.catchOnly[NumberFormatException](s.toInt).toOption * scala> val x = Option(List("1", "two", "3")) - * scala> x.traverseM(_.map(parseInt)) + * scala> x.flatTraverse(_.map(parseInt)) * res0: List[Option[Int]] = List(Some(1), None, Some(3)) * }}} */ - def traverseM[G[_], A, B](fa: F[A])(f: A => G[F[B]])(implicit G: Applicative[G], F: FlatMap[F]): G[F[B]] = + def flatTraverse[G[_], A, B](fa: F[A])(f: A => G[F[B]])(implicit G: Applicative[G], F: FlatMap[F]): G[F[B]] = G.map(traverse(fa)(f))(F.flatten) /** @@ -83,6 +83,24 @@ import simulacrum.typeclass def sequence[G[_]: Applicative, A](fga: F[G[A]]): G[F[A]] = traverse(fga)(ga => ga) + /** + * Thread all the G effects through the F structure and flatten to invert the + * structure from F[G[F[A]]] to G[F[A]]. + * + * Example: + * {{{ + * scala> import cats.implicits._ + * scala> val x: List[Option[List[Int]]] = List(Some(List(1, 2)), Some(List(3))) + * scala> val y: List[Option[List[Int]]] = List(None, Some(List(3))) + * scala> x.flatSequence + * res0: Option[List[Int]] = Some(List(1, 2, 3)) + * scala> y.flatSequence + * res1: Option[List[Int]] = None + * }}} + */ + def flatSequence[G[_], A](fgfa: F[G[F[A]]])(implicit G: Applicative[G], F: FlatMap[F]): G[F[A]] = + G.map(sequence(fgfa))(F.flatten) + /** * Behaves just like sequence, but uses [[Unapply]] to find the * Applicative instance for G. diff --git a/tests/src/test/scala/cats/tests/SyntaxTests.scala b/tests/src/test/scala/cats/tests/SyntaxTests.scala index c3c040ac8c..23172cd7bc 100644 --- a/tests/src/test/scala/cats/tests/SyntaxTests.scala +++ b/tests/src/test/scala/cats/tests/SyntaxTests.scala @@ -133,7 +133,7 @@ object SyntaxTests extends AllInstances with AllSyntax { val gfb: G[F[B]] = fa.traverse(f1) val f2 = mock[A => G[F[B]]] - val gfb2: G[F[B]] = fa.traverseM(f2) + val gfb2: G[F[B]] = fa.flatTraverse(f2) val fga = mock[F[G[A]]] val gunit: G[F[A]] = fga.sequence