diff --git a/core/src/main/scala-2.12/cats/ScalaVersionSpecificInstances.scala b/core/src/main/scala-2.12/cats/ScalaVersionSpecificInstances.scala new file mode 100644 index 0000000000..26acd54a2b --- /dev/null +++ b/core/src/main/scala-2.12/cats/ScalaVersionSpecificInstances.scala @@ -0,0 +1,36 @@ +package cats + +import cats.data.ZipStream + +private[cats] trait ScalaVersionSpecificTraverseInstances { + implicit def catsTraverseForStream: Traverse[Stream] = cats.instances.stream.catsStdInstancesForStream +} + +private[cats] trait ScalaVersionSpecificShowInstances { + implicit def catsShowForStream[A: Show]: Show[Stream[A]] = cats.instances.stream.catsStdShowForStream[A] +} + +private[cats] trait ScalaVersionSpecificSemigroupalInstances { + implicit def catsSemigroupalForStream: Semigroupal[Stream] = cats.instances.stream.catsStdInstancesForStream +} + +private[cats] trait ScalaVersionSpecificMonoidKInstances { + implicit def catsMonoidKForStream: MonoidK[Stream] = cats.instances.stream.catsStdInstancesForStream +} + +private[cats] trait ScalaVersionSpecificParallelInstances { + implicit def catsStdParallelForZipStream: Parallel.Aux[Stream, ZipStream] = + cats.instances.stream.catsStdParallelForStreamZipStream +} + +private[cats] trait ScalaVersionSpecificInvariantInstances { + implicit def catsInstancesForStream: Monad[Stream] with Alternative[Stream] with CoflatMap[Stream] = + cats.instances.stream.catsStdInstancesForStream +} + +private[cats] trait ScalaVersionSpecificTraverseFilterInstances { + implicit def catsTraverseFilterForStream: TraverseFilter[Stream] = + cats.instances.stream.catsStdTraverseFilterForStream +} + +private[cats] trait ScalaVersionSpecificAlignInstances diff --git a/core/src/main/scala-2.13+/cats/ScalaVersionSpecificInstances.scala b/core/src/main/scala-2.13+/cats/ScalaVersionSpecificInstances.scala new file mode 100644 index 0000000000..226db7d557 --- /dev/null +++ b/core/src/main/scala-2.13+/cats/ScalaVersionSpecificInstances.scala @@ -0,0 +1,81 @@ +package cats + +import cats.data.{ZipLazyList, ZipStream} +import scala.collection.immutable.ArraySeq + +private[cats] trait ScalaVersionSpecificTraverseInstances { + @deprecated("Use catsTraverseForLazyList", "3.0.0") + implicit def catsTraverseForStream: Traverse[Stream] = cats.instances.stream.catsStdInstancesForStream + + implicit def catsTraverseForLazyList: Traverse[LazyList] = cats.instances.lazyList.catsStdInstancesForLazyList + implicit def catsTraverseForArraySeq: Traverse[ArraySeq] = cats.instances.arraySeq.catsStdInstancesForArraySeq +} + +private[cats] trait ScalaVersionSpecificShowInstances { + @deprecated("Use catsShowForLazyList", "3.0.0") + implicit def catsShowForStream[A: Show]: Show[Stream[A]] = cats.instances.stream.catsStdShowForStream[A] + + implicit def catsShowForLazyList[A: Show]: Show[LazyList[A]] = cats.instances.lazyList.catsStdShowForLazyList[A] + implicit def catsShowForArraySeq[A: Show]: Show[ArraySeq[A]] = cats.instances.arraySeq.catsStdShowForArraySeq[A] +} + +private[cats] trait ScalaVersionSpecificSemigroupalInstances { + @deprecated("Use catsSemigroupalForLazyList", "3.0.0") + implicit def catsSemigroupalForStream: Semigroupal[Stream] = cats.instances.stream.catsStdInstancesForStream + + implicit def catsSemigroupalForLazyList: Semigroupal[LazyList] = cats.instances.lazyList.catsStdInstancesForLazyList + implicit def catsSemigroupalForArraySeq: Semigroupal[ArraySeq] = cats.instances.arraySeq.catsStdInstancesForArraySeq +} + +private[cats] trait ScalaVersionSpecificMonoidKInstances { + @deprecated("Use catsMonoidKForLazyList", "3.0.0") + implicit def catsMonoidKForStream: MonoidK[Stream] = cats.instances.stream.catsStdInstancesForStream + + implicit def catsMonoidKForLazyList: MonoidK[LazyList] = cats.instances.lazyList.catsStdInstancesForLazyList + implicit def catsMonoidKForArraySeq: MonoidK[ArraySeq] = cats.instances.arraySeq.catsStdInstancesForArraySeq +} + +private[cats] trait ScalaVersionSpecificParallelInstances { + @deprecated("Use catsParallelForLazyList", "3.0.0") + implicit def catsStdParallelForZipStream: Parallel.Aux[Stream, ZipStream] = + cats.instances.parallel.catsStdParallelForZipStream + + implicit def catsStdParallelForZipLazyList: Parallel.Aux[LazyList, ZipLazyList] = + cats.instances.lazyList.catsStdParallelForLazyListZipLazyList +} + +private[cats] trait ScalaVersionSpecificInvariantInstances { + @deprecated("Use catsInstancesForLazyList", "3.0.0") + implicit def catsInstancesForStream: Monad[Stream] with Alternative[Stream] with CoflatMap[Stream] = + cats.instances.stream.catsStdInstancesForStream + + implicit def catsInstancesForLazyList: Monad[LazyList] with Alternative[LazyList] with CoflatMap[LazyList] = + cats.instances.lazyList.catsStdInstancesForLazyList + + implicit def catsInstancesForArraySeq: Monad[ArraySeq] with Alternative[ArraySeq] with CoflatMap[ArraySeq] = + cats.instances.arraySeq.catsStdInstancesForArraySeq +} + +private[cats] trait ScalaVersionSpecificTraverseFilterInstances { + @deprecated("Use catsTraverseFilterForLazyList", "3.0.0") + implicit def catsTraverseFilterForStream: TraverseFilter[Stream] = + cats.instances.stream.catsStdTraverseFilterForStream + + implicit def catsTraverseFilterForLazyList: TraverseFilter[LazyList] = + cats.instances.lazyList.catsStdTraverseFilterForLazyList + + implicit def catsTraverseFilterForArraySeq: TraverseFilter[ArraySeq] = + cats.instances.arraySeq.catsStdTraverseFilterForArraySeq +} + +private[cats] trait ScalaVersionSpecificAlignInstances { + @deprecated("Use catsTraverseFilterForLazyList", "3.0.0") + implicit def catsAlignForStream: Align[Stream] = + cats.instances.stream.catsStdInstancesForStream + + implicit def catsAlignForLazyList: Align[LazyList] = + cats.instances.lazyList.catsStdInstancesForLazyList + + implicit def catsAlignForArraySeq: Align[ArraySeq] = + cats.instances.arraySeq.catsStdInstancesForArraySeq +} diff --git a/core/src/main/scala/cats/Align.scala b/core/src/main/scala/cats/Align.scala index 9dececada2..c66a9b9d07 100644 --- a/core/src/main/scala/cats/Align.scala +++ b/core/src/main/scala/cats/Align.scala @@ -3,6 +3,7 @@ package cats import simulacrum.typeclass import cats.data.Ior +import scala.collection.immutable.SortedMap /** * `Align` supports zipping together structures with different shapes, @@ -100,11 +101,19 @@ import cats.data.Ior } } -object Align { +object Align extends ScalaVersionSpecificAlignInstances { def semigroup[F[_], A](implicit F: Align[F], A: Semigroup[A]): Semigroup[F[A]] = new Semigroup[F[A]] { def combine(x: F[A], y: F[A]): F[A] = Align[F].alignCombine(x, y) } + implicit def catsAlignForList: Align[List] = cats.instances.list.catsStdInstancesForList + implicit def catsAlignForOption: Align[Option] = cats.instances.option.catsStdInstancesForOption + implicit def catsAlignForVector: Align[Vector] = cats.instances.vector.catsStdInstancesForVector + implicit def catsAlignForMap[K]: Align[Map[K, *]] = cats.instances.map.catsStdInstancesForMap[K] + implicit def catsAlignForSortedMap[K: Order]: Align[SortedMap[K, *]] = + cats.instances.sortedMap.catsStdInstancesForSortedMap[K] + implicit def catsAlignForEither[A]: Align[Either[A, *]] = cats.instances.either.catsStdInstancesForEither[A] + private[cats] def alignWithIterator[A, B, C](fa: Iterable[A], fb: Iterable[B])(f: Ior[A, B] => C): Iterator[C] = new Iterator[C] { private[this] val iterA = fa.iterator diff --git a/core/src/main/scala/cats/Applicative.scala b/core/src/main/scala/cats/Applicative.scala index 11fb476321..f7712def7d 100644 --- a/core/src/main/scala/cats/Applicative.scala +++ b/core/src/main/scala/cats/Applicative.scala @@ -1,7 +1,6 @@ package cats import cats.arrow.Arrow -import cats.instances.list._ import simulacrum.typeclass /** @@ -206,7 +205,7 @@ object Applicative { * res0: (Long, Int) = (3,6) * }}} */ - implicit def catsApplicativeForArrow[F[_, _], A](implicit F: Arrow[F]): Applicative[F[A, *]] = + def catsApplicativeForArrow[F[_, _], A](implicit F: Arrow[F]): Applicative[F[A, *]] = new ArrowApplicative[F, A](F) /** diff --git a/core/src/main/scala/cats/Bifoldable.scala b/core/src/main/scala/cats/Bifoldable.scala index 4098cbbf27..28615eae94 100644 --- a/core/src/main/scala/cats/Bifoldable.scala +++ b/core/src/main/scala/cats/Bifoldable.scala @@ -32,6 +32,11 @@ import simulacrum.typeclass } } +object Bifoldable { + implicit def catsBitraverseForEither: Bitraverse[Either] = cats.instances.either.catsStdBitraverseForEither + implicit def catsBitraverseForTuple2: Bitraverse[Tuple2] = cats.instances.tuple.catsStdBitraverseForTuple2 +} + private[cats] trait ComposedBifoldable[F[_, _], G[_, _]] extends Bifoldable[λ[(α, β) => F[G[α, β], G[α, β]]]] { implicit def F: Bifoldable[F] implicit def G: Bifoldable[G] diff --git a/core/src/main/scala/cats/Bifunctor.scala b/core/src/main/scala/cats/Bifunctor.scala index 031ab03421..a06ce0ebf5 100644 --- a/core/src/main/scala/cats/Bifunctor.scala +++ b/core/src/main/scala/cats/Bifunctor.scala @@ -55,6 +55,11 @@ import simulacrum.typeclass def leftWiden[A, B, AA >: A](fab: F[A, B]): F[AA, B] = fab.asInstanceOf[F[AA, B]] } +object Bifunctor { + implicit def catsBifunctorForEither: Bifunctor[Either] = cats.instances.either.catsStdBitraverseForEither + implicit def catsBifunctorForTuple2: Bifunctor[Tuple2] = cats.instances.tuple.catsStdBitraverseForTuple2 +} + private[cats] trait ComposedBifunctor[F[_, _], G[_, _]] extends Bifunctor[λ[(A, B) => F[G[A, B], G[A, B]]]] { def F: Bifunctor[F] def G: Bifunctor[G] diff --git a/core/src/main/scala/cats/Defer.scala b/core/src/main/scala/cats/Defer.scala index c24b65b0ec..9cbfee96ef 100644 --- a/core/src/main/scala/cats/Defer.scala +++ b/core/src/main/scala/cats/Defer.scala @@ -1,5 +1,7 @@ package cats +import scala.util.control.TailCalls.TailRec + /** * Defer is a type class that shows the ability to defer creation * inside of the type constructor F[_]. @@ -53,4 +55,8 @@ trait Defer[F[_]] extends Serializable { object Defer { def apply[F[_]](implicit defer: Defer[F]): Defer[F] = defer + + implicit def catsDeferForFunction0: Defer[Function0] = cats.instances.function.catsSddDeferForFunction0 + implicit def catsDeferForFunction1[A]: Defer[Function1[A, *]] = cats.instances.function.catsStdDeferForFunction1[A] + implicit def catsDeferForTailRec: Defer[TailRec] = cats.instances.tailRec.catsInstancesForTailRec } diff --git a/core/src/main/scala/cats/Foldable.scala b/core/src/main/scala/cats/Foldable.scala index 668614a0bd..9e6c56ca71 100644 --- a/core/src/main/scala/cats/Foldable.scala +++ b/core/src/main/scala/cats/Foldable.scala @@ -1,7 +1,6 @@ package cats import scala.collection.mutable -import cats.instances.either._ import cats.kernel.CommutativeMonoid import simulacrum.{noop, typeclass} import Foldable.sentinel @@ -693,8 +692,6 @@ import Foldable.sentinel * }}} */ def partitionEither[A, B, C](fa: F[A])(f: A => Either[B, C])(implicit A: Alternative[F]): (F[B], F[C]) = { - import cats.instances.tuple._ - implicit val mb: Monoid[F[B]] = A.algebra[B] implicit val mc: Monoid[F[C]] = A.algebra[C] diff --git a/core/src/main/scala/cats/FunctorFilter.scala b/core/src/main/scala/cats/FunctorFilter.scala index 7b3b230076..c50a190b22 100644 --- a/core/src/main/scala/cats/FunctorFilter.scala +++ b/core/src/main/scala/cats/FunctorFilter.scala @@ -1,5 +1,6 @@ package cats +import scala.collection.immutable.{Queue, SortedMap} import simulacrum.typeclass /** @@ -74,3 +75,17 @@ trait FunctorFilter[F[_]] extends Serializable { def filterNot[A](fa: F[A])(f: A => Boolean): F[A] = mapFilter(fa)(Some(_).filterNot(f)) } + +object FunctorFilter extends ScalaVersionSpecificTraverseFilterInstances { + implicit def catsTraverseFilterForOption: TraverseFilter[Option] = + cats.instances.option.catsStdTraverseFilterForOption + implicit def catsTraverseFilterForList: TraverseFilter[List] = cats.instances.list.catsStdTraverseFilterForList + implicit def catsTraverseFilterForVector: TraverseFilter[Vector] = + cats.instances.vector.catsStdTraverseFilterForVector + implicit def catsFunctorFilterForMap[K: Order]: FunctorFilter[Map[K, *]] = + cats.instances.map.catsStdFunctorFilterForMap[K] + implicit def catsTraverseFilterForSortedMap[K: Order]: TraverseFilter[SortedMap[K, *]] = + cats.instances.sortedMap.catsStdTraverseFilterForSortedMap[K] + implicit def catsTraverseFilterForQueue: TraverseFilter[Queue] = + cats.instances.queue.catsStdTraverseFilterForQueue +} diff --git a/core/src/main/scala/cats/Invariant.scala b/core/src/main/scala/cats/Invariant.scala index 0c391c1e88..4381b4e8d3 100644 --- a/core/src/main/scala/cats/Invariant.scala +++ b/core/src/main/scala/cats/Invariant.scala @@ -1,8 +1,12 @@ package cats +import cats.arrow.Arrow import cats.kernel._ import simulacrum.typeclass import cats.kernel.compat.scalaVersionSpecific._ +import scala.collection.immutable.{Queue, SortedMap} +import scala.util.Try +import scala.util.control.TailCalls.TailRec /** * Must obey the laws defined in cats.laws.InvariantLaws. @@ -45,7 +49,55 @@ import cats.kernel.compat.scalaVersionSpecific._ } @suppressUnusedImportWarningForScalaVersionSpecific -object Invariant { +object Invariant extends ScalaVersionSpecificInvariantInstances with InvariantInstances0 { + implicit def catsInstancesForId: Distributive[Id] with Comonad[Id] = cats.catsInstancesForId + implicit def catsComonadForTuple2[A]: Comonad[(A, *)] = cats.instances.tuple.catsStdInstancesForTuple2[A] + implicit def catsMonadErrorForEither[A]: MonadError[Either[A, *], A] = + cats.instances.either.catsStdInstancesForEither[A] + implicit def catsInstancesForOption + : MonadError[Option, Unit] with Alternative[Option] with CoflatMap[Option] with CommutativeMonad[Option] = + cats.instances.option.catsStdInstancesForOption + implicit def catsInstancesForList: Monad[List] with Alternative[List] with CoflatMap[List] = + cats.instances.list.catsStdInstancesForList + implicit def catsInstancesForVector: Monad[Vector] with Alternative[Vector] with CoflatMap[Vector] = + cats.instances.vector.catsStdInstancesForVector + implicit def catsInstancesForQueue: Monad[Queue] with Alternative[Queue] with CoflatMap[Queue] = + cats.instances.queue.catsStdInstancesForQueue + implicit def catsMonadForTailRec: Monad[TailRec] = cats.instances.tailRec.catsInstancesForTailRec + + implicit def catsFlatMapForMap[K]: FlatMap[Map[K, *]] = cats.instances.map.catsStdInstancesForMap[K] + implicit def catsFlatMapForSortedMap[K: Order]: FlatMap[SortedMap[K, *]] = + cats.instances.sortedMap.catsStdInstancesForSortedMap[K] + implicit def catsBimonadForFunction0[I]: Bimonad[Function0] = cats.instances.function.catsStdBimonadForFunction0 + implicit def catsMonadForFunction1[I]: Monad[I => *] = cats.instances.function.catsStdMonadForFunction1[I] + implicit def catsContravariantMonoidalForFunction1[R: Monoid]: ContravariantMonoidal[* => R] = + cats.instances.function.catsStdContravariantMonoidalForFunction1[R] + implicit def catsFunctorForPair: Functor[λ[P => (P, P)]] = cats.instances.tuple.catsDataFunctorForPair + + implicit def catsInstancesForTry: MonadError[Try, Throwable] with CoflatMap[Try] = + cats.instances.try_.catsStdInstancesForTry + + implicit def catsContravariantMonoidalForOrder: ContravariantMonoidal[Order] = + cats.instances.order.catsContravariantMonoidalForOrder + implicit def catsContravariantMonoidalForPartialOrder: ContravariantMonoidal[PartialOrder] = + cats.instances.partialOrder.catsContravariantMonoidalForPartialOrder + implicit def catsContravariantMonoidalForOrdering: ContravariantMonoidal[Ordering] = + cats.instances.ordering.catsContravariantMonoidalForOrdering + implicit def catsContravariantMonoidalForPartialOrdering: ContravariantMonoidal[PartialOrdering] = + cats.instances.partialOrdering.catsContravariantMonoidalForPartialOrdering + implicit def catsContravariantMonoidalForEq: ContravariantMonoidal[Eq] = + cats.instances.eq.catsContravariantMonoidalForEq + implicit def catsContravariantMonoidalForEquiv: ContravariantMonoidal[Equiv] = + cats.instances.equiv.catsContravariantMonoidalForEquiv + implicit def catsContravariantForHash: Contravariant[Hash] = + cats.instances.all.catsContravariantForHash + implicit def catsInvariantMonoidalForSemigroup: InvariantMonoidal[Semigroup] = + cats.instances.invariant.catsInvariantMonoidalSemigroup + implicit def catsInvariantMonoidalForCommutativeSemigroup: InvariantMonoidal[CommutativeSemigroup] = + cats.instances.invariant.catsInvariantMonoidalCommutativeSemigroup + implicit def catsInvariantSemigroupalForMonoid: InvariantSemigroupal[Monoid] = + cats.instances.invariant.catsSemigroupalForMonoid + implicit val catsInvariantMonoid: Invariant[Monoid] = new Invariant[Monoid] { def imap[A, B](fa: Monoid[A])(f: A => B)(g: B => A): Monoid[B] = new Monoid[B] { @@ -122,3 +174,30 @@ object Invariant { } } + +private[cats] trait InvariantInstances0 extends TupleInstances0 { + implicit def catsCommutativeMonadForTuple2[X](implicit X: CommutativeMonoid[X]): CommutativeMonad[(X, *)] = + cats.instances.tuple.catsStdCommutativeMonadForTuple2[X] + implicit def catsContravariantForFunction1[R]: Contravariant[* => R] = + cats.instances.function.catsStdContravariantForFunction1[R] + implicit def catsDistributiveForFunction0: Distributive[Function0] = cats.instances.function.function0Distributive + implicit def catsDistributiveForFunction1[I]: Distributive[I => *] = + cats.instances.function.catsStdDistributiveForFunction1[I] + implicit def catsApplicativeForArrow[F[_, _], A](implicit F: Arrow[F]): Applicative[F[A, *]] = + new ArrowApplicative[F, A](F) +} + +private trait TupleInstances0 extends TupleInstances1 { + implicit def catsCommutativeFlatMapForTuple2[X](implicit X: CommutativeSemigroup[X]): CommutativeFlatMap[(X, *)] = + cats.instances.tuple.catsStdCommutativeFlatMapForTuple2[X] +} + +private trait TupleInstances1 extends TupleInstances2 { + implicit def catsMonadForTuple2[X](implicit X: Monoid[X]): Monad[(X, *)] = + cats.instances.tuple.catsStdMonadForTuple2[X] +} + +private trait TupleInstances2 { + implicit def catsFlatMapForTuple2[X](implicit X: Semigroup[X]): FlatMap[(X, *)] = + cats.instances.tuple.catsStdFlatMapForTuple2[X] +} diff --git a/core/src/main/scala/cats/Parallel.scala b/core/src/main/scala/cats/Parallel.scala index 92e1ba661f..8a3a0c374e 100644 --- a/core/src/main/scala/cats/Parallel.scala +++ b/core/src/main/scala/cats/Parallel.scala @@ -1,6 +1,7 @@ package cats import cats.arrow.FunctionK +import cats.data.{Validated, ZipList, ZipVector} /** * Some types that form a FlatMap, are also capable of forming an Apply that supports parallel composition. @@ -106,11 +107,20 @@ trait Parallel[M[_]] extends NonEmptyParallel[M] { } } -object NonEmptyParallel { +object NonEmptyParallel extends ScalaVersionSpecificParallelInstances { type Aux[M[_], F0[_]] = NonEmptyParallel[M] { type F[x] = F0[x] } def apply[M[_], F[_]](implicit P: NonEmptyParallel.Aux[M, F]): NonEmptyParallel.Aux[M, F] = P def apply[M[_]](implicit P: NonEmptyParallel[M], D: DummyImplicit): NonEmptyParallel.Aux[M, P.F] = P + + implicit def catsParallelForEitherValidated[E: Semigroup]: Parallel.Aux[Either[E, *], Validated[E, *]] = + cats.instances.either.catsParallelForEitherAndValidated[E] + + implicit def catsStdNonEmptyParallelForZipList: NonEmptyParallel.Aux[List, ZipList] = + cats.instances.list.catsStdNonEmptyParallelForListZipList + + implicit def catsStdNonEmptyParallelForZipVector: NonEmptyParallel.Aux[Vector, ZipVector] = + cats.instances.vector.catsStdNonEmptyParallelForVectorZipVector } object Parallel extends ParallelArityFunctions2 { diff --git a/core/src/main/scala/cats/Representable.scala b/core/src/main/scala/cats/Representable.scala index d16720cbc5..84d953618c 100644 --- a/core/src/main/scala/cats/Representable.scala +++ b/core/src/main/scala/cats/Representable.scala @@ -145,4 +145,11 @@ object Representable { new RepresentableDistributive[F, Rep.Representation] { override def R: Aux[F, Rep.Representation] = Rep } + + implicit def catsRepresentableForFunction1[E](implicit EF: Functor[E => *]): Representable.Aux[E => *, E] = + cats.instances.function.catsStdRepresentableForFunction1[E] + + implicit def catsRepresentableForPair( + implicit PF: Functor[λ[P => (P, P)]] + ): Representable.Aux[λ[P => (P, P)], Boolean] = cats.instances.tuple.catsDataRepresentableForPair } diff --git a/core/src/main/scala/cats/SemigroupK.scala b/core/src/main/scala/cats/SemigroupK.scala index 3afa632164..a28cadb672 100644 --- a/core/src/main/scala/cats/SemigroupK.scala +++ b/core/src/main/scala/cats/SemigroupK.scala @@ -1,5 +1,6 @@ package cats +import scala.collection.immutable.{SortedMap, SortedSet} import simulacrum.typeclass import cats.data.Ior @@ -84,10 +85,22 @@ import cats.data.Ior combineK(F.map(fa)(Left(_)), F.map(fb)(Right(_))) } -object SemigroupK { +object SemigroupK extends ScalaVersionSpecificMonoidKInstances { def align[F[_]: SemigroupK: Functor]: Align[F] = new Align[F] { def align[A, B](fa: F[A], fb: F[B]): F[Ior[A, B]] = SemigroupK[F].combineK(Functor[F].map(fa)(Ior.left), Functor[F].map(fb)(Ior.right)) def functor: Functor[F] = Functor[F] } + + implicit def catsMonoidKForOption: MonoidK[Option] = cats.instances.option.catsStdInstancesForOption + implicit def catsMonoidKForList: MonoidK[List] = cats.instances.list.catsStdInstancesForList + implicit def catsMonoidKForVector: MonoidK[Vector] = cats.instances.vector.catsStdInstancesForVector + implicit def catsMonoidKForSet: MonoidK[Set] = cats.instances.set.catsStdInstancesForSet + implicit def catsMonoidKForMap[K]: MonoidK[Map[K, *]] = cats.instances.map.catsStdMonoidKForMap[K] + implicit def catsSemigroupKForEither[A]: SemigroupK[Either[A, *]] = + cats.instances.either.catsStdSemigroupKForEither[A] + implicit def catsSemigroupKForSortedSet: SemigroupK[SortedSet] = cats.instances.sortedSet.catsStdInstancesForSortedSet + implicit def catsMonoidKForSortedMap[K: Order]: MonoidK[SortedMap[K, *]] = + cats.instances.sortedMap.catsStdMonoidKForSortedMap[K] + implicit def catsMonoidKForEndo: MonoidK[Endo] = cats.instances.function.catsStdMonoidKForFunction1 } diff --git a/core/src/main/scala/cats/Semigroupal.scala b/core/src/main/scala/cats/Semigroupal.scala index 500e9cd010..794f98bd16 100644 --- a/core/src/main/scala/cats/Semigroupal.scala +++ b/core/src/main/scala/cats/Semigroupal.scala @@ -1,5 +1,8 @@ package cats +import cats.kernel.CommutativeSemigroup +import scala.collection.immutable.{Queue, SortedMap, SortedSet} +import scala.util.Try import simulacrum.typeclass /** @@ -42,4 +45,40 @@ import simulacrum.typeclass def product[A, B](fa: F[A], fb: F[B]): F[(A, B)] } -object Semigroupal extends SemigroupalArityFunctions +object Semigroupal extends ScalaVersionSpecificSemigroupalInstances with SemigroupalArityFunctions { + implicit def catsSemigroupalForOption: Semigroupal[Option] = cats.instances.option.catsStdInstancesForOption + implicit def catsSemigroupalForTry: Semigroupal[Try] = cats.instances.try_.catsStdInstancesForTry + implicit def catsSemigroupalForList: Semigroupal[List] = cats.instances.list.catsStdInstancesForList + implicit def catsSemigroupalForVector: Semigroupal[Vector] = cats.instances.vector.catsStdInstancesForVector + implicit def catsSemigroupalForQueue: Semigroupal[Queue] = cats.instances.queue.catsStdInstancesForQueue + implicit def catsSemigroupalForMap[K]: Semigroupal[Map[K, *]] = cats.instances.map.catsStdInstancesForMap[K] + implicit def catsSemigroupalForEither[A]: Semigroupal[Either[A, *]] = + cats.instances.either.catsStdInstancesForEither[A] + implicit def catsSemigroupalForSortedSet: Semigroupal[SortedSet] = + cats.instances.sortedSet.catsStdSemigroupalForSortedSet + implicit def catsSemigroupalForSortedMap[K: Order]: Semigroupal[SortedMap[K, *]] = + cats.instances.sortedMap.catsStdInstancesForSortedMap[K] + implicit def catsSemigroupalForFunction1[A]: Semigroupal[A => *] = + cats.instances.function.catsStdMonadForFunction1[A] + implicit def catsSemigroupalForFunction1Contravariant[R: Monoid]: Semigroupal[* => R] = + cats.instances.function.catsStdContravariantMonoidalForFunction1[R] + implicit def catsSemigroupalForFunction0: Semigroupal[Function0] = + cats.instances.function.catsStdBimonadForFunction0 + + implicit val catsSemigroupalForOrder: Semigroupal[Order] = cats.instances.order.catsContravariantMonoidalForOrder + implicit val catsSemigroupalForPartialOrder: Semigroupal[PartialOrder] = + cats.instances.partialOrder.catsContravariantMonoidalForPartialOrder + implicit val catsSemigroupalForOrdering: Semigroupal[Ordering] = + cats.instances.ordering.catsContravariantMonoidalForOrdering + implicit val catsSemigroupalForPartialOrdering: Semigroupal[PartialOrdering] = + cats.instances.partialOrdering.catsContravariantMonoidalForPartialOrdering + implicit val catsSemigroupalForEq: Semigroupal[Eq] = cats.instances.eq.catsContravariantMonoidalForEq + implicit val catsSemigroupalForEquiv: Semigroupal[Equiv] = + cats.instances.equiv.catsContravariantMonoidalForEquiv + implicit val catsSemigroupalForMonoid: Semigroupal[Monoid] = + cats.instances.invariant.catsSemigroupalForMonoid + implicit val catsSemigroupalForSemigroup: Semigroupal[Semigroup] = + cats.instances.invariant.catsInvariantMonoidalSemigroup + implicit val catsSemigroupalForCommutativeSemigroup: Semigroupal[CommutativeSemigroup] = + cats.instances.invariant.catsInvariantMonoidalCommutativeSemigroup +} diff --git a/core/src/main/scala/cats/Show.scala b/core/src/main/scala/cats/Show.scala index 08033ea072..3b73734c45 100644 --- a/core/src/main/scala/cats/Show.scala +++ b/core/src/main/scala/cats/Show.scala @@ -1,5 +1,10 @@ package cats +import java.util.UUID +import scala.collection.immutable.{BitSet, Queue, SortedMap, SortedSet} +import scala.concurrent.duration.{Duration, FiniteDuration} +import scala.util.Try + /** * A type class to provide textual representation. It is meant to be a * better "toString". Whereas toString exists for any Object, @@ -12,7 +17,7 @@ trait Show[T] extends Show.ContravariantShow[T] /** * Hand rolling the type class boilerplate due to scala/bug#6260 and scala/bug#10458 */ -object Show { +object Show extends ScalaVersionSpecificShowInstances with ShowInstances { def apply[A](implicit instance: Show[A]): Show[A] = instance @@ -56,4 +61,40 @@ object Show { def contramap[A, B](fa: Show[A])(f: B => A): Show[B] = show[B]((fa.show _).compose(f)) } + + implicit def catsShowForUnit: Show[Unit] = cats.instances.unit.catsStdShowForUnit + implicit def catsShowForBoolean: Show[Boolean] = cats.instances.boolean.catsStdShowForBoolean + implicit def catsShowForByte: Show[Byte] = cats.instances.byte.catsStdShowForByte + implicit def catsShowForShort: Show[Short] = cats.instances.short.catsStdShowForShort + implicit def catsShowForInt: Show[Int] = cats.instances.int.catsStdShowForInt + implicit def catsShowForLong: Show[Long] = cats.instances.long.catsStdShowForLong + implicit def catsShowForFloat: Show[Float] = cats.instances.float.catsStdShowForFloat + implicit def catsShowForDouble: Show[Double] = cats.instances.double.catsStdShowForDouble + implicit def catsShowForBigInt: Show[BigInt] = cats.instances.bigInt.catsStdShowForBigInt + implicit def catsShowForBigDecimal: Show[BigDecimal] = cats.instances.bigDecimal.catsStdShowForBigDecimal + implicit def catsShowForChar: Show[Char] = cats.instances.char.catsStdShowForChar + implicit def catsShowForSymbol: Show[Symbol] = cats.instances.symbol.catsStdShowForSymbol + implicit def catsShowForString: Show[String] = cats.instances.string.catsStdShowForString + implicit def catsShowForUUID: Show[UUID] = cats.instances.uuid.catsStdShowForUUID + implicit def catsShowForDuration: Show[Duration] = cats.instances.duration.catsStdShowForDurationUnambiguous + implicit def catsShowForBitSet: Show[BitSet] = cats.instances.bitSet.catsStdShowForBitSet + + implicit def catsShowForOption[A: Show]: Show[Option[A]] = cats.instances.option.catsStdShowForOption[A] + implicit def catsShowForTry[A: Show]: Show[Try[A]] = cats.instances.try_.catsStdShowForTry[A] + implicit def catsShowForList[A: Show]: Show[List[A]] = cats.instances.list.catsStdShowForList[A] + implicit def catsShowForVector[A: Show]: Show[Vector[A]] = cats.instances.vector.catsStdShowForVector[A] + implicit def catsShowForQueue[A: Show]: Show[Queue[A]] = cats.instances.queue.catsStdShowForQueue[A] + implicit def catsShowForEither[A: Show, B: Show]: Show[Either[A, B]] = + cats.instances.either.catsStdShowForEither[A, B] + implicit def catsShowForTuple2[A: Show, B: Show]: Show[(A, B)] = cats.instances.tuple.catsStdShowForTuple2[A, B] + implicit def catsShowForSet[A: Show]: Show[Set[A]] = cats.instances.set.catsStdShowForSet[A] + implicit def catsShowForMap[K: Show, V: Show]: Show[Map[K, V]] = cats.instances.map.catsStdShowForMap[K, V] + implicit def catsShowForSortedSet[A: Show]: Show[SortedSet[A]] = cats.instances.sortedSet.catsStdShowForSortedSet[A] + implicit def catsShowForSortedMap[K: Order: Show, V: Show]: Show[SortedMap[K, V]] = + cats.instances.sortedMap.catsStdShowForSortedMap[K, V] +} + +private[cats] trait ShowInstances { + implicit def catsShowForFiniteDuration: Show[FiniteDuration] = + cats.instances.finiteDuration.catsStdShowForFiniteDurationUnambiguous } diff --git a/core/src/main/scala/cats/Traverse.scala b/core/src/main/scala/cats/Traverse.scala index 17fc0a5a75..e4a5037f58 100644 --- a/core/src/main/scala/cats/Traverse.scala +++ b/core/src/main/scala/cats/Traverse.scala @@ -129,3 +129,7 @@ import simulacrum.typeclass override def unorderedSequence[G[_]: CommutativeApplicative, A](fga: F[G[A]]): G[F[A]] = sequence(fga) } + +object Traverse { + implicit def catsTraverseForEither[A]: Traverse[Either[A, *]] = cats.instances.either.catsStdInstancesForEither[A] +} diff --git a/core/src/main/scala/cats/UnorderedFoldable.scala b/core/src/main/scala/cats/UnorderedFoldable.scala index 683575f3e1..d267d5a4f7 100644 --- a/core/src/main/scala/cats/UnorderedFoldable.scala +++ b/core/src/main/scala/cats/UnorderedFoldable.scala @@ -1,7 +1,8 @@ package cats -import cats.instances.long._ import cats.kernel.CommutativeMonoid +import scala.collection.immutable.{Queue, SortedMap, SortedSet} +import scala.util.Try import simulacrum.{noop, typeclass} /** @@ -71,7 +72,7 @@ import simulacrum.{noop, typeclass} unorderedFoldMap(fa)(a => if (p(a)) 1L else 0L) } -object UnorderedFoldable { +object UnorderedFoldable extends ScalaVersionSpecificTraverseInstances { private val orEvalMonoid: CommutativeMonoid[Eval[Boolean]] = new CommutativeMonoid[Eval[Boolean]] { val empty: Eval[Boolean] = Eval.False @@ -91,4 +92,23 @@ object UnorderedFoldable { case false => Eval.False } } + + implicit def catsNonEmptyTraverseForId: NonEmptyTraverse[Id] = catsInstancesForId + implicit def catsTraverseForOption: Traverse[Option] = cats.instances.option.catsStdInstancesForOption + implicit def catsTraverseForList: Traverse[List] = cats.instances.list.catsStdInstancesForList + implicit def catsTraverseForVector: Traverse[Vector] = cats.instances.vector.catsStdInstancesForVector + implicit def catsTraverseForQueue: Traverse[Queue] = cats.instances.queue.catsStdInstancesForQueue + implicit def catsUnorderedTraverseForSet: UnorderedTraverse[Set] = cats.instances.set.catsStdInstancesForSet + implicit def catsFoldableForSortedSet: Foldable[SortedSet] = cats.instances.sortedSet.catsStdInstancesForSortedSet + implicit def catsTraverseForSortedMap[K: Order]: Traverse[SortedMap[K, *]] = + cats.instances.sortedMap.catsStdInstancesForSortedMap[K] + + implicit def catsUnorderedTraverseForMap[K]: UnorderedTraverse[Map[K, *]] = + cats.instances.map.catsStdInstancesForMap[K] + + implicit def catsTraverseForEither[A]: Traverse[Either[A, *]] = cats.instances.either.catsStdInstancesForEither[A] + implicit def catsInstancesForTuple[A]: Traverse[(A, *)] with Reducible[(A, *)] = + cats.instances.tuple.catsStdInstancesForTuple2[A] + + implicit def catsTraverseForTry: Traverse[Try] = cats.instances.try_.catsStdInstancesForTry } diff --git a/core/src/main/scala/cats/arrow/Compose.scala b/core/src/main/scala/cats/arrow/Compose.scala index c520eb5f19..e0745ccaaa 100644 --- a/core/src/main/scala/cats/arrow/Compose.scala +++ b/core/src/main/scala/cats/arrow/Compose.scala @@ -37,3 +37,9 @@ import simulacrum.typeclass def combine(f1: F[A, A], f2: F[A, A]): F[A, A] = self.compose(f1, f2) } } + +object Compose { + implicit def catsInstancesForFunction1: ArrowChoice[Function1] with CommutativeArrow[Function1] = + cats.instances.function.catsStdInstancesForFunction1 + implicit def catsComposeForMap: Compose[Map] = cats.instances.map.catsStdComposeForMap +} diff --git a/core/src/main/scala/cats/arrow/Profunctor.scala b/core/src/main/scala/cats/arrow/Profunctor.scala index 31ca4281ba..ad63da692c 100644 --- a/core/src/main/scala/cats/arrow/Profunctor.scala +++ b/core/src/main/scala/cats/arrow/Profunctor.scala @@ -40,3 +40,8 @@ import simulacrum.typeclass def rmap[A, B, C](fab: F[A, B])(f: B => C): F[A, C] = dimap[A, B, A, C](fab)(identity)(f) } + +object Profunctor { + implicit def catsStrongForFunction1: Strong[Function1] = + cats.instances.function.catsStdInstancesForFunction1 +} diff --git a/core/src/main/scala/cats/data/EitherT.scala b/core/src/main/scala/cats/data/EitherT.scala index e50d6f2d94..45ac64c1e7 100644 --- a/core/src/main/scala/cats/data/EitherT.scala +++ b/core/src/main/scala/cats/data/EitherT.scala @@ -1,7 +1,7 @@ package cats package data -import cats.instances.either._ +import cats.Bifunctor import cats.syntax.EitherUtil /** diff --git a/core/src/main/scala/cats/data/NonEmptyList.scala b/core/src/main/scala/cats/data/NonEmptyList.scala index 75ce264bb0..e6e8d48b2d 100644 --- a/core/src/main/scala/cats/data/NonEmptyList.scala +++ b/core/src/main/scala/cats/data/NonEmptyList.scala @@ -2,7 +2,6 @@ package cats package data import cats.data.NonEmptyList.ZipNonEmptyList -import cats.instances.list._ import scala.annotation.tailrec import scala.collection.immutable.{SortedMap, TreeMap, TreeSet} diff --git a/core/src/main/scala/cats/data/NonEmptyMapImpl.scala b/core/src/main/scala/cats/data/NonEmptyMapImpl.scala index 96f6c66b81..8762a59764 100644 --- a/core/src/main/scala/cats/data/NonEmptyMapImpl.scala +++ b/core/src/main/scala/cats/data/NonEmptyMapImpl.scala @@ -1,7 +1,6 @@ package cats package data -import cats.instances.sortedMap._ import cats.kernel._ import cats.{Always, Apply, Eval, Foldable, Functor, Later, NonEmptyTraverse, Now, SemigroupK, Show} diff --git a/core/src/main/scala/cats/data/NonEmptySet.scala b/core/src/main/scala/cats/data/NonEmptySet.scala index ffe6f07c33..740b5021eb 100644 --- a/core/src/main/scala/cats/data/NonEmptySet.scala +++ b/core/src/main/scala/cats/data/NonEmptySet.scala @@ -1,7 +1,6 @@ package cats package data -import cats.instances.sortedSet._ import cats.kernel._ import scala.collection.immutable._ diff --git a/core/src/main/scala/cats/data/NonEmptyVector.scala b/core/src/main/scala/cats/data/NonEmptyVector.scala index c5252c6157..2cbd15da6a 100644 --- a/core/src/main/scala/cats/data/NonEmptyVector.scala +++ b/core/src/main/scala/cats/data/NonEmptyVector.scala @@ -2,7 +2,6 @@ package cats package data import cats.data.NonEmptyVector.ZipNonEmptyVector -import cats.instances.vector._ import scala.annotation.tailrec import scala.collection.mutable diff --git a/core/src/main/scala/cats/data/OptionT.scala b/core/src/main/scala/cats/data/OptionT.scala index 222e39cca1..fc4e5cf6e6 100644 --- a/core/src/main/scala/cats/data/OptionT.scala +++ b/core/src/main/scala/cats/data/OptionT.scala @@ -1,8 +1,6 @@ package cats package data -import cats.instances.option.{catsStdInstancesForOption => optionInstance, catsStdTraverseFilterForOption} - /** * `OptionT[F[_], A]` is a light wrapper on an `F[Option[A]]` with some * convenient methods for working with this nested structure. @@ -120,13 +118,13 @@ final case class OptionT[F[_], A](value: F[Option[A]]) { eq.eqv(value, that.value) def traverse[G[_], B](f: A => G[B])(implicit F: Traverse[F], G: Applicative[G]): G[OptionT[F, B]] = - G.map(F.compose(optionInstance).traverse(value)(f))(OptionT.apply) + G.map(F.compose(Traverse[Option]).traverse(value)(f))(OptionT.apply) def foldLeft[B](b: B)(f: (B, A) => B)(implicit F: Foldable[F]): B = - F.compose(optionInstance).foldLeft(value, b)(f) + F.compose(Foldable[Option]).foldLeft(value, b)(f) def foldRight[B](lb: Eval[B])(f: (A, Eval[B]) => Eval[B])(implicit F: Foldable[F]): Eval[B] = - F.compose(optionInstance).foldRight(value, lb)(f) + F.compose(Foldable[Option]).foldRight(value, lb)(f) /** * Transform this `OptionT[F, A]` into a `[[Nested]][F, Option, A]`. diff --git a/core/src/main/scala/cats/data/WriterT.scala b/core/src/main/scala/cats/data/WriterT.scala index b1fb96cc8c..24fa9047e2 100644 --- a/core/src/main/scala/cats/data/WriterT.scala +++ b/core/src/main/scala/cats/data/WriterT.scala @@ -2,7 +2,6 @@ package cats package data import cats.Foldable -import cats.kernel.instances.tuple._ import cats.kernel.CommutativeMonoid final case class WriterT[F[_], L, V](run: F[(L, V)]) { diff --git a/core/src/main/scala/cats/data/ZipList.scala b/core/src/main/scala/cats/data/ZipList.scala index 66a491c736..7240ecc1a0 100644 --- a/core/src/main/scala/cats/data/ZipList.scala +++ b/core/src/main/scala/cats/data/ZipList.scala @@ -1,7 +1,6 @@ package cats package data -import instances.list.catsKernelStdEqForList import kernel.compat.scalaVersionSpecific._ class ZipList[A](val value: List[A]) extends AnyVal diff --git a/core/src/main/scala/cats/data/ZipVector.scala b/core/src/main/scala/cats/data/ZipVector.scala index ebb7e1a4cc..75f5a45736 100644 --- a/core/src/main/scala/cats/data/ZipVector.scala +++ b/core/src/main/scala/cats/data/ZipVector.scala @@ -1,7 +1,6 @@ package cats package data -import instances.vector._ import kernel.compat.scalaVersionSpecific._ class ZipVector[A](val value: Vector[A]) extends AnyVal diff --git a/core/src/main/scala/cats/data/package.scala b/core/src/main/scala/cats/data/package.scala index ca3e350143..3d5ea2c0ba 100644 --- a/core/src/main/scala/cats/data/package.scala +++ b/core/src/main/scala/cats/data/package.scala @@ -79,7 +79,6 @@ package object data extends ScalaVersionSpecificPackage { type Store[S, A] = RepresentableStore[S => *, S, A] object Store { - import cats.instances.function._ def apply[S, A](f: S => A, s: S): Store[S, A] = RepresentableStore[S => *, S, A](f, s) } diff --git a/kernel/src/main/scala-2.12/cats/kernel/ScalaVersionSpecificInstances.scala b/kernel/src/main/scala-2.12/cats/kernel/ScalaVersionSpecificInstances.scala new file mode 100644 index 0000000000..621365d5ee --- /dev/null +++ b/kernel/src/main/scala-2.12/cats/kernel/ScalaVersionSpecificInstances.scala @@ -0,0 +1,25 @@ +package cats.kernel + +private[kernel] trait ScalaVersionSpecificOrderInstances extends ScalaVersionSpecificPartialOrderInstances { + implicit def catsKernelOrderForStream[A: Order]: Order[Stream[A]] = + cats.kernel.instances.stream.catsKernelStdOrderForStream[A] +} + +private[kernel] trait ScalaVersionSpecificPartialOrderInstances extends ScalaVersionSpecificHashInstances { + implicit def catsKernelPartialOrderForStream[A: PartialOrder]: PartialOrder[Stream[A]] = + cats.kernel.instances.stream.catsKernelStdPartialOrderForStream[A] +} + +private[kernel] trait ScalaVersionSpecificHashInstances extends ScalaVersionSpecificEqInstances { + implicit def catsKernelHashForStream[A: Hash]: Hash[Stream[A]] = + cats.kernel.instances.stream.catsKernelStdHashForStream[A] +} + +private[kernel] trait ScalaVersionSpecificEqInstances { + implicit def catsKernelEqForStream[A: Eq]: Eq[Stream[A]] = cats.kernel.instances.stream.catsKernelStdEqForStream[A] +} + +private[kernel] trait ScalaVersionSpecificMonoidInstances { + implicit def catsKernelMonoidForStream[A]: Monoid[Stream[A]] = + cats.kernel.instances.stream.catsKernelStdMonoidForStream[A] +} diff --git a/kernel/src/main/scala-2.13+/cats/kernel/ScalaVersionSpecificInstances.scala b/kernel/src/main/scala-2.13+/cats/kernel/ScalaVersionSpecificInstances.scala new file mode 100644 index 0000000000..d5ac6ea207 --- /dev/null +++ b/kernel/src/main/scala-2.13+/cats/kernel/ScalaVersionSpecificInstances.scala @@ -0,0 +1,62 @@ +package cats.kernel + +import scala.collection.immutable.ArraySeq + +private[kernel] trait ScalaVersionSpecificOrderInstances extends ScalaVersionSpecificPartialOrderInstances { + @deprecated("Use catsKernelOrderForLazyList", "3.0.0") + implicit def catsKernelOrderForStream[A: Order]: Order[Stream[A]] = + cats.kernel.instances.stream.catsKernelStdOrderForStream[A] + + implicit def catsKernelOrderForLazyList[A: Order]: Order[LazyList[A]] = + cats.kernel.instances.lazyList.catsKernelStdOrderForLazyList[A] + + implicit def catsKernelOrderForArraySeq[A: Order]: Order[ArraySeq[A]] = + cats.kernel.instances.arraySeq.catsKernelStdOrderForArraySeq[A] +} + +private[kernel] trait ScalaVersionSpecificPartialOrderInstances extends ScalaVersionSpecificHashInstances { + @deprecated("Use catsKernelPartialOrderForLazyList", "3.0.0") + implicit def catsKernelPartialOrderForStream[A: PartialOrder]: PartialOrder[Stream[A]] = + cats.kernel.instances.stream.catsKernelStdPartialOrderForStream[A] + + implicit def catsKernelPartialOrderForLazyList[A: PartialOrder]: PartialOrder[LazyList[A]] = + cats.kernel.instances.lazyList.catsKernelStdPartialOrderForLazyList[A] + + implicit def catsKernelPartialOrderForArraySeq[A: PartialOrder]: PartialOrder[ArraySeq[A]] = + cats.kernel.instances.arraySeq.catsKernelStdPartialOrderForArraySeq[A] +} + +private[kernel] trait ScalaVersionSpecificHashInstances extends ScalaVersionSpecificEqInstances { + @deprecated("Use catsKernelHashForLazyList", "3.0.0") + implicit def catsKernelHashForStream[A: Hash]: Hash[Stream[A]] = + cats.kernel.instances.stream.catsKernelStdHashForStream[A] + + implicit def catsKernelHashForLazyList[A: Hash]: Hash[LazyList[A]] = + cats.kernel.instances.lazyList.catsKernelStdHashForLazyList[A] + + implicit def catsKernelHashForArraySeq[A: Hash]: Hash[ArraySeq[A]] = + cats.kernel.instances.arraySeq.catsKernelStdHashForArraySeq[A] +} + +private[kernel] trait ScalaVersionSpecificEqInstances { + @deprecated("Use catsKernelEqForLazyList", "3.0.0") + implicit def catsKernelEqForStream[A: Eq]: Eq[Stream[A]] = cats.kernel.instances.stream.catsKernelStdEqForStream[A] + + implicit def catsKernelEqForLazyList[A: Eq]: Eq[LazyList[A]] = + cats.kernel.instances.lazyList.catsKernelStdEqForLazyList[A] + + implicit def catsKernelEqForArraySeq[A: Eq]: Eq[ArraySeq[A]] = + cats.kernel.instances.arraySeq.catsKernelStdEqForArraySeq[A] +} + +private[kernel] trait ScalaVersionSpecificMonoidInstances { + @deprecated("Use catsKernelMonoidForLazyList", "3.0.0") + implicit def catsKernelMonoidForStream[A]: Monoid[Stream[A]] = + cats.kernel.instances.stream.catsKernelStdMonoidForStream[A] + + implicit def catsKernelMonoidForLazyList[A]: Monoid[LazyList[A]] = + cats.kernel.instances.lazyList.catsKernelStdMonoidForLazyList[A] + + implicit def catsKernelMonoidForArraySeq[A]: Monoid[ArraySeq[A]] = + cats.kernel.instances.arraySeq.catsKernelStdMonoidForArraySeq[A] +} diff --git a/kernel/src/main/scala/cats/kernel/Bounded.scala b/kernel/src/main/scala/cats/kernel/Bounded.scala index d57f3fe5fb..865d2b7b49 100644 --- a/kernel/src/main/scala/cats/kernel/Bounded.scala +++ b/kernel/src/main/scala/cats/kernel/Bounded.scala @@ -1,5 +1,7 @@ package cats.kernel +import java.util.UUID +import scala.concurrent.duration.{Duration, FiniteDuration} import scala.{specialized => sp} /** @@ -20,6 +22,25 @@ trait LowerBoundedFunctions[L[T] <: LowerBounded[T]] { object LowerBounded extends LowerBoundedFunctions[LowerBounded] { @inline def apply[A](implicit l: LowerBounded[A]): LowerBounded[A] = l + + implicit def catsKernelLowerBoundedForUnit: LowerBounded[Unit] = cats.kernel.instances.unit.catsKernelStdOrderForUnit + implicit def catsKernelLowerBoundedForBoolean: LowerBounded[Boolean] = + cats.kernel.instances.boolean.catsKernelStdOrderForBoolean + implicit def catsKernelLowerBoundedForByte: LowerBounded[Byte] = cats.kernel.instances.byte.catsKernelStdOrderForByte + implicit def catsKernelLowerBoundedForInt: LowerBounded[Int] = cats.kernel.instances.int.catsKernelStdOrderForInt + implicit def catsKernelLowerBoundedForShort: LowerBounded[Short] = + cats.kernel.instances.short.catsKernelStdOrderForShort + implicit def catsKernelLowerBoundedForLong: LowerBounded[Long] = cats.kernel.instances.long.catsKernelStdOrderForLong + implicit def catsKernelLowerBoundedForDuration: LowerBounded[Duration] = + cats.kernel.instances.duration.catsKernelStdOrderForDuration + implicit def catsKernelLowerBoundedForFiniteDuration: LowerBounded[FiniteDuration] = + cats.kernel.instances.all.catsKernelStdOrderForFiniteDuration + implicit def catsKernelLowerBoundedForChar: LowerBounded[Char] = cats.kernel.instances.char.catsKernelStdOrderForChar + implicit def catsKernelLowerBoundedForString: LowerBounded[String] = + cats.kernel.instances.string.catsKernelStdOrderForString + implicit def catsKernelLowerBoundedForSymbol: LowerBounded[Symbol] = + cats.kernel.instances.symbol.catsKernelStdOrderForSymbol + implicit def catsKernelLowerBoundedForUUID: LowerBounded[UUID] = cats.kernel.instances.uuid.catsKernelStdOrderForUUID } /** @@ -40,4 +61,19 @@ trait UpperBoundedFunctions[U[T] <: UpperBounded[T]] { object UpperBounded extends UpperBoundedFunctions[UpperBounded] { @inline def apply[A](implicit u: UpperBounded[A]): UpperBounded[A] = u + + implicit def catsKernelUpperBoundedForUnit: UpperBounded[Unit] = cats.kernel.instances.unit.catsKernelStdOrderForUnit + implicit def catsKernelUpperBoundedForBoolean: UpperBounded[Boolean] = + cats.kernel.instances.boolean.catsKernelStdOrderForBoolean + implicit def catsKernelUpperBoundedForByte: UpperBounded[Byte] = cats.kernel.instances.byte.catsKernelStdOrderForByte + implicit def catsKernelUpperBoundedForInt: UpperBounded[Int] = cats.kernel.instances.int.catsKernelStdOrderForInt + implicit def catsKernelUpperBoundedForShort: UpperBounded[Short] = + cats.kernel.instances.short.catsKernelStdOrderForShort + implicit def catsKernelUpperBoundedForLong: UpperBounded[Long] = cats.kernel.instances.long.catsKernelStdOrderForLong + implicit def catsKernelUpperBoundedForDuration: UpperBounded[Duration] = + cats.kernel.instances.duration.catsKernelStdOrderForDuration + implicit def catsKernelUpperBoundedForFiniteDuration: UpperBounded[FiniteDuration] = + cats.kernel.instances.all.catsKernelStdOrderForFiniteDuration + implicit def catsKernelUpperBoundedForChar: UpperBounded[Char] = cats.kernel.instances.char.catsKernelStdOrderForChar + implicit def catsKernelUpperBoundedForUUID: UpperBounded[UUID] = cats.kernel.instances.uuid.catsKernelStdOrderForUUID } diff --git a/kernel/src/main/scala/cats/kernel/Eq.scala b/kernel/src/main/scala/cats/kernel/Eq.scala index 94c6486589..1b88aa6dff 100644 --- a/kernel/src/main/scala/cats/kernel/Eq.scala +++ b/kernel/src/main/scala/cats/kernel/Eq.scala @@ -1,7 +1,11 @@ package cats.kernel -import scala.{specialized => sp} +import java.util.UUID +import scala.collection.immutable.{BitSet, Queue, SortedMap, SortedSet} +import scala.concurrent.duration.{Duration, FiniteDuration} import scala.math.Equiv +import scala.{specialized => sp} +import scala.util.{Failure, Success, Try} import compat.scalaVersionSpecific._ /** @@ -43,7 +47,12 @@ trait EqToEquivConversion { } @suppressUnusedImportWarningForScalaVersionSpecific -object Eq extends EqFunctions[Eq] with EqToEquivConversion { +object Eq + extends EqFunctions[Eq] + with EqToEquivConversion + with ScalaVersionSpecificOrderInstances + with instances.TupleOrderInstances + with PartialOrderInstances { /** * Access an implicit `Eq[A]`. @@ -135,4 +144,117 @@ object Eq extends EqFunctions[Eq] with EqToEquivConversion { }) } } + + implicit def catsKernelInstancesForBitSet: PartialOrder[BitSet] with Hash[BitSet] = + cats.kernel.instances.bitSet.catsKernelStdOrderForBitSet + implicit def catsKernelPartialOrderForSet[A]: PartialOrder[Set[A]] = + cats.kernel.instances.set.catsKernelStdPartialOrderForSet[A] + implicit def catsKernelOrderForEither[A: Order, B: Order]: Order[Either[A, B]] = + cats.kernel.instances.either.catsStdOrderForEither[A, B] + + implicit def catsKernelInstancesForUnit: Order[Unit] with Hash[Unit] = + cats.kernel.instances.unit.catsKernelStdOrderForUnit + implicit def catsKernelInstancesForBoolean: Order[Boolean] with Hash[Boolean] = + cats.kernel.instances.boolean.catsKernelStdOrderForBoolean + implicit def catsKernelInstancesForByte: Order[Byte] with Hash[Byte] = + cats.kernel.instances.byte.catsKernelStdOrderForByte + implicit def catsKernelInstancesForShort: Order[Short] with Hash[Short] = + cats.kernel.instances.short.catsKernelStdOrderForShort + implicit def catsKernelInstancesForInt: Order[Int] with Hash[Int] = cats.kernel.instances.int.catsKernelStdOrderForInt + implicit def catsKernelInstancesForLong: Order[Long] with Hash[Long] = + cats.kernel.instances.long.catsKernelStdOrderForLong + implicit def catsKernelInstancesForBigInt: Order[BigInt] with Hash[BigInt] = + cats.kernel.instances.bigInt.catsKernelStdOrderForBigInt + implicit def catsKernelInstancesForBigDecimal: Order[BigDecimal] with Hash[BigDecimal] = + cats.kernel.instances.bigDecimal.catsKernelStdOrderForBigDecimal + implicit def catsKernelInstancesForDuration: Order[Duration] with Hash[Duration] = + cats.kernel.instances.duration.catsKernelStdOrderForDuration + implicit def catsKernelInstancesForFiniteDuration: Order[FiniteDuration] with Hash[FiniteDuration] = + cats.kernel.instances.all.catsKernelStdOrderForFiniteDuration + implicit def catsKernelInstancesForChar: Order[Char] with Hash[Char] = + cats.kernel.instances.char.catsKernelStdOrderForChar + implicit def catsKernelInstancesForSymbol: Order[Symbol] with Hash[Symbol] = + cats.kernel.instances.symbol.catsKernelStdOrderForSymbol + implicit def catsKernelInstancesForString: Order[String] with Hash[String] = + cats.kernel.instances.string.catsKernelStdOrderForString + implicit def catsKernelInstancesForUUID: Order[UUID] with Hash[UUID] = + cats.kernel.instances.uuid.catsKernelStdOrderForUUID + implicit def catsKernelInstancesForDouble: Order[Double] with Hash[Double] = + cats.kernel.instances.double.catsKernelStdOrderForDouble + implicit def catsKernelInstancesForFloat: Order[Float] with Hash[Float] = + cats.kernel.instances.float.catsKernelStdOrderForFloat + + implicit def catsKernelOrderForOption[A: Order]: Order[Option[A]] = + cats.kernel.instances.option.catsKernelStdOrderForOption[A] + implicit def catsKernelOrderForList[A: Order]: Order[List[A]] = + cats.kernel.instances.list.catsKernelStdOrderForList[A] + implicit def catsKernelOrderForVector[A: Order]: Order[Vector[A]] = + cats.kernel.instances.vector.catsKernelStdOrderForVector[A] + implicit def catsKernelOrderForQueue[A: Order]: Order[Queue[A]] = + cats.kernel.instances.queue.catsKernelStdOrderForQueue[A] + implicit def catsKernelOrderForSortedSet[A: Order]: Order[SortedSet[A]] = + cats.kernel.instances.sortedSet.catsKernelStdOrderForSortedSet[A] + implicit def catsKernelOrderForFunction0[A: Order]: Order[() => A] = + cats.kernel.instances.function.catsKernelOrderForFunction0[A] + + /** + * you may wish to do equality by making `implicit val eqT: Eq[Throwable] = Eq.allEqual` + * doing a fine grained equality on Throwable can make the code very execution + * order dependent + */ + implicit def catsStdEqForTry[A, T](implicit A: Eq[A], T: Eq[Throwable]): Eq[Try[A]] = + new Eq[Try[A]] { + def eqv(x: Try[A], y: Try[A]): Boolean = (x, y) match { + case (Success(a), Success(b)) => A.eqv(a, b) + case (Failure(a), Failure(b)) => T.eqv(a, b) + case _ => false + } + } +} + +private[kernel] trait PartialOrderInstances extends HashInstances { + implicit def catsKernelPartialOrderForOption[A: PartialOrder]: PartialOrder[Option[A]] = + cats.kernel.instances.option.catsKernelStdPartialOrderForOption[A] + implicit def catsKernelPartialOrderForList[A: PartialOrder]: PartialOrder[List[A]] = + cats.kernel.instances.list.catsKernelStdPartialOrderForList[A] + implicit def catsKernelPartialOrderForVector[A: PartialOrder]: PartialOrder[Vector[A]] = + cats.kernel.instances.vector.catsKernelStdPartialOrderForVector[A] + implicit def catsKernelPartialOrderForQueue[A: PartialOrder]: PartialOrder[Queue[A]] = + cats.kernel.instances.queue.catsKernelStdPartialOrderForQueue[A] + implicit def catsKernelPartialOrderForFunction0[A: PartialOrder]: PartialOrder[() => A] = + cats.kernel.instances.function.catsKernelPartialOrderForFunction0[A] +} + +private[kernel] trait HashInstances extends EqInstances { + implicit def catsKernelHashForSet[A]: Hash[Set[A]] = cats.kernel.instances.set.catsKernelStdHashForSet[A] + implicit def catsKernelHashForOption[A: Hash]: Hash[Option[A]] = + cats.kernel.instances.option.catsKernelStdHashForOption[A] + implicit def catsKernelHashForList[A: Hash]: Hash[List[A]] = cats.kernel.instances.list.catsKernelStdHashForList[A] + implicit def catsKernelHashForVector[A: Hash]: Hash[Vector[A]] = + cats.kernel.instances.vector.catsKernelStdHashForVector[A] + implicit def catsKernelHashForQueue[A: Hash]: Hash[Queue[A]] = + cats.kernel.instances.queue.catsKernelStdHashForQueue[A] + implicit def catsKernelHashForSortedSet[A: Hash]: Hash[SortedSet[A]] = + cats.kernel.instances.sortedSet.catsKernelStdHashForSortedSet[A](Hash[A]) + implicit def catsKernelHashForFunction0[A: Hash]: Hash[() => A] = + cats.kernel.instances.function.catsKernelHashForFunction0[A] + implicit def catsKernelHashForMap[K: Hash, V: Hash]: Hash[Map[K, V]] = + cats.kernel.instances.map.catsKernelStdHashForMap[K, V] + implicit def catsKernelHashForSortedMap[K: Order: Hash, V: Hash]: Hash[SortedMap[K, V]] = + cats.kernel.instances.sortedMap.catsKernelStdHashForSortedMap[K, V] + implicit def catsKernelHashForEither[A: Hash, B: Hash]: Hash[Either[A, B]] = + cats.kernel.instances.either.catsStdHashForEither[A, B] +} + +private[kernel] trait EqInstances { + implicit def catsKernelEqForOption[A: Eq]: Eq[Option[A]] = cats.kernel.instances.option.catsKernelStdEqForOption[A] + implicit def catsKernelEqForList[A: Eq]: Eq[List[A]] = cats.kernel.instances.list.catsKernelStdEqForList[A] + implicit def catsKernelEqForVector[A: Eq]: Eq[Vector[A]] = cats.kernel.instances.vector.catsKernelStdEqForVector[A] + implicit def catsKernelEqForQueue[A: Eq]: Eq[Queue[A]] = cats.kernel.instances.queue.catsKernelStdEqForQueue[A] + implicit def catsKernelEqForFunction0[A: Eq]: Eq[() => A] = cats.kernel.instances.function.catsKernelEqForFunction0[A] + implicit def catsKernelEqForMap[K, V: Eq]: Eq[Map[K, V]] = cats.kernel.instances.map.catsKernelStdEqForMap[K, V] + implicit def catsKernelEqForSortedMap[K: Order, V: Eq]: Eq[SortedMap[K, V]] = + cats.kernel.instances.sortedMap.catsKernelStdEqForSortedMap[K, V] + implicit def catsKernelEqForEither[A: Eq, B: Eq]: Eq[Either[A, B]] = + cats.kernel.instances.either.catsStdEqForEither[A, B] } diff --git a/kernel/src/main/scala/cats/kernel/Semigroup.scala b/kernel/src/main/scala/cats/kernel/Semigroup.scala index 2628eb21c2..d0b8c94d61 100644 --- a/kernel/src/main/scala/cats/kernel/Semigroup.scala +++ b/kernel/src/main/scala/cats/kernel/Semigroup.scala @@ -1,7 +1,10 @@ package cats.kernel -import scala.{specialized => sp} import scala.annotation.tailrec +import scala.collection.immutable.{BitSet, Queue, SortedMap, SortedSet} +import scala.concurrent.duration.{Duration, FiniteDuration} +import scala.{specialized => sp} +import scala.util.{Failure, Success, Try} import compat.scalaVersionSpecific._ /** @@ -130,7 +133,11 @@ abstract class SemigroupFunctions[S[T] <: Semigroup[T]] { ev.combineAllOption(as) } -object Semigroup extends SemigroupFunctions[Semigroup] { +object Semigroup + extends SemigroupFunctions[Semigroup] + with ScalaVersionSpecificMonoidInstances + with instances.TupleCommutativeGroupInstances + with GroupInstances { /** * Access an implicit `Semigroup[A]`. @@ -143,4 +150,131 @@ object Semigroup extends SemigroupFunctions[Semigroup] { @inline def instance[A](cmb: (A, A) => A): Semigroup[A] = new Semigroup[A] { override def combine(x: A, y: A): A = cmb(x, y) } + + implicit def catsKernelBoundedSemilatticeForBitSet: BoundedSemilattice[BitSet] = + cats.kernel.instances.bitSet.catsKernelStdSemilatticeForBitSet + implicit def catsKernelInstancesForUnit: BoundedSemilattice[Unit] with CommutativeGroup[Unit] = + cats.kernel.instances.unit.catsKernelStdAlgebraForUnit + implicit def catsKernelCommutativeGroupForByte: CommutativeGroup[Byte] = + cats.kernel.instances.byte.catsKernelStdGroupForByte + implicit def catsKernelCommutativeGroupForShort: CommutativeGroup[Short] = + cats.kernel.instances.short.catsKernelStdGroupForShort + implicit def catsKernelCommutativeGroupForInt: CommutativeGroup[Int] = + cats.kernel.instances.int.catsKernelStdGroupForInt + implicit def catsKernelCommutativeGroupForLong: CommutativeGroup[Long] = + cats.kernel.instances.long.catsKernelStdGroupForLong + implicit def catsKernelCommutativeGroupForBigInt: CommutativeGroup[BigInt] = + cats.kernel.instances.bigInt.catsKernelStdGroupForBigInt + implicit def catsKernelCommutativeGroupForBigDecimal: CommutativeGroup[BigDecimal] = + cats.kernel.instances.bigDecimal.catsKernelStdGroupForBigDecimal + implicit def catsKernelCommutativeGroupForDuration: CommutativeGroup[Duration] = + cats.kernel.instances.duration.catsKernelStdGroupForDuration + implicit def catsKernelCommutativeGroupForFiniteDuration: CommutativeGroup[FiniteDuration] = + cats.kernel.instances.all.catsKernelStdGroupForFiniteDuration + implicit def catsKernelCommutativeGroupForDouble: CommutativeGroup[Double] = + cats.kernel.instances.double.catsKernelStdGroupForDouble + implicit def catsKernelCommutativeGroupForFloat: CommutativeGroup[Float] = + cats.kernel.instances.float.catsKernelStdGroupForFloat + + implicit def catsKernelMonoidForString: Monoid[String] = cats.kernel.instances.string.catsKernelStdMonoidForString + + implicit def catsKernelMonoidForOption[A: Semigroup]: Monoid[Option[A]] = + cats.kernel.instances.option.catsKernelStdMonoidForOption[A] + implicit def catsKernelMonoidForList[A]: Monoid[List[A]] = cats.kernel.instances.list.catsKernelStdMonoidForList[A] + implicit def catsKernelMonoidForVector[A]: Monoid[Vector[A]] = + cats.kernel.instances.vector.catsKernelStdMonoidForVector[A] + implicit def catsKernelMonoidForQueue[A]: Monoid[Queue[A]] = + cats.kernel.instances.queue.catsKernelStdMonoidForQueue[A] + + implicit def catsKernelCommutativeGroupForFunction0[A: CommutativeGroup]: CommutativeGroup[() => A] = + cats.kernel.instances.function.catsKernelCommutativeGroupForFunction0[A] + implicit def catsKernelCommutativeGroupForFunction1[A, B: CommutativeGroup]: CommutativeGroup[A => B] = + cats.kernel.instances.function.catsKernelCommutativeGroupForFunction1[A, B] + + implicit def catsKernelBoundedSemilatticeForSet[A]: BoundedSemilattice[Set[A]] = + cats.kernel.instances.set.catsKernelStdSemilatticeForSet[A] + implicit def catsKernelBoundedSemilatticeForSortedSet[A: Order]: BoundedSemilattice[SortedSet[A]] = + cats.kernel.instances.sortedSet.catsKernelStdBoundedSemilatticeForSortedSet[A] + + implicit def catsKernelCommutativeMonoidForMap[K, V: CommutativeSemigroup]: CommutativeMonoid[Map[K, V]] = + cats.kernel.instances.map.catsKernelStdCommutativeMonoidForMap[K, V] + implicit def catsKernelCommutativeMonoidForSortedMap[K: Order, V: CommutativeSemigroup] + : CommutativeMonoid[SortedMap[K, V]] = + cats.kernel.instances.sortedMap.catsKernelStdCommutativeMonoidForSortedMap[K, V] +} + +private[kernel] trait GroupInstances extends BoundedSemilatticeInstances { + implicit def catsKernelGroupForFunction0[A: Group]: Group[() => A] = + cats.kernel.instances.function.catsKernelGroupForFunction0[A] + implicit def catsKernelGroupForFunction1[A, B: Group]: Group[A => B] = + cats.kernel.instances.function.catsKernelGroupForFunction1[A, B] +} + +private[kernel] trait BoundedSemilatticeInstances extends SemilatticeInstances { + implicit def catsKernelBoundedSemilatticeForFunction0[A: BoundedSemilattice]: BoundedSemilattice[() => A] = + cats.kernel.instances.function.catsKernelBoundedSemilatticeForFunction0[A] + implicit def catsKernelBoundedSemilatticeForFunction1[A, B: BoundedSemilattice]: BoundedSemilattice[A => B] = + cats.kernel.instances.function.catsKernelBoundedSemilatticeForFunction1[A, B] +} + +private[kernel] trait SemilatticeInstances extends CommutativeMonoidInstances { + implicit def catsKernelSemilatticeForFunction0[A: Semilattice]: Semilattice[() => A] = + cats.kernel.instances.function.catsKernelSemilatticeForFunction0[A] + implicit def catsKernelSemilatticeForFunction1[A, B: Semilattice]: Semilattice[A => B] = + cats.kernel.instances.function.catsKernelSemilatticeForFunction1[A, B] +} + +private[kernel] trait CommutativeMonoidInstances extends MonoidInstances { + implicit def catsKernelCommutativeMonoidForFunction0[A: CommutativeMonoid]: CommutativeMonoid[() => A] = + cats.kernel.instances.function.catsKernelCommutativeMonoidForFunction0[A] + implicit def catsKernelCommutativeMonoidForFunction1[A, B: CommutativeMonoid]: CommutativeMonoid[A => B] = + cats.kernel.instances.function.catsKernelCommutativeMonoidForFunction1[A, B] +} + +private[kernel] trait MonoidInstances extends BandInstances { + implicit def catsKernelMonoidForFunction0[A: Monoid]: Monoid[() => A] = + cats.kernel.instances.function.catsKernelMonoidForFunction0[A] + implicit def catsKernelMonoidForFunction1[A, B: Monoid]: Monoid[A => B] = + cats.kernel.instances.function.catsKernelMonoidForFunction1[A, B] + implicit def catsKernelMonoidForSortedMap[K: Order, V: Semigroup]: Monoid[SortedMap[K, V]] = + cats.kernel.instances.sortedMap.catsKernelStdMonoidForSortedMap[K, V] + implicit def catsKernelMonoidForEither[A, B: Monoid]: Monoid[Either[A, B]] = + cats.kernel.instances.either.catsDataMonoidForEither[A, B] + implicit def catsKernelMonoidForTry[A: Monoid]: Monoid[Try[A]] = new TryMonoid[A](Monoid[A]) +} + +private[kernel] trait BandInstances extends CommutativeSemigroupInstances { + implicit def catsKernelBandForFunction0[A: Band]: Band[() => A] = + cats.kernel.instances.function.catsKernelBandForFunction0[A] + implicit def catsKernelBandForFunction1[A, B: Band]: Band[A => B] = + cats.kernel.instances.function.catsKernelBandForFunction1[A, B] +} + +private[kernel] trait CommutativeSemigroupInstances extends SemigroupInstances { + implicit def catsKernelCommutativeSemigroupForFunction0[A: CommutativeSemigroup]: CommutativeSemigroup[() => A] = + cats.kernel.instances.function.catsKernelCommutativeSemigroupForFunction0[A] + implicit def catsKernelCommutativeSemigroupForFunction1[A, B: CommutativeSemigroup]: CommutativeSemigroup[A => B] = + cats.kernel.instances.function.catsKernelCommutativeSemigroupForFunction1[A, B] +} + +private[kernel] trait SemigroupInstances { + implicit def catsKernelSemigroupForFunction0[A: Semigroup]: Semigroup[() => A] = + cats.kernel.instances.function.catsKernelSemigroupForFunction0[A] + implicit def catsKernelSemigroupForFunction1[A, B: Semigroup]: Semigroup[A => B] = + cats.kernel.instances.function.catsKernelSemigroupForFunction1[A, B] + implicit def catsKernelSemigroupForEither[A, B: Semigroup]: Semigroup[Either[A, B]] = + cats.kernel.instances.either.catsDataSemigroupForEither[A, B] + implicit def catsKernelSemigroupForTry[A: Semigroup]: Semigroup[Try[A]] = new TrySemigroup[A](Semigroup[A]) +} + +private class TryMonoid[A](A: Monoid[A]) extends TrySemigroup[A](A) with Monoid[Try[A]] { + def empty: Try[A] = Success(A.empty) +} + +private class TrySemigroup[A](A: Semigroup[A]) extends Semigroup[Try[A]] { + def combine(x: Try[A], y: Try[A]): Try[A] = (x, y) match { + case (Success(xv), Success(yv)) => Success(A.combine(xv, yv)) + case (f @ Failure(_), _) => f + case (_, f) => f + } } diff --git a/project/KernelBoiler.scala b/project/KernelBoiler.scala index 105e12dba3..304d485be7 100644 --- a/project/KernelBoiler.scala +++ b/project/KernelBoiler.scala @@ -255,6 +255,194 @@ object KernelBoiler { } """ } + ), + InstanceDef( + "private[kernel] trait TupleBandInstances extends TupleSemigroupInstances {", + tv => + new TemplatedBlock(tv) { + import tv._ + def content = + block""" + implicit def catsKernelBandForTuple${arity}[${`A..N`}](implicit ${constraints("Band")}): Band[${`(A..N)`}] = new Band[${`(A..N)`}] { + def combine(x: ${`(A..N)`}, y: ${`(A..N)`}): ${`(A..N)`} = ${binTuple("combine")} + } + """ + } + ), + InstanceDef( + "private[kernel] trait TupleBoundedSemilatticeInstances extends TupleGroupInstances {", + tv => + new TemplatedBlock(tv) { + import tv._ + def content = + block""" + implicit def catsKernelBoundedSemilatticeForTuple${arity}[${`A..N`}](implicit ${constraints( + "BoundedSemilattice" + )}): BoundedSemilattice[${`(A..N)`}] = new BoundedSemilattice[${`(A..N)`}] { + def combine(x: ${`(A..N)`}, y: ${`(A..N)`}): ${`(A..N)`} = ${binTuple("combine")} + def empty: ${`(A..N)`} = ${nullaryTuple("empty")} + } + """ + } + ), + InstanceDef( + "private[kernel] trait TupleCommutativeGroupInstances extends TupleBoundedSemilatticeInstances {", + tv => + new TemplatedBlock(tv) { + import tv._ + def content = + block""" + implicit def catsKernelCommutativeGroupForTuple${arity}[${`A..N`}](implicit ${constraints( + "CommutativeGroup" + )}): CommutativeGroup[${`(A..N)`}] = new CommutativeGroup[${`(A..N)`}] { + def combine(x: ${`(A..N)`}, y: ${`(A..N)`}): ${`(A..N)`} = ${binTuple("combine")} + def empty: ${`(A..N)`} = ${nullaryTuple("empty")} + def inverse(x: ${`(A..N)`}): ${`(A..N)`} = ${unaryTuple("inverse")} + } + """ + } + ), + InstanceDef( + "private[kernel] trait TupleCommutativeMonoidInstances extends TupleSemilatticeInstances {", + tv => + new TemplatedBlock(tv) { + import tv._ + def content = + block""" + implicit def catsKernelCommutativeMonoidForTuple${arity}[${`A..N`}](implicit ${constraints( + "CommutativeMonoid" + )}): CommutativeMonoid[${`(A..N)`}] = new CommutativeMonoid[${`(A..N)`}] { + def combine(x: ${`(A..N)`}, y: ${`(A..N)`}): ${`(A..N)`} = ${binTuple("combine")} + def empty: ${`(A..N)`} = ${nullaryTuple("empty")} + } + """ + } + ), + InstanceDef( + "private[kernel] trait TupleCommutativeSemigroupInstances extends TupleBandInstances {", + tv => + new TemplatedBlock(tv) { + import tv._ + def content = + block""" + implicit def catsKernelCommutativeSemigroupForTuple${arity}[${`A..N`}](implicit ${constraints( + "CommutativeSemigroup" + )}): CommutativeSemigroup[${`(A..N)`}] = new CommutativeSemigroup[${`(A..N)`}] { + def combine(x: ${`(A..N)`}, y: ${`(A..N)`}): ${`(A..N)`} = ${binTuple("combine")} + } + """ + } + ), + InstanceDef( + "private[kernel] trait TupleEqInstances {", + tv => + new TemplatedBlock(tv) { + import tv._ + def content = + block""" + implicit def catsKernelEqForTuple${arity}[${`A..N`}](implicit ${constraints("Eq")}): Eq[${`(A..N)`}] = new Eq[${`(A..N)`}] { + def eqv(x: ${`(A..N)`}, y: ${`(A..N)`}): Boolean = ${binMethod("eqv").mkString(" && ")} + } + """ + } + ), + InstanceDef( + "private[kernel] trait TupleGroupInstances extends TupleCommutativeMonoidInstances {", + tv => + new TemplatedBlock(tv) { + import tv._ + def content = + block""" + implicit def catsKernelGroupForTuple${arity}[${`A..N`}](implicit ${constraints("Group")}): Group[${`(A..N)`}] = new Group[${`(A..N)`}] { + def combine(x: ${`(A..N)`}, y: ${`(A..N)`}): ${`(A..N)`} = ${binTuple("combine")} + def empty: ${`(A..N)`} = ${nullaryTuple("empty")} + def inverse(x: ${`(A..N)`}): ${`(A..N)`} = ${unaryTuple("inverse")} + } + """ + } + ), + InstanceDef( + "private[kernel] trait TupleHashInstances extends TupleEqInstances {", + tv => + new TemplatedBlock(tv) { + import tv._ + def content = + block""" + implicit def catsKernelHashForTuple${arity}[${`A..N`}](implicit ${constraints("Hash")}): Hash[${`(A..N)`}] = new Hash[${`(A..N)`}] { + def hash(x: ${`(A..N)`}): Int = ${unaryMethod("hash") + .mkString(s"$tupleNHeader(", ", ", ")")}.hashCode() + def eqv(x: ${`(A..N)`}, y: ${`(A..N)`}): Boolean = ${binMethod("eqv").mkString(" && ")} + } + """ + } + ), + InstanceDef( + "private[kernel] trait TupleMonoidInstances extends TupleCommutativeSemigroupInstances {", + tv => + new TemplatedBlock(tv) { + import tv._ + def content = + block""" + implicit def catsKernelMonoidForTuple${arity}[${`A..N`}](implicit ${constraints("Monoid")}): Monoid[${`(A..N)`}] = new Monoid[${`(A..N)`}] { + def combine(x: ${`(A..N)`}, y: ${`(A..N)`}): ${`(A..N)`} = ${binTuple("combine")} + def empty: ${`(A..N)`} = ${nullaryTuple("empty")} + } + """ + } + ), + InstanceDef( + "private[kernel] trait TupleOrderInstances extends TuplePartialOrderInstances {", + tv => + new TemplatedBlock(tv) { + import tv._ + def content = + block""" + implicit def catsKernelOrderForTuple${arity}[${`A..N`}](implicit ${constraints("Order")}): Order[${`(A..N)`}] = new Order[${`(A..N)`}] { + def compare(x: ${`(A..N)`}, y: ${`(A..N)`}): Int = + ${binMethod("compare").mkString("Array(", ", ", ")")}.find(_ != 0).getOrElse(0) + } + """ + } + ), + InstanceDef( + "private[kernel] trait TuplePartialOrderInstances extends TupleHashInstances {", + tv => + new TemplatedBlock(tv) { + import tv._ + def content = + block""" + implicit def catsKernelPartialOrderForTuple${arity}[${`A..N`}](implicit ${constraints("PartialOrder")}): PartialOrder[${`(A..N)`}] = new PartialOrder[${`(A..N)`}] { + def partialCompare(x: ${`(A..N)`}, y: ${`(A..N)`}): Double = + ${binMethod("partialCompare").mkString("Array(", ", ", ")")}.find(_ != 0.0).getOrElse(0.0) + } + """ + } + ), + InstanceDef( + "private[kernel] trait TupleSemigroupInstances {", + tv => + new TemplatedBlock(tv) { + import tv._ + def content = + block""" + implicit def catsKernelSemigroupForTuple${arity}[${`A..N`}](implicit ${constraints("Semigroup")}): Semigroup[${`(A..N)`}] = new Semigroup[${`(A..N)`}] { + def combine(x: ${`(A..N)`}, y: ${`(A..N)`}): ${`(A..N)`} = ${binTuple("combine")} + } + """ + } + ), + InstanceDef( + "private[kernel] trait TupleSemilatticeInstances extends TupleMonoidInstances {", + tv => + new TemplatedBlock(tv) { + import tv._ + def content = + block""" + implicit def catsKernelSemilatticeForTuple${arity}[${`A..N`}](implicit ${constraints("Semilattice")}): Semilattice[${`(A..N)`}] = new Semilattice[${`(A..N)`}] { + def combine(x: ${`(A..N)`}, y: ${`(A..N)`}): ${`(A..N)`} = ${binTuple("combine")} + } + """ + } ) ) }