Skip to content

Commit

Permalink
Enable SI-2712 fix in cats / Remove unapply machinery (#1583)
Browse files Browse the repository at this point in the history
* standardized to partial unification as SI-2712 fix

* Update functor.md

* addressed misc feedback

* removed the incorrect doc

* Update faq.md
  • Loading branch information
kailuowang authored Apr 21, 2017
1 parent 669a023 commit 01711b0
Show file tree
Hide file tree
Showing 35 changed files with 84 additions and 293 deletions.
45 changes: 0 additions & 45 deletions core/src/main/scala/cats/Foldable.scala
Original file line number Diff line number Diff line change
Expand Up @@ -231,30 +231,6 @@ import simulacrum.typeclass
G.map2Eval(f(a), acc) { (_, _) => () }
}.value

/**
* Behaves like traverse_, but uses [[Unapply]] to find the
* [[Applicative]] instance for `G` - used when `G` is a
* type constructor with two or more parameters such as [[scala.util.Either]]
*
* {{{
* scala> import cats.implicits._
* scala> def parseInt(s: String): Either[String, Int] =
* | try { Right(s.toInt) }
* | catch { case _: NumberFormatException => Left("boo") }
* scala> val F = Foldable[List]
* scala> F.traverseU_(List("333", "444"))(parseInt)
* res0: Either[String, Unit] = Right(())
* scala> F.traverseU_(List("333", "zzz"))(parseInt)
* res1: Either[String, Unit] = Left(boo)
* }}}
*
* Note that using `traverse_` instead of `traverseU_` would not compile without
* explicitly passing in the type parameters - the type checker has trouble
* inferring the appropriate instance.
*/
def traverseU_[A, GB](fa: F[A])(f: A => GB)(implicit U: Unapply[Applicative, GB]): U.M[Unit] =
traverse_(fa)(f.andThen(U.subst))(U.TC)

/**
* Sequence `F[G[A]]` using `Applicative[G]`.
*
Expand All @@ -275,27 +251,6 @@ import simulacrum.typeclass
def sequence_[G[_]: Applicative, A](fga: F[G[A]]): G[Unit] =
traverse_(fga)(identity)

/**
* Behaves like sequence_, but uses [[Unapply]] to find the
* [[Applicative]] instance for `G` - used when `G` is a
* type constructor with two or more parameters such as [[scala.util.Either]]
*
* {{{
* scala> import cats.implicits._
* scala> val F = Foldable[List]
* scala> F.sequenceU_(List(Either.right[String, Int](333), Right(444)))
* res0: Either[String, Unit] = Right(())
* scala> F.sequenceU_(List(Either.right[String, Int](333), Left("boo")))
* res1: Either[String, Unit] = Left(boo)
* }}}
*
* Note that using `sequence_` instead of `sequenceU_` would not compile without
* explicitly passing in the type parameters - the type checker has trouble
* inferring the appropriate instance.
*/
def sequenceU_[GA](fa: F[GA])(implicit U: Unapply[Applicative, GA]): U.M[Unit] =
traverseU_(fa)(identity)

/**
* Fold implemented using the given `MonoidK[G]` instance.
*
Expand Down
36 changes: 0 additions & 36 deletions core/src/main/scala/cats/Traverse.scala
Original file line number Diff line number Diff line change
Expand Up @@ -32,24 +32,6 @@ import simulacrum.typeclass
*/
def traverse[G[_]: Applicative, A, B](fa: F[A])(f: A => G[B]): G[F[B]]

/**
* Behaves just like traverse, but uses [[Unapply]] to find the
* Applicative instance for G.
*
* Example:
* {{{
* scala> import cats.implicits._
* scala> def parseInt(s: String): Either[String, Int] = Either.catchOnly[NumberFormatException](s.toInt).leftMap(_ => "no number")
* scala> val ns = List("1", "2", "3")
* scala> ns.traverseU(parseInt)
* res0: Either[String, List[Int]] = Right(List(1, 2, 3))
* scala> ns.traverse[Either[String, ?], Int](parseInt)
* res1: Either[String, List[Int]] = Right(List(1, 2, 3))
* }}}
*/
def traverseU[A, GB](fa: F[A])(f: A => GB)(implicit U: Unapply[Applicative, GB]): U.M[F[U.A]] =
U.TC.traverse(fa)(a => U.subst(f(a)))(this)

/**
* A traverse followed by flattening the inner result.
*
Expand Down Expand Up @@ -101,24 +83,6 @@ import simulacrum.typeclass
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.
*
* Example:
* {{{
* scala> import cats.data.{Validated, ValidatedNel}
* scala> import cats.implicits._
* scala> val x: List[ValidatedNel[String, Int]] = List(Validated.valid(1), Validated.invalid("a"), Validated.invalid("b")).map(_.toValidatedNel)
* scala> x.sequenceU
* res0: cats.data.ValidatedNel[String,List[Int]] = Invalid(NonEmptyList(a, b))
* scala> x.sequence[ValidatedNel[String, ?], Int]
* res1: cats.data.ValidatedNel[String,List[Int]] = Invalid(NonEmptyList(a, b))
* }}}
*/
def sequenceU[GA](fga: F[GA])(implicit U: Unapply[Applicative, GA]): U.M[F[U.A]] =
traverse(fga)(U.subst)(U.TC)

def compose[G[_]: Traverse]: Traverse[λ[α => F[G[α]]]] =
new ComposedTraverse[F, G] {
val F = self
Expand Down
14 changes: 14 additions & 0 deletions core/src/main/scala/cats/data/Const.scala
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,20 @@ final case class Const[A, B](getConst: A) {
object Const extends ConstInstances {
def empty[A, B](implicit A: Monoid[A]): Const[A, B] =
Const(A.empty)

final class OfPartiallyApplied[B] {
def apply[A](a: A): Const[A, B] = Const(a)
}

/**
* Convenient syntax for creating a Const[A, B] from an `A`
* {{{
* scala> import cats.data._
* scala> Const.of[Int]("a")
* res0: Const[String, Int] = Const(a)
* }}}
*/
def of[B]: OfPartiallyApplied[B] = new OfPartiallyApplied
}

private[data] sealed abstract class ConstInstances extends ConstInstances0 {
Expand Down
6 changes: 1 addition & 5 deletions core/src/main/scala/cats/data/EitherT.scala
Original file line number Diff line number Diff line change
Expand Up @@ -195,17 +195,13 @@ final case class EitherT[F[_], A, B](value: F[Either[A, B]]) {
* | EitherT(List(Either.right(_.toString), Either.left("error")))
* scala> val fa: EitherT[List, String, Int] =
* | EitherT(List(Either.right(1), Either.right(2)))
* scala> type ErrorOr[A] = Either[String, A]
* scala> type ListErrorOr[A] = Nested[List, ErrorOr, A]
* scala> type ListErrorOr[A] = Nested[List, Either[String, ?], A]
* scala> ff.ap(fa)
* res0: EitherT[List,String,String] = EitherT(List(Right(1), Right(2), Left(error)))
* scala> EitherT((ff.toNested: ListErrorOr[Int => String]).ap(fa.toNested: ListErrorOr[Int]).value)
* res1: EitherT[List,String,String] = EitherT(List(Right(1), Right(2), Left(error), Left(error)))
* }}}
*
* Note that we need the `ErrorOr` type alias above because otherwise we can't use the
* syntax function `ap` on `Nested[List, Either[A, ?], B]`. This won't be needed after cats has
* decided [[https://github.com/typelevel/cats/issues/1073 how to handle the SI-2712 fix]].
*/
def toNested: Nested[F, Either[A, ?], B] = Nested[F, Either[A, ?], B](value)

Expand Down
3 changes: 0 additions & 3 deletions core/src/main/scala/cats/data/Func.scala
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,6 @@ object Func extends FuncInstances {
def run: A => F[B] = run0
}

/** applicative function using [[Unapply]]. */
def appFuncU[A, R](f: A => R)(implicit RR: Unapply[Applicative, R]): AppFunc[RR.M, A, RR.A] =
appFunc({ a: A => RR.subst(f(a)) })(RR.TC)
}

private[data] abstract class FuncInstances extends FuncInstances0 {
Expand Down
12 changes: 2 additions & 10 deletions core/src/main/scala/cats/syntax/apply.scala
Original file line number Diff line number Diff line change
@@ -1,16 +1,8 @@
package cats
package syntax

private[syntax] trait ApplySyntax1 {
implicit final def catsSyntaxUApply[FA](fa: FA)(implicit U: Unapply[Apply, FA]): Apply.Ops[U.M, U.A] =
new Apply.Ops[U.M, U.A] {
val self = U.subst(fa)
val typeClassInstance = U.TC
}
}

trait ApplySyntax extends ApplySyntax1 {
implicit def catsSyntaxApply[F[_], A](fa: F[A])(implicit F: Apply[F]): Apply.Ops[F, A] =
trait ApplySyntax {
implicit final def catsSyntaxApply[F[_], A](fa: F[A])(implicit F: Apply[F]): Apply.Ops[F, A] =
new Apply.Ops[F, A] {
val self = fa
val typeClassInstance = F
Expand Down
10 changes: 1 addition & 9 deletions core/src/main/scala/cats/syntax/cartesian.scala
Original file line number Diff line number Diff line change
@@ -1,15 +1,7 @@
package cats
package syntax

private[syntax] trait CartesianSyntax1 {
implicit final def catsSyntaxUCartesian[FA](fa: FA)(implicit U: Unapply[Cartesian, FA]): CartesianOps[U.M, U.A] =
new CartesianOps[U.M, U.A] {
val self = U.subst(fa)
val typeClassInstance = U.TC
}
}

trait CartesianSyntax extends CartesianSyntax1 {
trait CartesianSyntax {
implicit final def catsSyntaxCartesian[F[_], A](fa: F[A])(implicit F: Cartesian[F]): CartesianOps[F, A] =
new CartesianOps[F, A] {
val self = fa
Expand Down
9 changes: 1 addition & 8 deletions core/src/main/scala/cats/syntax/coflatMap.scala
Original file line number Diff line number Diff line change
@@ -1,11 +1,4 @@
package cats
package syntax

private[syntax] trait CoflatMapSyntax1 {
implicit final def catsSyntaxUCoflatMap[FA](fa: FA)(implicit U: Unapply[CoflatMap, FA]): CoflatMap.Ops[U.M, U.A] = new CoflatMap.Ops[U.M, U.A] {
val self = U.subst(fa)
val typeClassInstance = U.TC
}
}

trait CoflatMapSyntax extends CoflatMap.ToCoflatMapOps with CoflatMapSyntax1
trait CoflatMapSyntax extends CoflatMap.ToCoflatMapOps
9 changes: 1 addition & 8 deletions core/src/main/scala/cats/syntax/comonad.scala
Original file line number Diff line number Diff line change
@@ -1,12 +1,5 @@
package cats
package syntax

private[syntax] trait ComonadSyntax1 {
implicit final def catsSyntaxUComonad[FA](fa: FA)(implicit U: Unapply[Comonad, FA]): Comonad.Ops[U.M, U.A] =
new Comonad.Ops[U.M, U.A] {
val self = U.subst(fa)
val typeClassInstance = U.TC
}
}
trait ComonadSyntax extends Comonad.ToComonadOps

trait ComonadSyntax extends Comonad.ToComonadOps with ComonadSyntax1
10 changes: 1 addition & 9 deletions core/src/main/scala/cats/syntax/contravariant.scala
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,5 @@ package syntax

import cats.functor.Contravariant

private[syntax] trait ContravariantSyntax1 {
implicit final def catsSyntaxUContravariant[FA](fa: FA)(implicit U: Unapply[Contravariant, FA]): Contravariant.Ops[U.M, U.A] =
new Contravariant.Ops[U.M, U.A] {
val self = U.subst(fa)
val typeClassInstance = U.TC
}
}

trait ContravariantSyntax extends Contravariant.ToContravariantOps with ContravariantSyntax1
trait ContravariantSyntax extends Contravariant.ToContravariantOps

10 changes: 1 addition & 9 deletions core/src/main/scala/cats/syntax/flatMap.scala
Original file line number Diff line number Diff line change
@@ -1,15 +1,7 @@
package cats
package syntax

private[syntax] trait FlatMapSyntax1 {
implicit final def catsSyntaxUFlatMap[FA](fa: FA)(implicit U: Unapply[FlatMap, FA]): FlatMap.Ops[U.M, U.A] =
new FlatMap.Ops[U.M, U.A]{
val self = U.subst(fa)
val typeClassInstance = U.TC
}
}

trait FlatMapSyntax extends FlatMap.ToFlatMapOps with FlatMapSyntax1 {
trait FlatMapSyntax extends FlatMap.ToFlatMapOps {

implicit final def catsSyntaxFlatten[F[_]: FlatMap, A](ffa: F[F[A]]): FlattenOps[F, A] =
new FlattenOps[F, A](ffa)
Expand Down
10 changes: 1 addition & 9 deletions core/src/main/scala/cats/syntax/foldable.scala
Original file line number Diff line number Diff line change
@@ -1,15 +1,7 @@
package cats
package syntax

private[syntax] trait FoldableSyntax1 {
implicit final def catsSyntaxUFoldable[FA](fa: FA)(implicit U: Unapply[Foldable, FA]): Foldable.Ops[U.M, U.A] =
new Foldable.Ops[U.M, U.A] {
val self = U.subst(fa)
val typeClassInstance = U.TC
}
}

trait FoldableSyntax extends Foldable.ToFoldableOps with FoldableSyntax1 {
trait FoldableSyntax extends Foldable.ToFoldableOps {
implicit final def catsSyntaxNestedFoldable[F[_]: Foldable, G[_], A](fga: F[G[A]]): NestedFoldableOps[F, G, A] =
new NestedFoldableOps[F, G, A](fga)
}
Expand Down
9 changes: 1 addition & 8 deletions core/src/main/scala/cats/syntax/functor.scala
Original file line number Diff line number Diff line change
@@ -1,12 +1,5 @@
package cats
package syntax

private[syntax] trait FunctorSyntax1 {
implicit final def catsSyntaxUFunctor[FA](fa: FA)(implicit U: Unapply[Functor, FA]): Functor.Ops[U.M, U.A] =
new Functor.Ops[U.M, U.A]{
val self = U.subst(fa)
val typeClassInstance = U.TC
}
}
trait FunctorSyntax extends Functor.ToFunctorOps

trait FunctorSyntax extends Functor.ToFunctorOps with FunctorSyntax1
10 changes: 1 addition & 9 deletions core/src/main/scala/cats/syntax/functorFilter.scala
Original file line number Diff line number Diff line change
@@ -1,12 +1,4 @@
package cats
package syntax

private[syntax] trait FunctorFilterSyntax1 {
implicit final def catsSyntaxUFunctorFilter[FA](fa: FA)(implicit U: Unapply[FunctorFilter, FA]): FunctorFilter.Ops[U.M, U.A] =
new FunctorFilter.Ops[U.M, U.A]{
val self = U.subst(fa)
val typeClassInstance = U.TC
}
}

trait FunctorFilterSyntax extends FunctorFilter.ToFunctorFilterOps with FunctorFilterSyntax1
trait FunctorFilterSyntax extends FunctorFilter.ToFunctorFilterOps
10 changes: 1 addition & 9 deletions core/src/main/scala/cats/syntax/invariant.scala
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,4 @@ package syntax

import cats.functor.Invariant

private[syntax] trait InvariantSyntax1 {
implicit final def catsSyntaxUInvariant[FA](fa: FA)(implicit U: Unapply[Invariant, FA]): Invariant.Ops[U.M, U.A] =
new Invariant.Ops[U.M, U.A] {
val self = U.subst(fa)
val typeClassInstance = U.TC
}
}

trait InvariantSyntax extends Invariant.ToInvariantOps with InvariantSyntax1
trait InvariantSyntax extends Invariant.ToInvariantOps
9 changes: 1 addition & 8 deletions core/src/main/scala/cats/syntax/monadFilter.scala
Original file line number Diff line number Diff line change
@@ -1,12 +1,5 @@
package cats
package syntax

private[syntax] trait MonadFilterSyntax1 {
implicit final def catsSyntaxUMonadFilter[FA](fa: FA)(implicit U: Unapply[MonadFilter, FA]): MonadFilter.Ops[U.M, U.A] =
new MonadFilter.Ops[U.M, U.A] {
val self = U.subst(fa)
val typeClassInstance = U.TC
}
}
trait MonadFilterSyntax extends MonadFilter.ToMonadFilterOps

trait MonadFilterSyntax extends MonadFilter.ToMonadFilterOps with MonadFilterSyntax1
10 changes: 1 addition & 9 deletions core/src/main/scala/cats/syntax/reducible.scala
Original file line number Diff line number Diff line change
@@ -1,15 +1,7 @@
package cats
package syntax

private[syntax] trait ReducibleSyntax1 {
implicit final def catsSyntaxUReducible[FA](fa: FA)(implicit U: Unapply[Reducible, FA]): Reducible.Ops[U.M, U.A] =
new Reducible.Ops[U.M, U.A] {
val self = U.subst(fa)
val typeClassInstance = U.TC
}
}

trait ReducibleSyntax extends Reducible.ToReducibleOps with ReducibleSyntax1 {
trait ReducibleSyntax extends Reducible.ToReducibleOps {
implicit final def catsSyntaxNestedReducible[F[_]: Reducible, G[_], A](fga: F[G[A]]): NestedReducibleOps[F, G, A] =
new NestedReducibleOps[F, G, A](fga)
}
Expand Down
11 changes: 1 addition & 10 deletions core/src/main/scala/cats/syntax/semigroupk.scala
Original file line number Diff line number Diff line change
@@ -1,13 +1,4 @@
package cats
package syntax

private[syntax] trait SemigroupKSyntax1 {
// TODO: use simulacrum instances eventually
implicit final def catsSyntaxUSemigroup[FA](fa: FA)(implicit U: Unapply[SemigroupK, FA]): SemigroupK.Ops[U.M, U.A] =
new SemigroupK.Ops[U.M, U.A] {
val self = U.subst(fa)
val typeClassInstance = U.TC
}
}

trait SemigroupKSyntax extends SemigroupK.ToSemigroupKOps with SemigroupKSyntax1
trait SemigroupKSyntax extends SemigroupK.ToSemigroupKOps
3 changes: 1 addition & 2 deletions core/src/main/scala/cats/syntax/transLift.scala
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,7 @@ package cats
package syntax

trait TransLiftSyntax {
implicit final def catsSyntaxTransLift[E](ma: E)(implicit U: Unapply[Trivial.PH1, E]): TransLiftOps[U.M, U.A] =
new TransLiftOps(U.subst(ma))
implicit final def catsSyntaxTransLift[M0[_], A](ma: M0[A]): TransLiftOps[M0, A] = new TransLiftOps(ma)
}

final class TransLiftOps[M0[_], A](val ma: M0[A]) extends AnyVal {
Expand Down
10 changes: 1 addition & 9 deletions core/src/main/scala/cats/syntax/traverse.scala
Original file line number Diff line number Diff line change
@@ -1,12 +1,4 @@
package cats
package syntax

private[syntax] trait TraverseSyntax1 {
implicit final def catsSyntaxUTraverse[FA](fa: FA)(implicit U: Unapply[Traverse, FA]): Traverse.Ops[U.M, U.A] =
new Traverse.Ops[U.M, U.A]{
val self = U.subst(fa)
val typeClassInstance = U.TC
}
}

trait TraverseSyntax extends Traverse.ToTraverseOps with TraverseSyntax1
trait TraverseSyntax extends Traverse.ToTraverseOps
10 changes: 1 addition & 9 deletions core/src/main/scala/cats/syntax/traverseFilter.scala
Original file line number Diff line number Diff line change
@@ -1,12 +1,4 @@
package cats
package syntax

trait TraverseFilterSyntax extends TraverseFilter.ToTraverseFilterOps with TraverseFilterSyntax1

private[syntax] trait TraverseFilterSyntax1 {
implicit final def catsSyntaxUTraverseFilter[FA](fa: FA)(implicit U: Unapply[TraverseFilter, FA]): TraverseFilter.Ops[U.M, U.A] =
new TraverseFilter.Ops[U.M, U.A]{
val self = U.subst(fa)
val typeClassInstance = U.TC
}
}
trait TraverseFilterSyntax extends TraverseFilter.ToTraverseFilterOps
Loading

0 comments on commit 01711b0

Please sign in to comment.