From a644aaf89ff4a163e33d05060176369583a3dedf Mon Sep 17 00:00:00 2001 From: Yilin Wei Date: Thu, 11 May 2017 11:17:45 +0100 Subject: [PATCH] move instances into separate trait --- core/src/main/scala/cats/Cartesian.scala | 12 +---- .../scala/cats/ContravariantCartesian.scala | 10 ---- .../main/scala/cats/InvariantMonoidal.scala | 46 ------------------- .../scala/cats/functor/Contravariant.scala | 29 ------------ .../main/scala/cats/functor/Invariant.scala | 11 ----- core/src/main/scala/cats/instances/all.scala | 5 ++ core/src/main/scala/cats/instances/eq.scala | 10 ++++ .../main/scala/cats/instances/monoid.scala | 26 +++++++++++ .../src/main/scala/cats/instances/order.scala | 16 +++++++ .../scala/cats/instances/partialOrder.scala | 15 ++++++ .../main/scala/cats/instances/semigroup.scala | 24 ++++++++++ .../cats/laws/discipline/FlatMapTests.scala | 2 + 12 files changed, 99 insertions(+), 107 deletions(-) create mode 100644 core/src/main/scala/cats/instances/eq.scala create mode 100644 core/src/main/scala/cats/instances/monoid.scala create mode 100644 core/src/main/scala/cats/instances/order.scala create mode 100644 core/src/main/scala/cats/instances/partialOrder.scala create mode 100644 core/src/main/scala/cats/instances/semigroup.scala diff --git a/core/src/main/scala/cats/Cartesian.scala b/core/src/main/scala/cats/Cartesian.scala index a8cdb7f0af..a3543d009a 100644 --- a/core/src/main/scala/cats/Cartesian.scala +++ b/core/src/main/scala/cats/Cartesian.scala @@ -16,14 +16,4 @@ import simulacrum.typeclass def product[A, B](fa: F[A], fb: F[B]): F[(A, B)] } -object Cartesian extends CartesianArityFunctions with KernelCartesianInstances - -/** - * Cartesian instances for types that are housed in Kernel and therefore - * can't have instances for Cats type classes in their companion objects. - */ -private[cats] sealed trait KernelCartesianInstances { - implicit val catsInvariantSemigroup: Cartesian[Semigroup] = InvariantMonoidal.catsInvariantMonoidalSemigroup - implicit val catsInvariantMonoid: Cartesian[Monoid] = InvariantMonoidal.catsInvariantMonoidalMonoid - implicit val catsCartesianEq: Cartesian[Eq] = ContravariantCartesian.catsContravariantCartesianEq -} +object Cartesian extends CartesianArityFunctions diff --git a/core/src/main/scala/cats/ContravariantCartesian.scala b/core/src/main/scala/cats/ContravariantCartesian.scala index eee7b65866..6842150640 100644 --- a/core/src/main/scala/cats/ContravariantCartesian.scala +++ b/core/src/main/scala/cats/ContravariantCartesian.scala @@ -14,13 +14,3 @@ import simulacrum.typeclass def G = Functor[G] } } - -object ContravariantCartesian extends KernelContravariantCartesianInstances - -private[cats] sealed trait KernelContravariantCartesianInstances { - implicit val catsContravariantCartesianEq: ContravariantCartesian[Eq] = new ContravariantCartesian[Eq] { - def contramap[A, B](fa: Eq[A])(fn: B => A): Eq[B] = fa.on(fn) - def product[A, B](fa: Eq[A], fb: Eq[B]): Eq[(A, B)] = - Eq.instance { (left, right) => fa.eqv(left._1, right._1) && fb.eqv(left._2, right._2) } - } -} diff --git a/core/src/main/scala/cats/InvariantMonoidal.scala b/core/src/main/scala/cats/InvariantMonoidal.scala index fca19d871c..445a58e342 100644 --- a/core/src/main/scala/cats/InvariantMonoidal.scala +++ b/core/src/main/scala/cats/InvariantMonoidal.scala @@ -11,49 +11,3 @@ import simulacrum.typeclass @typeclass trait InvariantMonoidal[F[_]] extends Invariant[F] with Cartesian[F] { def pure[A](a: A): F[A] } - -object InvariantMonoidal extends KernelInvariantMonoidalInstances - -/** - * InvariantMonoidal instances for types that are housed in cats.kernel and therefore - * can't have instances for this type class in their companion objects. - */ -private[cats] trait KernelInvariantMonoidalInstances { - implicit val catsInvariantMonoidalSemigroup: InvariantMonoidal[Semigroup] = new InvariantMonoidal[Semigroup] { - def product[A, B](fa: Semigroup[A], fb: Semigroup[B]): Semigroup[(A, B)] = new Semigroup[(A, B)] { - def combine(x: (A, B), y: (A, B)): (A, B) = fa.combine(x._1, y._1) -> fb.combine(x._2, y._2) - } - - def imap[A, B](fa: Semigroup[A])(f: A => B)(g: B => A): Semigroup[B] = new Semigroup[B] { - def combine(x: B, y: B): B = f(fa.combine(g(x), g(y))) - override def combineAllOption(bs: TraversableOnce[B]): Option[B] = - fa.combineAllOption(bs.map(g)).map(f) - } - - def pure[A](a: A): Semigroup[A] = new Semigroup[A] { - def combine(x: A, y: A): A = a - override def combineAllOption(as: TraversableOnce[A]): Option[A] = - if (as.isEmpty) None else Some(a) - } - } - - implicit val catsInvariantMonoidalMonoid: InvariantMonoidal[Monoid] = new InvariantMonoidal[Monoid] { - def product[A, B](fa: Monoid[A], fb: Monoid[B]): Monoid[(A, B)] = new Monoid[(A, B)] { - val empty = fa.empty -> fb.empty - def combine(x: (A, B), y: (A, B)): (A, B) = fa.combine(x._1, y._1) -> fb.combine(x._2, y._2) - } - - def imap[A, B](fa: Monoid[A])(f: A => B)(g: B => A): Monoid[B] = new Monoid[B] { - val empty = f(fa.empty) - def combine(x: B, y: B): B = f(fa.combine(g(x), g(y))) - override def combineAll(bs: TraversableOnce[B]): B = - f(fa.combineAll(bs.map(g))) - } - - def pure[A](a: A): Monoid[A] = new Monoid[A] { - val empty = a - def combine(x: A, y: A): A = a - override def combineAll(as: TraversableOnce[A]): A = a - } - } -} diff --git a/core/src/main/scala/cats/functor/Contravariant.scala b/core/src/main/scala/cats/functor/Contravariant.scala index 3f8cf6860f..d71af9ab24 100644 --- a/core/src/main/scala/cats/functor/Contravariant.scala +++ b/core/src/main/scala/cats/functor/Contravariant.scala @@ -28,32 +28,3 @@ import simulacrum.typeclass val G = Functor[G] } } - -object Contravariant extends KernelContravariantInstances - -/** - * Convariant instances for types that are housed in cats.kernel and therefore - * can't have instances for this type class in their companion objects. - */ -private[functor] sealed trait KernelContravariantInstances { - implicit def catsFunctorContravariantForEq: Contravariant[Eq] = - ContravariantCartesian.catsContravariantCartesianEq - - implicit val catsFunctorContravariantForPartialOrder: Contravariant[PartialOrder] = - new Contravariant[PartialOrder] { - /** Derive a `PartialOrder` for `B` given a `PartialOrder[A]` and a function `B => A`. - * - * Note: resulting instances are law-abiding only when the functions used are injective (represent a one-to-one mapping) - */ - def contramap[A, B](fa: PartialOrder[A])(f: B => A): PartialOrder[B] = fa.on(f) - } - - implicit val catsFunctorContravariantForOrder: Contravariant[Order] = - new Contravariant[Order] { - /** Derive an `Order` for `B` given an `Order[A]` and a function `B => A`. - * - * Note: resulting instances are law-abiding only when the functions used are injective (represent a one-to-one mapping) - */ - def contramap[A, B](fa: Order[A])(f: B => A): Order[B] = fa.on(f) - } -} diff --git a/core/src/main/scala/cats/functor/Invariant.scala b/core/src/main/scala/cats/functor/Invariant.scala index 20b361b2f1..d748b4a25a 100644 --- a/core/src/main/scala/cats/functor/Invariant.scala +++ b/core/src/main/scala/cats/functor/Invariant.scala @@ -27,14 +27,3 @@ import simulacrum.typeclass val G = Contravariant[G] } } - -object Invariant extends KernelInvariantInstances - -/** - * Invariant instances for types that are housed in cats.kernel and therefore - * can't have instances for this type class in their companion objects. - */ -private[functor] sealed trait KernelInvariantInstances { - implicit val catsFunctorInvariantForSemigroup: Invariant[Semigroup] = InvariantMonoidal.catsInvariantMonoidalSemigroup - implicit val catsFunctorInvariantForMonoid: Invariant[Monoid] = InvariantMonoidal.catsInvariantMonoidalMonoid -} diff --git a/core/src/main/scala/cats/instances/all.scala b/core/src/main/scala/cats/instances/all.scala index 586d5f287d..9a52de3f6c 100644 --- a/core/src/main/scala/cats/instances/all.scala +++ b/core/src/main/scala/cats/instances/all.scala @@ -5,8 +5,13 @@ trait AllInstances extends FunctionInstances with StringInstances with EitherInstances + with EqInstances with ListInstances with OptionInstances + with OrderInstances + with MonoidInstances + with PartialOrderInstances + with SemigroupInstances with SetInstances with StreamInstances with VectorInstances diff --git a/core/src/main/scala/cats/instances/eq.scala b/core/src/main/scala/cats/instances/eq.scala new file mode 100644 index 0000000000..aab0f91579 --- /dev/null +++ b/core/src/main/scala/cats/instances/eq.scala @@ -0,0 +1,10 @@ +package cats +package instances + +trait EqInstances { + implicit val catsContravariantCartesianEq: ContravariantCartesian[Eq] = new ContravariantCartesian[Eq] { + def contramap[A, B](fa: Eq[A])(fn: B => A): Eq[B] = fa.on(fn) + def product[A, B](fa: Eq[A], fb: Eq[B]): Eq[(A, B)] = + Eq.instance { (left, right) => fa.eqv(left._1, right._1) && fb.eqv(left._2, right._2) } + } +} diff --git a/core/src/main/scala/cats/instances/monoid.scala b/core/src/main/scala/cats/instances/monoid.scala new file mode 100644 index 0000000000..3679a52084 --- /dev/null +++ b/core/src/main/scala/cats/instances/monoid.scala @@ -0,0 +1,26 @@ +package cats +package instances + +trait MonoidInstances { + + implicit val catsInvariantMonoidalMonoid: InvariantMonoidal[Monoid] = new InvariantMonoidal[Monoid] { + def product[A, B](fa: Monoid[A], fb: Monoid[B]): Monoid[(A, B)] = new Monoid[(A, B)] { + val empty = fa.empty -> fb.empty + def combine(x: (A, B), y: (A, B)): (A, B) = fa.combine(x._1, y._1) -> fb.combine(x._2, y._2) + } + + def imap[A, B](fa: Monoid[A])(f: A => B)(g: B => A): Monoid[B] = new Monoid[B] { + val empty = f(fa.empty) + def combine(x: B, y: B): B = f(fa.combine(g(x), g(y))) + override def combineAll(bs: TraversableOnce[B]): B = + f(fa.combineAll(bs.map(g))) + } + + def pure[A](a: A): Monoid[A] = new Monoid[A] { + val empty = a + def combine(x: A, y: A): A = a + override def combineAll(as: TraversableOnce[A]): A = a + } + } + +} diff --git a/core/src/main/scala/cats/instances/order.scala b/core/src/main/scala/cats/instances/order.scala new file mode 100644 index 0000000000..ac05fd87bc --- /dev/null +++ b/core/src/main/scala/cats/instances/order.scala @@ -0,0 +1,16 @@ +package cats +package instances + +import cats.functor.Contravariant + +trait OrderInstances { + + implicit val catsFunctorContravariantForOrder: Contravariant[Order] = + new Contravariant[Order] { + /** Derive an `Order` for `B` given an `Order[A]` and a function `B => A`. + * + * Note: resulting instances are law-abiding only when the functions used are injective (represent a one-to-one mapping) + */ + def contramap[A, B](fa: Order[A])(f: B => A): Order[B] = fa.on(f) + } +} diff --git a/core/src/main/scala/cats/instances/partialOrder.scala b/core/src/main/scala/cats/instances/partialOrder.scala new file mode 100644 index 0000000000..37e6db2146 --- /dev/null +++ b/core/src/main/scala/cats/instances/partialOrder.scala @@ -0,0 +1,15 @@ +package cats +package instances + +import cats.functor.Contravariant + +trait PartialOrderInstances { + implicit val catsFunctorContravariantForPartialOrder: Contravariant[PartialOrder] = + new Contravariant[PartialOrder] { + /** Derive a `PartialOrder` for `B` given a `PartialOrder[A]` and a function `B => A`. + * + * Note: resulting instances are law-abiding only when the functions used are injective (represent a one-to-one mapping) + */ + def contramap[A, B](fa: PartialOrder[A])(f: B => A): PartialOrder[B] = fa.on(f) + } +} diff --git a/core/src/main/scala/cats/instances/semigroup.scala b/core/src/main/scala/cats/instances/semigroup.scala new file mode 100644 index 0000000000..4d50d5d4d8 --- /dev/null +++ b/core/src/main/scala/cats/instances/semigroup.scala @@ -0,0 +1,24 @@ +package cats +package instances + +trait SemigroupInstances { + + implicit val catsInvariantMonoidalSemigroup: InvariantMonoidal[Semigroup] = new InvariantMonoidal[Semigroup] { + def product[A, B](fa: Semigroup[A], fb: Semigroup[B]): Semigroup[(A, B)] = new Semigroup[(A, B)] { + def combine(x: (A, B), y: (A, B)): (A, B) = fa.combine(x._1, y._1) -> fb.combine(x._2, y._2) + } + + def imap[A, B](fa: Semigroup[A])(f: A => B)(g: B => A): Semigroup[B] = new Semigroup[B] { + def combine(x: B, y: B): B = f(fa.combine(g(x), g(y))) + override def combineAllOption(bs: TraversableOnce[B]): Option[B] = + fa.combineAllOption(bs.map(g)).map(f) + } + + def pure[A](a: A): Semigroup[A] = new Semigroup[A] { + def combine(x: A, y: A): A = a + override def combineAllOption(as: TraversableOnce[A]): Option[A] = + if (as.isEmpty) None else Some(a) + } + } + +} diff --git a/laws/src/main/scala/cats/laws/discipline/FlatMapTests.scala b/laws/src/main/scala/cats/laws/discipline/FlatMapTests.scala index 10c72fd33e..ec88abdb4a 100644 --- a/laws/src/main/scala/cats/laws/discipline/FlatMapTests.scala +++ b/laws/src/main/scala/cats/laws/discipline/FlatMapTests.scala @@ -2,6 +2,8 @@ package cats package laws package discipline +import cats.instances.all._ + import cats.laws.discipline.CartesianTests.Isomorphisms import org.scalacheck.{Arbitrary, Cogen, Prop} import Prop._