Skip to content

Commit

Permalink
Add sequenceFilter syntax (#2600)
Browse files Browse the repository at this point in the history
  • Loading branch information
kubukoz authored and Luka Jacobowitz committed Dec 7, 2018
1 parent f8324d4 commit 903617a
Show file tree
Hide file tree
Showing 5 changed files with 36 additions and 4 deletions.
1 change: 1 addition & 0 deletions core/src/main/scala/cats/implicits.scala
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ object implicits
with syntax.AllSyntaxBinCompat1
with syntax.AllSyntaxBinCompat2
with syntax.AllSyntaxBinCompat3
with syntax.AllSyntaxBinCompat4
with instances.AllInstances
with instances.AllInstancesBinCompat0
with instances.AllInstancesBinCompat1
Expand Down
3 changes: 3 additions & 0 deletions core/src/main/scala/cats/syntax/all.scala
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ abstract class AllSyntaxBinCompat
with AllSyntaxBinCompat1
with AllSyntaxBinCompat2
with AllSyntaxBinCompat3
with AllSyntaxBinCompat4

trait AllSyntax
extends AlternativeSyntax
Expand Down Expand Up @@ -77,3 +78,5 @@ trait AllSyntaxBinCompat2
with ValidatedSyntaxBincompat0

trait AllSyntaxBinCompat3 extends UnorderedFoldableSyntax with Function1Syntax

trait AllSyntaxBinCompat4 extends TraverseFilterSyntaxBinCompat0
2 changes: 1 addition & 1 deletion core/src/main/scala/cats/syntax/package.scala
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ package object syntax {
object strong extends StrongSyntax
object try_ extends TrySyntax
object traverse extends TraverseSyntax
object traverseFilter extends TraverseFilterSyntax
object traverseFilter extends TraverseFilterSyntax with TraverseFilterSyntaxBinCompat0
object nonEmptyTraverse extends NonEmptyTraverseSyntax
object unorderedFoldable extends UnorderedFoldableSyntax
object unorderedTraverse extends UnorderedTraverseSyntax
Expand Down
18 changes: 18 additions & 0 deletions core/src/main/scala/cats/syntax/traverseFilter.scala
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,21 @@ package cats
package syntax

trait TraverseFilterSyntax extends TraverseFilter.ToTraverseFilterOps

trait TraverseFilterSyntaxBinCompat0 {
implicit def toSequenceFilterOps[F[_], G[_], A](fgoa: F[G[Option[A]]]): SequenceFilterOps[F, G, A] =
new SequenceFilterOps(fgoa)
}

final class SequenceFilterOps[F[_], G[_], A](val fgoa: F[G[Option[A]]]) extends AnyVal {

/**
* {{{
* scala> import cats.implicits._
* scala> val a: List[Either[String, Option[Int]]] = List(Right(Some(1)), Right(Some(5)), Right(Some(3)))
* scala> val b: Either[String, List[Int]] = a.sequenceFilter
* b: Either[String, List[Int]] = Right(List(1, 5, 3))
* }}}
* */
def sequenceFilter(implicit F: TraverseFilter[F], G: Applicative[G]): G[F[A]] = F.traverseFilter(fgoa)(identity)
}
16 changes: 13 additions & 3 deletions tests/src/test/scala/cats/tests/SyntaxSuite.scala
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ import scala.collection.immutable.SortedSet
import scala.collection.immutable.SortedMap
import cats.arrow.Compose
import cats.data.{Binested, Nested, NonEmptyChain, NonEmptyList, NonEmptySet}
import cats.instances.AllInstances
import cats.syntax.{AllSyntax, AllSyntaxBinCompat}
import cats.instances.{AllInstances, AllInstancesBinCompat0, AllInstancesBinCompat1, AllInstancesBinCompat2}
import cats.syntax.AllSyntaxBinCompat

/**
* Test that our syntax implicits are working.
Expand All @@ -26,7 +26,12 @@ import cats.syntax.{AllSyntax, AllSyntaxBinCompat}
*
* None of these tests should ever run, or do any runtime checks.
*/
object SyntaxSuite extends AllSyntaxBinCompat with AllInstances with AllSyntax {
object SyntaxSuite
extends AllSyntaxBinCompat
with AllInstances
with AllInstancesBinCompat0
with AllInstancesBinCompat1
with AllInstancesBinCompat2 {

// pretend we have a value of type A
def mock[A]: A = ???
Expand Down Expand Up @@ -387,4 +392,9 @@ object SyntaxSuite extends AllSyntaxBinCompat with AllInstances with AllSyntax {
val grouped: SortedMap[B, NonEmptyChain[A]] = list.groupByNec(f)
}

def testSequenceFilter[A, B]: Unit = {
val f = mock[List[Either[A, Option[B]]]]

val result: Either[A, List[B]] = f.sequenceFilter
}
}

0 comments on commit 903617a

Please sign in to comment.