Skip to content

Commit

Permalink
Enable breakout in functions nonEmptyTraverse_ and nonEmptySequence_ (#…
Browse files Browse the repository at this point in the history
…3545)

* Enable breakout in functions nonEmptyTraverse_ and nonEmptySequence_

* f => f andThen G.void
  • Loading branch information
takayahilton authored Aug 4, 2020
1 parent 84c2e76 commit 66e6e11
Show file tree
Hide file tree
Showing 2 changed files with 15 additions and 4 deletions.
8 changes: 5 additions & 3 deletions core/src/main/scala/cats/Reducible.scala
Original file line number Diff line number Diff line change
Expand Up @@ -181,8 +181,10 @@ import scala.annotation.implicitNotFound
* available for `G` and want to take advantage of short-circuiting
* the traversal.
*/
def nonEmptyTraverse_[G[_], A, B](fa: F[A])(f: A => G[B])(implicit G: Apply[G]): G[Unit] =
G.void(reduceLeftTo(fa)(f)((x, y) => G.map2(x, f(y))((_, b) => b)))
def nonEmptyTraverse_[G[_], A, B](fa: F[A])(f: A => G[B])(implicit G: Apply[G]): G[Unit] = {
val f1 = f.andThen(G.void)
reduceRightTo(fa)(f1)((x, y) => G.map2Eval(f1(x), y)((_, b) => b)).value
}

/**
* Sequence `F[G[A]]` using `Apply[G]`.
Expand All @@ -192,7 +194,7 @@ import scala.annotation.implicitNotFound
* [[nonEmptyTraverse_]] documentation for a description of the differences.
*/
def nonEmptySequence_[G[_], A](fga: F[G[A]])(implicit G: Apply[G]): G[Unit] =
G.void(reduceLeft(fga)((x, y) => G.map2(x, y)((_, b) => b)))
nonEmptyTraverse_(fga)(identity)

def toNonEmptyList[A](fa: F[A]): NonEmptyList[A] =
reduceRightTo(fa)(a => NonEmptyList(a, Nil)) { (a, lnel) =>
Expand Down
11 changes: 10 additions & 1 deletion tests/src/test/scala/cats/tests/ReducibleSuite.scala
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,16 @@ class ReducibleSuiteAdditional extends CatsSuite {

notAllEven.reduceMapA { a => out += a; if (a % 2 == 0) Some(a) else None }

assert(out.toList === (List(2, 4, 6, 9)))
assert(out.toList === List(2, 4, 6, 9))
}

test("Reducible[NonEmptyList].nonEmptyTraverse_ can breakout") {
val notAllEven = NonEmptyList.of(2, 4, 6, 9, 10, 12, 14)
val out = mutable.ListBuffer[Int]()

notAllEven.nonEmptyTraverse_ { a => out += a; if (a % 2 == 0) Some(a) else None }

assert(out.toList === List(2, 4, 6, 9))
}

// A simple non-empty stream with lazy `foldRight` and `reduceRightTo` implementations.
Expand Down

0 comments on commit 66e6e11

Please sign in to comment.