From a891d38104bfcc585b22a2c8ed65602fb4e13155 Mon Sep 17 00:00:00 2001 From: Travis Brown Date: Wed, 11 Mar 2020 07:21:54 -0500 Subject: [PATCH] Run Simulacrum Scalafix rules and format --- .../src/main/scala/alleycats/ConsK.scala | 43 ++++++++- .../src/main/scala/alleycats/Empty.scala | 45 ++++++++- .../src/main/scala/alleycats/EmptyK.scala | 46 ++++++++- .../src/main/scala/alleycats/Extract.scala | 44 ++++++++- .../src/main/scala/alleycats/One.scala | 45 ++++++++- .../src/main/scala/alleycats/Pure.scala | 43 ++++++++- .../src/main/scala/alleycats/Zero.scala | 45 ++++++++- core/src/main/scala/cats/Align.scala | 49 +++++++++- core/src/main/scala/cats/Alternative.scala | 52 ++++++++++ core/src/main/scala/cats/Applicative.scala | 42 ++++++++ core/src/main/scala/cats/Apply.scala | 55 +++++++++++ core/src/main/scala/cats/Bifoldable.scala | 52 +++++++++- core/src/main/scala/cats/Bifunctor.scala | 49 +++++++++- core/src/main/scala/cats/Bimonad.scala | 46 +++++++++ core/src/main/scala/cats/Bitraverse.scala | 50 ++++++++++ core/src/main/scala/cats/CoflatMap.scala | 48 ++++++++++ .../scala/cats/CommutativeApplicative.scala | 45 +++++++++ .../main/scala/cats/CommutativeApply.scala | 43 +++++++++ .../main/scala/cats/CommutativeFlatMap.scala | 46 +++++++++ .../main/scala/cats/CommutativeMonad.scala | 50 ++++++++++ core/src/main/scala/cats/Comonad.scala | 47 +++++++++ core/src/main/scala/cats/Contravariant.scala | 48 ++++++++++ .../scala/cats/ContravariantMonoidal.scala | 48 ++++++++++ .../scala/cats/ContravariantSemigroupal.scala | 47 +++++++++ core/src/main/scala/cats/Distributive.scala | 46 +++++++++ core/src/main/scala/cats/FlatMap.scala | 52 ++++++++++ core/src/main/scala/cats/Foldable.scala | 95 +++++++++++++++++++ core/src/main/scala/cats/Functor.scala | 54 +++++++++++ core/src/main/scala/cats/FunctorFilter.scala | 50 ++++++++++ core/src/main/scala/cats/Invariant.scala | 44 ++++++++- .../main/scala/cats/InvariantMonoidal.scala | 43 +++++++++ .../scala/cats/InvariantSemigroupal.scala | 45 +++++++++ core/src/main/scala/cats/Monad.scala | 51 ++++++++++ core/src/main/scala/cats/MonoidK.scala | 46 +++++++++ .../main/scala/cats/NonEmptyTraverse.scala | 54 +++++++++++ core/src/main/scala/cats/Reducible.scala | 73 ++++++++++++++ core/src/main/scala/cats/SemigroupK.scala | 46 ++++++++- core/src/main/scala/cats/Semigroupal.scala | 47 ++++++++- core/src/main/scala/cats/Traverse.scala | 62 ++++++++++++ core/src/main/scala/cats/TraverseFilter.scala | 52 ++++++++++ .../main/scala/cats/UnorderedFoldable.scala | 51 +++++++++- .../main/scala/cats/UnorderedTraverse.scala | 50 ++++++++++ core/src/main/scala/cats/arrow/Arrow.scala | 50 ++++++++++ .../main/scala/cats/arrow/ArrowChoice.scala | 50 ++++++++++ core/src/main/scala/cats/arrow/Category.scala | 46 +++++++++ core/src/main/scala/cats/arrow/Choice.scala | 48 ++++++++++ .../scala/cats/arrow/CommutativeArrow.scala | 48 ++++++++++ core/src/main/scala/cats/arrow/Compose.scala | 50 +++++++++- .../main/scala/cats/arrow/Profunctor.scala | 49 +++++++++- core/src/main/scala/cats/arrow/Strong.scala | 48 ++++++++++ 50 files changed, 2461 insertions(+), 17 deletions(-) diff --git a/alleycats-core/src/main/scala/alleycats/ConsK.scala b/alleycats-core/src/main/scala/alleycats/ConsK.scala index b0fac0b0fe..71a5a38929 100644 --- a/alleycats-core/src/main/scala/alleycats/ConsK.scala +++ b/alleycats-core/src/main/scala/alleycats/ConsK.scala @@ -2,8 +2,10 @@ package alleycats import cats.SemigroupK import simulacrum.typeclass +import scala.annotation.implicitNotFound -@typeclass trait ConsK[F[_]] { +@implicitNotFound("Could not find an instance of ConsK for ${F}") +@typeclass trait ConsK[F[_]] extends Serializable { def cons[A](hd: A, tl: F[A]): F[A] } @@ -12,4 +14,43 @@ object ConsK { new ConsK[F] { def cons[A](hd: A, tl: F[A]): F[A] = s.combineK(p.pure(hd), tl) } + + /****************************************************************************/ + /* THE FOLLOWING CODE IS MANAGED BY SIMULACRUM; PLEASE DO NOT EDIT!!!! */ + /****************************************************************************/ + /** + * Summon an instance of [[ConsK]] for `F`. + */ + @inline def apply[F[_]](implicit instance: ConsK[F]): ConsK[F] = instance + + trait Ops[F[_], A] { + type TypeClassType <: ConsK[F] + def self: F[A] + val typeClassInstance: TypeClassType + } + trait AllOps[F[_], A] extends Ops[F, A] + trait ToConsKOps { + implicit def toConsKOps[F[_], A](target: F[A])(implicit tc: ConsK[F]): Ops[F, A] { + type TypeClassType = ConsK[F] + } = new Ops[F, A] { + type TypeClassType = ConsK[F] + val self: F[A] = target + val typeClassInstance: TypeClassType = tc + } + } + object nonInheritedOps extends ToConsKOps + object ops { + implicit def toAllConsKOps[F[_], A](target: F[A])(implicit tc: ConsK[F]): AllOps[F, A] { + type TypeClassType = ConsK[F] + } = new AllOps[F, A] { + type TypeClassType = ConsK[F] + val self: F[A] = target + val typeClassInstance: TypeClassType = tc + } + } + + /****************************************************************************/ + /* END OF SIMULACRUM-MANAGED CODE */ + /****************************************************************************/ + } diff --git a/alleycats-core/src/main/scala/alleycats/Empty.scala b/alleycats-core/src/main/scala/alleycats/Empty.scala index bfb8fa40d8..698e49b4f2 100644 --- a/alleycats-core/src/main/scala/alleycats/Empty.scala +++ b/alleycats-core/src/main/scala/alleycats/Empty.scala @@ -4,8 +4,10 @@ import cats.{Eq, Monoid} import cats.syntax.eq._ import simulacrum.typeclass +import scala.annotation.implicitNotFound -@typeclass trait Empty[A] { +@implicitNotFound("Could not find an instance of Empty for ${A}") +@typeclass trait Empty[A] extends Serializable { def empty: A def isEmpty(a: A)(implicit ev: Eq[A]): Boolean = @@ -20,6 +22,47 @@ object Empty extends EmptyInstances0 { new Empty[A] { lazy val empty: A = a } def fromEmptyK[F[_], T](implicit ekf: EmptyK[F]): Empty[F[T]] = ekf.synthesize[T] + + /****************************************************************************/ + /* THE FOLLOWING CODE IS MANAGED BY SIMULACRUM; PLEASE DO NOT EDIT!!!! */ + /****************************************************************************/ + /** + * Summon an instance of [[Empty]] for `A`. + */ + @inline def apply[A](implicit instance: Empty[A]): Empty[A] = instance + + trait Ops[A] { + type TypeClassType <: Empty[A] + def self: A + val typeClassInstance: TypeClassType + def isEmpty(implicit ev: Eq[A]): Boolean = typeClassInstance.isEmpty(self)(ev) + def nonEmpty(implicit ev: Eq[A]): Boolean = typeClassInstance.nonEmpty(self)(ev) + } + trait AllOps[A] extends Ops[A] + trait ToEmptyOps { + implicit def toEmptyOps[A](target: A)(implicit tc: Empty[A]): Ops[A] { + type TypeClassType = Empty[A] + } = new Ops[A] { + type TypeClassType = Empty[A] + val self: A = target + val typeClassInstance: TypeClassType = tc + } + } + object nonInheritedOps extends ToEmptyOps + object ops { + implicit def toAllEmptyOps[A](target: A)(implicit tc: Empty[A]): AllOps[A] { + type TypeClassType = Empty[A] + } = new AllOps[A] { + type TypeClassType = Empty[A] + val self: A = target + val typeClassInstance: TypeClassType = tc + } + } + + /****************************************************************************/ + /* END OF SIMULACRUM-MANAGED CODE */ + /****************************************************************************/ + } private[alleycats] trait EmptyInstances0 extends compat.IterableEmptyInstance with EmptyInstances1 diff --git a/alleycats-core/src/main/scala/alleycats/EmptyK.scala b/alleycats-core/src/main/scala/alleycats/EmptyK.scala index 8854e1c64a..2a809b9c7e 100644 --- a/alleycats-core/src/main/scala/alleycats/EmptyK.scala +++ b/alleycats-core/src/main/scala/alleycats/EmptyK.scala @@ -1,8 +1,10 @@ package alleycats import simulacrum.typeclass +import scala.annotation.implicitNotFound -@typeclass trait EmptyK[F[_]] { self => +@implicitNotFound("Could not find an instance of EmptyK for ${F}") +@typeclass trait EmptyK[F[_]] extends Serializable { self => def empty[A]: F[A] def synthesize[A]: Empty[F[A]] = @@ -10,3 +12,45 @@ import simulacrum.typeclass def empty: F[A] = self.empty[A] } } + +object EmptyK { + + /****************************************************************************/ + /* THE FOLLOWING CODE IS MANAGED BY SIMULACRUM; PLEASE DO NOT EDIT!!!! */ + /****************************************************************************/ + /** + * Summon an instance of [[EmptyK]] for `F`. + */ + @inline def apply[F[_]](implicit instance: EmptyK[F]): EmptyK[F] = instance + + trait Ops[F[_], A] { + type TypeClassType <: EmptyK[F] + def self: F[A] + val typeClassInstance: TypeClassType + } + trait AllOps[F[_], A] extends Ops[F, A] + trait ToEmptyKOps { + implicit def toEmptyKOps[F[_], A](target: F[A])(implicit tc: EmptyK[F]): Ops[F, A] { + type TypeClassType = EmptyK[F] + } = new Ops[F, A] { + type TypeClassType = EmptyK[F] + val self: F[A] = target + val typeClassInstance: TypeClassType = tc + } + } + object nonInheritedOps extends ToEmptyKOps + object ops { + implicit def toAllEmptyKOps[F[_], A](target: F[A])(implicit tc: EmptyK[F]): AllOps[F, A] { + type TypeClassType = EmptyK[F] + } = new AllOps[F, A] { + type TypeClassType = EmptyK[F] + val self: F[A] = target + val typeClassInstance: TypeClassType = tc + } + } + + /****************************************************************************/ + /* END OF SIMULACRUM-MANAGED CODE */ + /****************************************************************************/ + +} diff --git a/alleycats-core/src/main/scala/alleycats/Extract.scala b/alleycats-core/src/main/scala/alleycats/Extract.scala index 04b0f72750..808ae60506 100644 --- a/alleycats-core/src/main/scala/alleycats/Extract.scala +++ b/alleycats-core/src/main/scala/alleycats/Extract.scala @@ -3,8 +3,10 @@ package alleycats import cats.{CoflatMap, Comonad} import simulacrum.typeclass +import scala.annotation.implicitNotFound -@typeclass trait Extract[F[_]] { +@implicitNotFound("Could not find an instance of Extract for ${F}") +@typeclass trait Extract[F[_]] extends Serializable { def extract[A](fa: F[A]): A } @@ -22,4 +24,44 @@ object Extract { override def map[A, B](fa: F[A])(f: A => B): F[B] = cf.map(fa)(f) def coflatMap[A, B](fa: F[A])(f: F[A] => B): F[B] = cf.coflatMap(fa)(f) } + + /****************************************************************************/ + /* THE FOLLOWING CODE IS MANAGED BY SIMULACRUM; PLEASE DO NOT EDIT!!!! */ + /****************************************************************************/ + /** + * Summon an instance of [[Extract]] for `F`. + */ + @inline def apply[F[_]](implicit instance: Extract[F]): Extract[F] = instance + + trait Ops[F[_], A] { + type TypeClassType <: Extract[F] + def self: F[A] + val typeClassInstance: TypeClassType + def extract: A = typeClassInstance.extract[A](self) + } + trait AllOps[F[_], A] extends Ops[F, A] + trait ToExtractOps { + implicit def toExtractOps[F[_], A](target: F[A])(implicit tc: Extract[F]): Ops[F, A] { + type TypeClassType = Extract[F] + } = new Ops[F, A] { + type TypeClassType = Extract[F] + val self: F[A] = target + val typeClassInstance: TypeClassType = tc + } + } + object nonInheritedOps extends ToExtractOps + object ops { + implicit def toAllExtractOps[F[_], A](target: F[A])(implicit tc: Extract[F]): AllOps[F, A] { + type TypeClassType = Extract[F] + } = new AllOps[F, A] { + type TypeClassType = Extract[F] + val self: F[A] = target + val typeClassInstance: TypeClassType = tc + } + } + + /****************************************************************************/ + /* END OF SIMULACRUM-MANAGED CODE */ + /****************************************************************************/ + } diff --git a/alleycats-core/src/main/scala/alleycats/One.scala b/alleycats-core/src/main/scala/alleycats/One.scala index 19a8bd7f80..a70d39ae6c 100644 --- a/alleycats-core/src/main/scala/alleycats/One.scala +++ b/alleycats-core/src/main/scala/alleycats/One.scala @@ -3,8 +3,10 @@ package alleycats import cats.Eq import cats.syntax.eq._ import simulacrum.typeclass +import scala.annotation.implicitNotFound -@typeclass trait One[A] { +@implicitNotFound("Could not find an instance of One for ${A}") +@typeclass trait One[A] extends Serializable { def one: A def isOne(a: A)(implicit ev: Eq[A]): Boolean = @@ -17,4 +19,45 @@ import simulacrum.typeclass object One { def apply[A](a: => A): One[A] = new One[A] { lazy val one: A = a } + + /****************************************************************************/ + /* THE FOLLOWING CODE IS MANAGED BY SIMULACRUM; PLEASE DO NOT EDIT!!!! */ + /****************************************************************************/ + /** + * Summon an instance of [[One]] for `A`. + */ + @inline def apply[A](implicit instance: One[A]): One[A] = instance + + trait Ops[A] { + type TypeClassType <: One[A] + def self: A + val typeClassInstance: TypeClassType + def isOne(implicit ev: Eq[A]): Boolean = typeClassInstance.isOne(self)(ev) + def nonOne(implicit ev: Eq[A]): Boolean = typeClassInstance.nonOne(self)(ev) + } + trait AllOps[A] extends Ops[A] + trait ToOneOps { + implicit def toOneOps[A](target: A)(implicit tc: One[A]): Ops[A] { + type TypeClassType = One[A] + } = new Ops[A] { + type TypeClassType = One[A] + val self: A = target + val typeClassInstance: TypeClassType = tc + } + } + object nonInheritedOps extends ToOneOps + object ops { + implicit def toAllOneOps[A](target: A)(implicit tc: One[A]): AllOps[A] { + type TypeClassType = One[A] + } = new AllOps[A] { + type TypeClassType = One[A] + val self: A = target + val typeClassInstance: TypeClassType = tc + } + } + + /****************************************************************************/ + /* END OF SIMULACRUM-MANAGED CODE */ + /****************************************************************************/ + } diff --git a/alleycats-core/src/main/scala/alleycats/Pure.scala b/alleycats-core/src/main/scala/alleycats/Pure.scala index 9a8359d01d..cb96acbdc0 100644 --- a/alleycats-core/src/main/scala/alleycats/Pure.scala +++ b/alleycats-core/src/main/scala/alleycats/Pure.scala @@ -2,8 +2,10 @@ package alleycats import cats.{Applicative, FlatMap, Monad} import simulacrum.typeclass +import scala.annotation.implicitNotFound -@typeclass trait Pure[F[_]] { +@implicitNotFound("Could not find an instance of Pure for ${F}") +@typeclass trait Pure[F[_]] extends Serializable { def pure[A](a: A): F[A] } @@ -22,4 +24,43 @@ object Pure { def flatMap[A, B](fa: F[A])(f: A => F[B]): F[B] = fm.flatMap(fa)(f) def tailRecM[A, B](a: A)(f: (A) => F[Either[A, B]]): F[B] = fm.tailRecM(a)(f) } + + /****************************************************************************/ + /* THE FOLLOWING CODE IS MANAGED BY SIMULACRUM; PLEASE DO NOT EDIT!!!! */ + /****************************************************************************/ + /** + * Summon an instance of [[Pure]] for `F`. + */ + @inline def apply[F[_]](implicit instance: Pure[F]): Pure[F] = instance + + trait Ops[F[_], A] { + type TypeClassType <: Pure[F] + def self: F[A] + val typeClassInstance: TypeClassType + } + trait AllOps[F[_], A] extends Ops[F, A] + trait ToPureOps { + implicit def toPureOps[F[_], A](target: F[A])(implicit tc: Pure[F]): Ops[F, A] { + type TypeClassType = Pure[F] + } = new Ops[F, A] { + type TypeClassType = Pure[F] + val self: F[A] = target + val typeClassInstance: TypeClassType = tc + } + } + object nonInheritedOps extends ToPureOps + object ops { + implicit def toAllPureOps[F[_], A](target: F[A])(implicit tc: Pure[F]): AllOps[F, A] { + type TypeClassType = Pure[F] + } = new AllOps[F, A] { + type TypeClassType = Pure[F] + val self: F[A] = target + val typeClassInstance: TypeClassType = tc + } + } + + /****************************************************************************/ + /* END OF SIMULACRUM-MANAGED CODE */ + /****************************************************************************/ + } diff --git a/alleycats-core/src/main/scala/alleycats/Zero.scala b/alleycats-core/src/main/scala/alleycats/Zero.scala index f51ab497ad..80c993c5b4 100644 --- a/alleycats-core/src/main/scala/alleycats/Zero.scala +++ b/alleycats-core/src/main/scala/alleycats/Zero.scala @@ -4,8 +4,10 @@ import cats.Eq import cats.syntax.eq._ import simulacrum.typeclass +import scala.annotation.implicitNotFound -@typeclass trait Zero[A] { +@implicitNotFound("Could not find an instance of Zero for ${A}") +@typeclass trait Zero[A] extends Serializable { def zero: A def isZero(a: A)(implicit ev: Eq[A]): Boolean = @@ -18,4 +20,45 @@ import simulacrum.typeclass object Zero { def apply[A](a: => A): Zero[A] = new Zero[A] { lazy val zero: A = a } + + /****************************************************************************/ + /* THE FOLLOWING CODE IS MANAGED BY SIMULACRUM; PLEASE DO NOT EDIT!!!! */ + /****************************************************************************/ + /** + * Summon an instance of [[Zero]] for `A`. + */ + @inline def apply[A](implicit instance: Zero[A]): Zero[A] = instance + + trait Ops[A] { + type TypeClassType <: Zero[A] + def self: A + val typeClassInstance: TypeClassType + def isZero(implicit ev: Eq[A]): Boolean = typeClassInstance.isZero(self)(ev) + def nonZero(implicit ev: Eq[A]): Boolean = typeClassInstance.nonZero(self)(ev) + } + trait AllOps[A] extends Ops[A] + trait ToZeroOps { + implicit def toZeroOps[A](target: A)(implicit tc: Zero[A]): Ops[A] { + type TypeClassType = Zero[A] + } = new Ops[A] { + type TypeClassType = Zero[A] + val self: A = target + val typeClassInstance: TypeClassType = tc + } + } + object nonInheritedOps extends ToZeroOps + object ops { + implicit def toAllZeroOps[A](target: A)(implicit tc: Zero[A]): AllOps[A] { + type TypeClassType = Zero[A] + } = new AllOps[A] { + type TypeClassType = Zero[A] + val self: A = target + val typeClassInstance: TypeClassType = tc + } + } + + /****************************************************************************/ + /* END OF SIMULACRUM-MANAGED CODE */ + /****************************************************************************/ + } diff --git a/core/src/main/scala/cats/Align.scala b/core/src/main/scala/cats/Align.scala index 3008fb5b37..718f9b4208 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.annotation.implicitNotFound /** * `Align` supports zipping together structures with different shapes, @@ -10,7 +11,8 @@ import cats.data.Ior * * Must obey the laws in cats.laws.AlignLaws */ -@typeclass trait Align[F[_]] { +@implicitNotFound("Could not find an instance of Align for ${F}") +@typeclass trait Align[F[_]] extends Serializable { def functor: Functor[F] @@ -100,4 +102,49 @@ object Align { else Ior.right(iterB.next()) ) } + + /****************************************************************************/ + /* THE FOLLOWING CODE IS MANAGED BY SIMULACRUM; PLEASE DO NOT EDIT!!!! */ + /****************************************************************************/ + /** + * Summon an instance of [[Align]] for `F`. + */ + @inline def apply[F[_]](implicit instance: Align[F]): Align[F] = instance + + trait Ops[F[_], A] { + type TypeClassType <: Align[F] + def self: F[A] + val typeClassInstance: TypeClassType + def align[B](fb: F[B]): F[Ior[A, B]] = typeClassInstance.align[A, B](self, fb) + def alignWith[B, C](fb: F[B])(f: Ior[A, B] => C): F[C] = typeClassInstance.alignWith[A, B, C](self, fb)(f) + def alignCombine(fa2: F[A])(implicit ev$1: Semigroup[A]): F[A] = typeClassInstance.alignCombine[A](self, fa2) + def padZip[B](fb: F[B]): F[(Option[A], Option[B])] = typeClassInstance.padZip[A, B](self, fb) + def padZipWith[B, C](fb: F[B])(f: (Option[A], Option[B]) => C): F[C] = + typeClassInstance.padZipWith[A, B, C](self, fb)(f) + } + trait AllOps[F[_], A] extends Ops[F, A] + trait ToAlignOps { + implicit def toAlignOps[F[_], A](target: F[A])(implicit tc: Align[F]): Ops[F, A] { + type TypeClassType = Align[F] + } = new Ops[F, A] { + type TypeClassType = Align[F] + val self: F[A] = target + val typeClassInstance: TypeClassType = tc + } + } + object nonInheritedOps extends ToAlignOps + object ops { + implicit def toAllAlignOps[F[_], A](target: F[A])(implicit tc: Align[F]): AllOps[F, A] { + type TypeClassType = Align[F] + } = new AllOps[F, A] { + type TypeClassType = Align[F] + val self: F[A] = target + val typeClassInstance: TypeClassType = tc + } + } + + /****************************************************************************/ + /* END OF SIMULACRUM-MANAGED CODE */ + /****************************************************************************/ + } diff --git a/core/src/main/scala/cats/Alternative.scala b/core/src/main/scala/cats/Alternative.scala index be24937a82..3068c9fbde 100644 --- a/core/src/main/scala/cats/Alternative.scala +++ b/core/src/main/scala/cats/Alternative.scala @@ -1,7 +1,9 @@ package cats import simulacrum.typeclass +import scala.annotation.implicitNotFound +@implicitNotFound("Could not find an instance of Alternative for ${F}") @typeclass trait Alternative[F[_]] extends Applicative[F] with MonoidK[F] { self => /** @@ -87,3 +89,53 @@ import simulacrum.typeclass val G = Applicative[G] } } + +object Alternative { + + /****************************************************************************/ + /* THE FOLLOWING CODE IS MANAGED BY SIMULACRUM; PLEASE DO NOT EDIT!!!! */ + /****************************************************************************/ + /** + * Summon an instance of [[Alternative]] for `F`. + */ + @inline def apply[F[_]](implicit instance: Alternative[F]): Alternative[F] = instance + + trait Ops[F[_], A] { + type TypeClassType <: Alternative[F] + def self: F[A] + val typeClassInstance: TypeClassType + def unite[G[_], B](implicit ev$1: A <:< G[B], FM: Monad[F], G: Foldable[G]): F[B] = + typeClassInstance.unite[G, B](self.asInstanceOf[F[G[B]]])(FM, G) + def separate[G[_, _], B, C](implicit ev$1: A <:< G[B, C], FM: Monad[F], G: Bifoldable[G]): (F[B], F[C]) = + typeClassInstance.separate[G, B, C](self.asInstanceOf[F[G[B, C]]])(FM, G) + def separateFoldable[G[_, _], B, C](implicit ev$1: A <:< G[B, C], G: Bifoldable[G], FF: Foldable[F]): (F[B], F[C]) = + typeClassInstance.separateFoldable[G, B, C](self.asInstanceOf[F[G[B, C]]])(G, FF) + } + trait AllOps[F[_], A] extends Ops[F, A] with Applicative.AllOps[F, A] with MonoidK.AllOps[F, A] { + type TypeClassType <: Alternative[F] + } + trait ToAlternativeOps { + implicit def toAlternativeOps[F[_], A](target: F[A])(implicit tc: Alternative[F]): Ops[F, A] { + type TypeClassType = Alternative[F] + } = new Ops[F, A] { + type TypeClassType = Alternative[F] + val self: F[A] = target + val typeClassInstance: TypeClassType = tc + } + } + object nonInheritedOps extends ToAlternativeOps + object ops { + implicit def toAllAlternativeOps[F[_], A](target: F[A])(implicit tc: Alternative[F]): AllOps[F, A] { + type TypeClassType = Alternative[F] + } = new AllOps[F, A] { + type TypeClassType = Alternative[F] + val self: F[A] = target + val typeClassInstance: TypeClassType = tc + } + } + + /****************************************************************************/ + /* END OF SIMULACRUM-MANAGED CODE */ + /****************************************************************************/ + +} diff --git a/core/src/main/scala/cats/Applicative.scala b/core/src/main/scala/cats/Applicative.scala index 11fb476321..59a0c99ff6 100644 --- a/core/src/main/scala/cats/Applicative.scala +++ b/core/src/main/scala/cats/Applicative.scala @@ -3,6 +3,7 @@ package cats import cats.arrow.Arrow import cats.instances.list._ import simulacrum.typeclass +import scala.annotation.implicitNotFound /** * Applicative functor. @@ -14,6 +15,7 @@ import simulacrum.typeclass * * Must obey the laws defined in cats.laws.ApplicativeLaws. */ +@implicitNotFound("Could not find an instance of Applicative for ${F}") @typeclass trait Applicative[F[_]] extends Apply[F] with InvariantMonoidal[F] { self => /** @@ -229,6 +231,46 @@ object Applicative { def map[A, B](fa: F[A])(f: A => B): F[B] = F.map(fa)(f) } + /****************************************************************************/ + /* THE FOLLOWING CODE IS MANAGED BY SIMULACRUM; PLEASE DO NOT EDIT!!!! */ + /****************************************************************************/ + /** + * Summon an instance of [[Applicative]] for `F`. + */ + @inline def apply[F[_]](implicit instance: Applicative[F]): Applicative[F] = instance + + trait Ops[F[_], A] { + type TypeClassType <: Applicative[F] + def self: F[A] + val typeClassInstance: TypeClassType + } + trait AllOps[F[_], A] extends Ops[F, A] with Apply.AllOps[F, A] with InvariantMonoidal.AllOps[F, A] { + type TypeClassType <: Applicative[F] + } + trait ToApplicativeOps { + implicit def toApplicativeOps[F[_], A](target: F[A])(implicit tc: Applicative[F]): Ops[F, A] { + type TypeClassType = Applicative[F] + } = new Ops[F, A] { + type TypeClassType = Applicative[F] + val self: F[A] = target + val typeClassInstance: TypeClassType = tc + } + } + object nonInheritedOps extends ToApplicativeOps + object ops { + implicit def toAllApplicativeOps[F[_], A](target: F[A])(implicit tc: Applicative[F]): AllOps[F, A] { + type TypeClassType = Applicative[F] + } = new AllOps[F, A] { + type TypeClassType = Applicative[F] + val self: F[A] = target + val typeClassInstance: TypeClassType = tc + } + } + + /****************************************************************************/ + /* END OF SIMULACRUM-MANAGED CODE */ + /****************************************************************************/ + } private[cats] class ApplicativeMonoid[F[_], A](f: Applicative[F], monoid: Monoid[A]) diff --git a/core/src/main/scala/cats/Apply.scala b/core/src/main/scala/cats/Apply.scala index e9dd61e940..db0f042d77 100644 --- a/core/src/main/scala/cats/Apply.scala +++ b/core/src/main/scala/cats/Apply.scala @@ -2,12 +2,14 @@ package cats import simulacrum.{noop, typeclass} import cats.data.Ior +import scala.annotation.implicitNotFound /** * Weaker version of Applicative[F]; has apply but not pure. * * Must obey the laws defined in cats.laws.ApplyLaws. */ +@implicitNotFound("Could not find an instance of Apply for ${F}") @typeclass(excludeParents = List("ApplyArityFunctions")) trait Apply[F[_]] extends Functor[F] with InvariantSemigroupal[F] with ApplyArityFunctions[F] { self => @@ -263,6 +265,59 @@ object Apply { def align[A, B](fa: F[A], fb: F[B]): F[Ior[A, B]] = Apply[F].map2(fa, fb)(Ior.both) def functor: Functor[F] = Apply[F] } + + /****************************************************************************/ + /* THE FOLLOWING CODE IS MANAGED BY SIMULACRUM; PLEASE DO NOT EDIT!!!! */ + /****************************************************************************/ + /** + * Summon an instance of [[Apply]] for `F`. + */ + @inline def apply[F[_]](implicit instance: Apply[F]): Apply[F] = instance + + trait Ops[F[_], A] { + type TypeClassType <: Apply[F] + def self: F[A] + val typeClassInstance: TypeClassType + def ap[B, C](fa: F[B])(implicit ev$1: A <:< (B => C)): F[C] = + typeClassInstance.ap[B, C](self.asInstanceOf[F[B => C]])(fa) + def productR[B](fb: F[B]): F[B] = typeClassInstance.productR[A, B](self)(fb) + def productL[B](fb: F[B]): F[A] = typeClassInstance.productL[A, B](self)(fb) + @inline final def <*>[B, C](fa: F[B])(implicit ev$1: A <:< (B => C)): F[C] = + typeClassInstance.<*>[B, C](self.asInstanceOf[F[B => C]])(fa) + @inline final def *>[B](fb: F[B]): F[B] = typeClassInstance.*>[A, B](self)(fb) + @inline final def <*[B](fb: F[B]): F[A] = typeClassInstance.<*[A, B](self)(fb) + def ap2[B, C, D](fa: F[B], fb: F[C])(implicit ev$1: A <:< ((B, C) => D)): F[D] = + typeClassInstance.ap2[B, C, D](self.asInstanceOf[F[(B, C) => D]])(fa, fb) + def map2[B, C](fb: F[B])(f: (A, B) => C): F[C] = typeClassInstance.map2[A, B, C](self, fb)(f) + def map2Eval[B, C](fb: Eval[F[B]])(f: (A, B) => C): Eval[F[C]] = typeClassInstance.map2Eval[A, B, C](self, fb)(f) + } + trait AllOps[F[_], A] extends Ops[F, A] with Functor.AllOps[F, A] with InvariantSemigroupal.AllOps[F, A] { + type TypeClassType <: Apply[F] + } + trait ToApplyOps { + implicit def toApplyOps[F[_], A](target: F[A])(implicit tc: Apply[F]): Ops[F, A] { + type TypeClassType = Apply[F] + } = new Ops[F, A] { + type TypeClassType = Apply[F] + val self: F[A] = target + val typeClassInstance: TypeClassType = tc + } + } + object nonInheritedOps extends ToApplyOps + object ops { + implicit def toAllApplyOps[F[_], A](target: F[A])(implicit tc: Apply[F]): AllOps[F, A] { + type TypeClassType = Apply[F] + } = new AllOps[F, A] { + type TypeClassType = Apply[F] + val self: F[A] = target + val typeClassInstance: TypeClassType = tc + } + } + + /****************************************************************************/ + /* END OF SIMULACRUM-MANAGED CODE */ + /****************************************************************************/ + } private[cats] class ApplySemigroup[F[_], A](f: Apply[F], sg: Semigroup[A]) extends Semigroup[F[A]] { diff --git a/core/src/main/scala/cats/Bifoldable.scala b/core/src/main/scala/cats/Bifoldable.scala index 4098cbbf27..5c65df0eb8 100644 --- a/core/src/main/scala/cats/Bifoldable.scala +++ b/core/src/main/scala/cats/Bifoldable.scala @@ -1,11 +1,13 @@ package cats import simulacrum.typeclass +import scala.annotation.implicitNotFound /** * A type class abstracting over types that give rise to two independent [[cats.Foldable]]s. */ -@typeclass trait Bifoldable[F[_, _]] { self => +@implicitNotFound("Could not find an instance of Bifoldable for ${F}") +@typeclass trait Bifoldable[F[_, _]] extends Serializable { self => /** Collapse the structure with a left-associative function */ def bifoldLeft[A, B, C](fab: F[A, B], c: C)(f: (C, A) => C, g: (C, B) => C): C @@ -32,6 +34,54 @@ import simulacrum.typeclass } } +object Bifoldable { + + /****************************************************************************/ + /* THE FOLLOWING CODE IS MANAGED BY SIMULACRUM; PLEASE DO NOT EDIT!!!! */ + /****************************************************************************/ + /** + * Summon an instance of [[Bifoldable]] for `F`. + */ + @inline def apply[F[_, _]](implicit instance: Bifoldable[F]): Bifoldable[F] = instance + + trait Ops[F[_, _], A, B] { + type TypeClassType <: Bifoldable[F] + def self: F[A, B] + val typeClassInstance: TypeClassType + def bifoldLeft[C](c: C)(f: (C, A) => C, g: (C, B) => C): C = typeClassInstance.bifoldLeft[A, B, C](self, c)(f, g) + def bifoldRight[C](c: Eval[C])(f: (A, Eval[C]) => Eval[C], g: (B, Eval[C]) => Eval[C]): Eval[C] = + typeClassInstance.bifoldRight[A, B, C](self, c)(f, g) + def bifoldMap[C](f: A => C, g: B => C)(implicit C: Monoid[C]): C = + typeClassInstance.bifoldMap[A, B, C](self)(f, g)(C) + def bifold(implicit A: Monoid[A], B: Monoid[B]): (A, B) = typeClassInstance.bifold[A, B](self)(A, B) + } + trait AllOps[F[_, _], A, B] extends Ops[F, A, B] + trait ToBifoldableOps { + implicit def toBifoldableOps[F[_, _], A, B](target: F[A, B])(implicit tc: Bifoldable[F]): Ops[F, A, B] { + type TypeClassType = Bifoldable[F] + } = new Ops[F, A, B] { + type TypeClassType = Bifoldable[F] + val self: F[A, B] = target + val typeClassInstance: TypeClassType = tc + } + } + object nonInheritedOps extends ToBifoldableOps + object ops { + implicit def toAllBifoldableOps[F[_, _], A, B](target: F[A, B])(implicit tc: Bifoldable[F]): AllOps[F, A, B] { + type TypeClassType = Bifoldable[F] + } = new AllOps[F, A, B] { + type TypeClassType = Bifoldable[F] + val self: F[A, B] = target + val typeClassInstance: TypeClassType = tc + } + } + + /****************************************************************************/ + /* END OF SIMULACRUM-MANAGED CODE */ + /****************************************************************************/ + +} + 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..9ed8656ed1 100644 --- a/core/src/main/scala/cats/Bifunctor.scala +++ b/core/src/main/scala/cats/Bifunctor.scala @@ -1,11 +1,13 @@ package cats import simulacrum.typeclass +import scala.annotation.implicitNotFound /** * A type class of types which give rise to two independent, covariant * functors. */ -@typeclass trait Bifunctor[F[_, _]] { self => +@implicitNotFound("Could not find an instance of Bifunctor for ${F}") +@typeclass trait Bifunctor[F[_, _]] extends Serializable { self => /** * The quintessential method of the Bifunctor trait, it applies a @@ -55,6 +57,51 @@ import simulacrum.typeclass def leftWiden[A, B, AA >: A](fab: F[A, B]): F[AA, B] = fab.asInstanceOf[F[AA, B]] } +object Bifunctor { + + /****************************************************************************/ + /* THE FOLLOWING CODE IS MANAGED BY SIMULACRUM; PLEASE DO NOT EDIT!!!! */ + /****************************************************************************/ + /** + * Summon an instance of [[Bifunctor]] for `F`. + */ + @inline def apply[F[_, _]](implicit instance: Bifunctor[F]): Bifunctor[F] = instance + + trait Ops[F[_, _], A, B] { + type TypeClassType <: Bifunctor[F] + def self: F[A, B] + val typeClassInstance: TypeClassType + def bimap[C, D](f: A => C, g: B => D): F[C, D] = typeClassInstance.bimap[A, B, C, D](self)(f, g) + def leftMap[C](f: A => C): F[C, B] = typeClassInstance.leftMap[A, B, C](self)(f) + def leftWiden[C >: A]: F[C, B] = typeClassInstance.leftWiden[A, B, C](self) + } + trait AllOps[F[_, _], A, B] extends Ops[F, A, B] + trait ToBifunctorOps { + implicit def toBifunctorOps[F[_, _], A, B](target: F[A, B])(implicit tc: Bifunctor[F]): Ops[F, A, B] { + type TypeClassType = Bifunctor[F] + } = new Ops[F, A, B] { + type TypeClassType = Bifunctor[F] + val self: F[A, B] = target + val typeClassInstance: TypeClassType = tc + } + } + object nonInheritedOps extends ToBifunctorOps + object ops { + implicit def toAllBifunctorOps[F[_, _], A, B](target: F[A, B])(implicit tc: Bifunctor[F]): AllOps[F, A, B] { + type TypeClassType = Bifunctor[F] + } = new AllOps[F, A, B] { + type TypeClassType = Bifunctor[F] + val self: F[A, B] = target + val typeClassInstance: TypeClassType = tc + } + } + + /****************************************************************************/ + /* END OF SIMULACRUM-MANAGED CODE */ + /****************************************************************************/ + +} + 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/Bimonad.scala b/core/src/main/scala/cats/Bimonad.scala index cd11549bfe..b41df55c50 100644 --- a/core/src/main/scala/cats/Bimonad.scala +++ b/core/src/main/scala/cats/Bimonad.scala @@ -1,5 +1,51 @@ package cats import simulacrum.typeclass +import scala.annotation.implicitNotFound +@implicitNotFound("Could not find an instance of Bimonad for ${F}") @typeclass trait Bimonad[F[_]] extends Monad[F] with Comonad[F] + +object Bimonad { + + /****************************************************************************/ + /* THE FOLLOWING CODE IS MANAGED BY SIMULACRUM; PLEASE DO NOT EDIT!!!! */ + /****************************************************************************/ + /** + * Summon an instance of [[Bimonad]] for `F`. + */ + @inline def apply[F[_]](implicit instance: Bimonad[F]): Bimonad[F] = instance + + trait Ops[F[_], A] { + type TypeClassType <: Bimonad[F] + def self: F[A] + val typeClassInstance: TypeClassType + } + trait AllOps[F[_], A] extends Ops[F, A] with Monad.AllOps[F, A] with Comonad.AllOps[F, A] { + type TypeClassType <: Bimonad[F] + } + trait ToBimonadOps { + implicit def toBimonadOps[F[_], A](target: F[A])(implicit tc: Bimonad[F]): Ops[F, A] { + type TypeClassType = Bimonad[F] + } = new Ops[F, A] { + type TypeClassType = Bimonad[F] + val self: F[A] = target + val typeClassInstance: TypeClassType = tc + } + } + object nonInheritedOps extends ToBimonadOps + object ops { + implicit def toAllBimonadOps[F[_], A](target: F[A])(implicit tc: Bimonad[F]): AllOps[F, A] { + type TypeClassType = Bimonad[F] + } = new AllOps[F, A] { + type TypeClassType = Bimonad[F] + val self: F[A] = target + val typeClassInstance: TypeClassType = tc + } + } + + /****************************************************************************/ + /* END OF SIMULACRUM-MANAGED CODE */ + /****************************************************************************/ + +} diff --git a/core/src/main/scala/cats/Bitraverse.scala b/core/src/main/scala/cats/Bitraverse.scala index a0439e4137..5eda743132 100644 --- a/core/src/main/scala/cats/Bitraverse.scala +++ b/core/src/main/scala/cats/Bitraverse.scala @@ -1,10 +1,12 @@ package cats import simulacrum.{noop, typeclass} +import scala.annotation.implicitNotFound /** * A type class abstracting over types that give rise to two independent [[cats.Traverse]]s. */ +@implicitNotFound("Could not find an instance of Bitraverse for ${F}") @typeclass trait Bitraverse[F[_, _]] extends Bifoldable[F] with Bifunctor[F] { self => /** @@ -109,6 +111,54 @@ import simulacrum.{noop, typeclass} bitraverse(fgab)(identity, G.pure(_)) } +object Bitraverse { + + /****************************************************************************/ + /* THE FOLLOWING CODE IS MANAGED BY SIMULACRUM; PLEASE DO NOT EDIT!!!! */ + /****************************************************************************/ + /** + * Summon an instance of [[Bitraverse]] for `F`. + */ + @inline def apply[F[_, _]](implicit instance: Bitraverse[F]): Bitraverse[F] = instance + + trait Ops[F[_, _], A, B] { + type TypeClassType <: Bitraverse[F] + def self: F[A, B] + val typeClassInstance: TypeClassType + def bitraverse[G[_], C, D](f: A => G[C], g: B => G[D])(implicit ev$1: Applicative[G]): G[F[C, D]] = + typeClassInstance.bitraverse[G, A, B, C, D](self)(f, g) + def bisequence[G[_], C, D](implicit ev$1: A <:< G[C], ev$2: B <:< G[D], ev$3: Applicative[G]): G[F[C, D]] = + typeClassInstance.bisequence[G, C, D](self.asInstanceOf[F[G[C], G[D]]]) + } + trait AllOps[F[_, _], A, B] extends Ops[F, A, B] with Bifoldable.AllOps[F, A, B] with Bifunctor.AllOps[F, A, B] { + type TypeClassType <: Bitraverse[F] + } + trait ToBitraverseOps { + implicit def toBitraverseOps[F[_, _], A, B](target: F[A, B])(implicit tc: Bitraverse[F]): Ops[F, A, B] { + type TypeClassType = Bitraverse[F] + } = new Ops[F, A, B] { + type TypeClassType = Bitraverse[F] + val self: F[A, B] = target + val typeClassInstance: TypeClassType = tc + } + } + object nonInheritedOps extends ToBitraverseOps + object ops { + implicit def toAllBitraverseOps[F[_, _], A, B](target: F[A, B])(implicit tc: Bitraverse[F]): AllOps[F, A, B] { + type TypeClassType = Bitraverse[F] + } = new AllOps[F, A, B] { + type TypeClassType = Bitraverse[F] + val self: F[A, B] = target + val typeClassInstance: TypeClassType = tc + } + } + + /****************************************************************************/ + /* END OF SIMULACRUM-MANAGED CODE */ + /****************************************************************************/ + +} + private[cats] trait ComposedBitraverse[F[_, _], G[_, _]] extends Bitraverse[λ[(α, β) => F[G[α, β], G[α, β]]]] with ComposedBifoldable[F, G] diff --git a/core/src/main/scala/cats/CoflatMap.scala b/core/src/main/scala/cats/CoflatMap.scala index 7df1e6266b..59645bac71 100644 --- a/core/src/main/scala/cats/CoflatMap.scala +++ b/core/src/main/scala/cats/CoflatMap.scala @@ -1,12 +1,14 @@ package cats import simulacrum.typeclass +import scala.annotation.implicitNotFound /** * `CoflatMap` is the dual of `FlatMap`. * * Must obey the laws in cats.laws.CoflatMapLaws */ +@implicitNotFound("Could not find an instance of CoflatMap for ${F}") @typeclass trait CoflatMap[F[_]] extends Functor[F] { /** @@ -45,3 +47,49 @@ import simulacrum.typeclass def coflatten[A](fa: F[A]): F[F[A]] = coflatMap(fa)(fa => fa) } + +object CoflatMap { + + /****************************************************************************/ + /* THE FOLLOWING CODE IS MANAGED BY SIMULACRUM; PLEASE DO NOT EDIT!!!! */ + /****************************************************************************/ + /** + * Summon an instance of [[CoflatMap]] for `F`. + */ + @inline def apply[F[_]](implicit instance: CoflatMap[F]): CoflatMap[F] = instance + + trait Ops[F[_], A] { + type TypeClassType <: CoflatMap[F] + def self: F[A] + val typeClassInstance: TypeClassType + def coflatMap[B](f: F[A] => B): F[B] = typeClassInstance.coflatMap[A, B](self)(f) + def coflatten: F[F[A]] = typeClassInstance.coflatten[A](self) + } + trait AllOps[F[_], A] extends Ops[F, A] with Functor.AllOps[F, A] { + type TypeClassType <: CoflatMap[F] + } + trait ToCoflatMapOps { + implicit def toCoflatMapOps[F[_], A](target: F[A])(implicit tc: CoflatMap[F]): Ops[F, A] { + type TypeClassType = CoflatMap[F] + } = new Ops[F, A] { + type TypeClassType = CoflatMap[F] + val self: F[A] = target + val typeClassInstance: TypeClassType = tc + } + } + object nonInheritedOps extends ToCoflatMapOps + object ops { + implicit def toAllCoflatMapOps[F[_], A](target: F[A])(implicit tc: CoflatMap[F]): AllOps[F, A] { + type TypeClassType = CoflatMap[F] + } = new AllOps[F, A] { + type TypeClassType = CoflatMap[F] + val self: F[A] = target + val typeClassInstance: TypeClassType = tc + } + } + + /****************************************************************************/ + /* END OF SIMULACRUM-MANAGED CODE */ + /****************************************************************************/ + +} diff --git a/core/src/main/scala/cats/CommutativeApplicative.scala b/core/src/main/scala/cats/CommutativeApplicative.scala index 3f38346c1c..26bc936ece 100644 --- a/core/src/main/scala/cats/CommutativeApplicative.scala +++ b/core/src/main/scala/cats/CommutativeApplicative.scala @@ -2,6 +2,7 @@ package cats import cats.kernel.CommutativeMonoid import simulacrum.typeclass +import scala.annotation.implicitNotFound /** * Commutative Applicative. @@ -12,6 +13,7 @@ import simulacrum.typeclass * * Must obey the laws defined in cats.laws.CommutativeApplicativeLaws. */ +@implicitNotFound("Could not find an instance of CommutativeApplicative for ${F}") @typeclass trait CommutativeApplicative[F[_]] extends Applicative[F] with CommutativeApply[F] object CommutativeApplicative { @@ -25,4 +27,47 @@ object CommutativeApplicative { CommutativeApplicative[F] .map2(x, y)(CommutativeMonoid[A].combine) } + + /****************************************************************************/ + /* THE FOLLOWING CODE IS MANAGED BY SIMULACRUM; PLEASE DO NOT EDIT!!!! */ + /****************************************************************************/ + /** + * Summon an instance of [[CommutativeApplicative]] for `F`. + */ + @inline def apply[F[_]](implicit instance: CommutativeApplicative[F]): CommutativeApplicative[F] = instance + + trait Ops[F[_], A] { + type TypeClassType <: CommutativeApplicative[F] + def self: F[A] + val typeClassInstance: TypeClassType + } + trait AllOps[F[_], A] extends Ops[F, A] with Applicative.AllOps[F, A] with CommutativeApply.AllOps[F, A] { + type TypeClassType <: CommutativeApplicative[F] + } + trait ToCommutativeApplicativeOps { + implicit def toCommutativeApplicativeOps[F[_], A](target: F[A])(implicit tc: CommutativeApplicative[F]): Ops[F, A] { + type TypeClassType = CommutativeApplicative[F] + } = new Ops[F, A] { + type TypeClassType = CommutativeApplicative[F] + val self: F[A] = target + val typeClassInstance: TypeClassType = tc + } + } + object nonInheritedOps extends ToCommutativeApplicativeOps + object ops { + implicit def toAllCommutativeApplicativeOps[F[_], A]( + target: F[A] + )(implicit tc: CommutativeApplicative[F]): AllOps[F, A] { + type TypeClassType = CommutativeApplicative[F] + } = new AllOps[F, A] { + type TypeClassType = CommutativeApplicative[F] + val self: F[A] = target + val typeClassInstance: TypeClassType = tc + } + } + + /****************************************************************************/ + /* END OF SIMULACRUM-MANAGED CODE */ + /****************************************************************************/ + } diff --git a/core/src/main/scala/cats/CommutativeApply.scala b/core/src/main/scala/cats/CommutativeApply.scala index f88b9a453d..65a30e905b 100644 --- a/core/src/main/scala/cats/CommutativeApply.scala +++ b/core/src/main/scala/cats/CommutativeApply.scala @@ -2,6 +2,7 @@ package cats import cats.kernel.CommutativeSemigroup import simulacrum.typeclass +import scala.annotation.implicitNotFound /** * Commutative Apply. @@ -12,6 +13,7 @@ import simulacrum.typeclass * * Must obey the laws defined in cats.laws.CommutativeApplyLaws. */ +@implicitNotFound("Could not find an instance of CommutativeApply for ${F}") @typeclass trait CommutativeApply[F[_]] extends Apply[F] object CommutativeApply { @@ -21,4 +23,45 @@ object CommutativeApply { CommutativeApply[F] .map2(x, y)(CommutativeSemigroup[A].combine) } + + /****************************************************************************/ + /* THE FOLLOWING CODE IS MANAGED BY SIMULACRUM; PLEASE DO NOT EDIT!!!! */ + /****************************************************************************/ + /** + * Summon an instance of [[CommutativeApply]] for `F`. + */ + @inline def apply[F[_]](implicit instance: CommutativeApply[F]): CommutativeApply[F] = instance + + trait Ops[F[_], A] { + type TypeClassType <: CommutativeApply[F] + def self: F[A] + val typeClassInstance: TypeClassType + } + trait AllOps[F[_], A] extends Ops[F, A] with Apply.AllOps[F, A] { + type TypeClassType <: CommutativeApply[F] + } + trait ToCommutativeApplyOps { + implicit def toCommutativeApplyOps[F[_], A](target: F[A])(implicit tc: CommutativeApply[F]): Ops[F, A] { + type TypeClassType = CommutativeApply[F] + } = new Ops[F, A] { + type TypeClassType = CommutativeApply[F] + val self: F[A] = target + val typeClassInstance: TypeClassType = tc + } + } + object nonInheritedOps extends ToCommutativeApplyOps + object ops { + implicit def toAllCommutativeApplyOps[F[_], A](target: F[A])(implicit tc: CommutativeApply[F]): AllOps[F, A] { + type TypeClassType = CommutativeApply[F] + } = new AllOps[F, A] { + type TypeClassType = CommutativeApply[F] + val self: F[A] = target + val typeClassInstance: TypeClassType = tc + } + } + + /****************************************************************************/ + /* END OF SIMULACRUM-MANAGED CODE */ + /****************************************************************************/ + } diff --git a/core/src/main/scala/cats/CommutativeFlatMap.scala b/core/src/main/scala/cats/CommutativeFlatMap.scala index 22998bb3db..860054dc4a 100644 --- a/core/src/main/scala/cats/CommutativeFlatMap.scala +++ b/core/src/main/scala/cats/CommutativeFlatMap.scala @@ -1,6 +1,7 @@ package cats import simulacrum.typeclass +import scala.annotation.implicitNotFound /** * Commutative FlatMap. @@ -11,4 +12,49 @@ import simulacrum.typeclass * * Must obey the laws defined in cats.laws.CommutativeFlatMapLaws. */ +@implicitNotFound("Could not find an instance of CommutativeFlatMap for ${F}") @typeclass trait CommutativeFlatMap[F[_]] extends FlatMap[F] with CommutativeApply[F] + +object CommutativeFlatMap { + + /****************************************************************************/ + /* THE FOLLOWING CODE IS MANAGED BY SIMULACRUM; PLEASE DO NOT EDIT!!!! */ + /****************************************************************************/ + /** + * Summon an instance of [[CommutativeFlatMap]] for `F`. + */ + @inline def apply[F[_]](implicit instance: CommutativeFlatMap[F]): CommutativeFlatMap[F] = instance + + trait Ops[F[_], A] { + type TypeClassType <: CommutativeFlatMap[F] + def self: F[A] + val typeClassInstance: TypeClassType + } + trait AllOps[F[_], A] extends Ops[F, A] with FlatMap.AllOps[F, A] with CommutativeApply.AllOps[F, A] { + type TypeClassType <: CommutativeFlatMap[F] + } + trait ToCommutativeFlatMapOps { + implicit def toCommutativeFlatMapOps[F[_], A](target: F[A])(implicit tc: CommutativeFlatMap[F]): Ops[F, A] { + type TypeClassType = CommutativeFlatMap[F] + } = new Ops[F, A] { + type TypeClassType = CommutativeFlatMap[F] + val self: F[A] = target + val typeClassInstance: TypeClassType = tc + } + } + object nonInheritedOps extends ToCommutativeFlatMapOps + object ops { + implicit def toAllCommutativeFlatMapOps[F[_], A](target: F[A])(implicit tc: CommutativeFlatMap[F]): AllOps[F, A] { + type TypeClassType = CommutativeFlatMap[F] + } = new AllOps[F, A] { + type TypeClassType = CommutativeFlatMap[F] + val self: F[A] = target + val typeClassInstance: TypeClassType = tc + } + } + + /****************************************************************************/ + /* END OF SIMULACRUM-MANAGED CODE */ + /****************************************************************************/ + +} diff --git a/core/src/main/scala/cats/CommutativeMonad.scala b/core/src/main/scala/cats/CommutativeMonad.scala index 9c7b07792d..8e3258d052 100644 --- a/core/src/main/scala/cats/CommutativeMonad.scala +++ b/core/src/main/scala/cats/CommutativeMonad.scala @@ -1,6 +1,7 @@ package cats import simulacrum.typeclass +import scala.annotation.implicitNotFound /** * Commutative Monad. @@ -11,4 +12,53 @@ import simulacrum.typeclass * * Must obey the laws defined in cats.laws.CommutativeMonadLaws. */ +@implicitNotFound("Could not find an instance of CommutativeMonad for ${F}") @typeclass trait CommutativeMonad[F[_]] extends Monad[F] with CommutativeFlatMap[F] with CommutativeApplicative[F] + +object CommutativeMonad { + + /****************************************************************************/ + /* THE FOLLOWING CODE IS MANAGED BY SIMULACRUM; PLEASE DO NOT EDIT!!!! */ + /****************************************************************************/ + /** + * Summon an instance of [[CommutativeMonad]] for `F`. + */ + @inline def apply[F[_]](implicit instance: CommutativeMonad[F]): CommutativeMonad[F] = instance + + trait Ops[F[_], A] { + type TypeClassType <: CommutativeMonad[F] + def self: F[A] + val typeClassInstance: TypeClassType + } + trait AllOps[F[_], A] + extends Ops[F, A] + with Monad.AllOps[F, A] + with CommutativeFlatMap.AllOps[F, A] + with CommutativeApplicative.AllOps[F, A] { + type TypeClassType <: CommutativeMonad[F] + } + trait ToCommutativeMonadOps { + implicit def toCommutativeMonadOps[F[_], A](target: F[A])(implicit tc: CommutativeMonad[F]): Ops[F, A] { + type TypeClassType = CommutativeMonad[F] + } = new Ops[F, A] { + type TypeClassType = CommutativeMonad[F] + val self: F[A] = target + val typeClassInstance: TypeClassType = tc + } + } + object nonInheritedOps extends ToCommutativeMonadOps + object ops { + implicit def toAllCommutativeMonadOps[F[_], A](target: F[A])(implicit tc: CommutativeMonad[F]): AllOps[F, A] { + type TypeClassType = CommutativeMonad[F] + } = new AllOps[F, A] { + type TypeClassType = CommutativeMonad[F] + val self: F[A] = target + val typeClassInstance: TypeClassType = tc + } + } + + /****************************************************************************/ + /* END OF SIMULACRUM-MANAGED CODE */ + /****************************************************************************/ + +} diff --git a/core/src/main/scala/cats/Comonad.scala b/core/src/main/scala/cats/Comonad.scala index 7bf47d0b7c..df2ed898b8 100644 --- a/core/src/main/scala/cats/Comonad.scala +++ b/core/src/main/scala/cats/Comonad.scala @@ -1,6 +1,7 @@ package cats import simulacrum.typeclass +import scala.annotation.implicitNotFound /** * Comonad @@ -10,6 +11,7 @@ import simulacrum.typeclass * * Must obey the laws defined in cats.laws.ComonadLaws. */ +@implicitNotFound("Could not find an instance of Comonad for ${F}") @typeclass trait Comonad[F[_]] extends CoflatMap[F] { /** @@ -27,3 +29,48 @@ import simulacrum.typeclass */ def extract[A](x: F[A]): A } + +object Comonad { + + /****************************************************************************/ + /* THE FOLLOWING CODE IS MANAGED BY SIMULACRUM; PLEASE DO NOT EDIT!!!! */ + /****************************************************************************/ + /** + * Summon an instance of [[Comonad]] for `F`. + */ + @inline def apply[F[_]](implicit instance: Comonad[F]): Comonad[F] = instance + + trait Ops[F[_], A] { + type TypeClassType <: Comonad[F] + def self: F[A] + val typeClassInstance: TypeClassType + def extract: A = typeClassInstance.extract[A](self) + } + trait AllOps[F[_], A] extends Ops[F, A] with CoflatMap.AllOps[F, A] { + type TypeClassType <: Comonad[F] + } + trait ToComonadOps { + implicit def toComonadOps[F[_], A](target: F[A])(implicit tc: Comonad[F]): Ops[F, A] { + type TypeClassType = Comonad[F] + } = new Ops[F, A] { + type TypeClassType = Comonad[F] + val self: F[A] = target + val typeClassInstance: TypeClassType = tc + } + } + object nonInheritedOps extends ToComonadOps + object ops { + implicit def toAllComonadOps[F[_], A](target: F[A])(implicit tc: Comonad[F]): AllOps[F, A] { + type TypeClassType = Comonad[F] + } = new AllOps[F, A] { + type TypeClassType = Comonad[F] + val self: F[A] = target + val typeClassInstance: TypeClassType = tc + } + } + + /****************************************************************************/ + /* END OF SIMULACRUM-MANAGED CODE */ + /****************************************************************************/ + +} diff --git a/core/src/main/scala/cats/Contravariant.scala b/core/src/main/scala/cats/Contravariant.scala index 3924822748..14c4318368 100644 --- a/core/src/main/scala/cats/Contravariant.scala +++ b/core/src/main/scala/cats/Contravariant.scala @@ -1,9 +1,11 @@ package cats import simulacrum.typeclass +import scala.annotation.implicitNotFound /** * Must obey the laws defined in cats.laws.ContravariantLaws. */ +@implicitNotFound("Could not find an instance of Contravariant for ${F}") @typeclass trait Contravariant[F[_]] extends Invariant[F] { self => def contramap[A, B](fa: F[A])(f: B => A): F[B] override def imap[A, B](fa: F[A])(f: A => B)(fi: B => A): F[B] = contramap(fa)(fi) @@ -28,3 +30,49 @@ import simulacrum.typeclass val G = Functor[G] } } + +object Contravariant { + + /****************************************************************************/ + /* THE FOLLOWING CODE IS MANAGED BY SIMULACRUM; PLEASE DO NOT EDIT!!!! */ + /****************************************************************************/ + /** + * Summon an instance of [[Contravariant]] for `F`. + */ + @inline def apply[F[_]](implicit instance: Contravariant[F]): Contravariant[F] = instance + + trait Ops[F[_], A] { + type TypeClassType <: Contravariant[F] + def self: F[A] + val typeClassInstance: TypeClassType + def contramap[B](f: B => A): F[B] = typeClassInstance.contramap[A, B](self)(f) + def narrow[B <: A]: F[B] = typeClassInstance.narrow[A, B](self) + } + trait AllOps[F[_], A] extends Ops[F, A] with Invariant.AllOps[F, A] { + type TypeClassType <: Contravariant[F] + } + trait ToContravariantOps { + implicit def toContravariantOps[F[_], A](target: F[A])(implicit tc: Contravariant[F]): Ops[F, A] { + type TypeClassType = Contravariant[F] + } = new Ops[F, A] { + type TypeClassType = Contravariant[F] + val self: F[A] = target + val typeClassInstance: TypeClassType = tc + } + } + object nonInheritedOps extends ToContravariantOps + object ops { + implicit def toAllContravariantOps[F[_], A](target: F[A])(implicit tc: Contravariant[F]): AllOps[F, A] { + type TypeClassType = Contravariant[F] + } = new AllOps[F, A] { + type TypeClassType = Contravariant[F] + val self: F[A] = target + val typeClassInstance: TypeClassType = tc + } + } + + /****************************************************************************/ + /* END OF SIMULACRUM-MANAGED CODE */ + /****************************************************************************/ + +} diff --git a/core/src/main/scala/cats/ContravariantMonoidal.scala b/core/src/main/scala/cats/ContravariantMonoidal.scala index 069357f32b..b6f6e84bee 100644 --- a/core/src/main/scala/cats/ContravariantMonoidal.scala +++ b/core/src/main/scala/cats/ContravariantMonoidal.scala @@ -1,6 +1,7 @@ package cats import simulacrum.typeclass +import scala.annotation.implicitNotFound /** * [[ContravariantMonoidal]] functors are functors that supply @@ -11,6 +12,7 @@ import simulacrum.typeclass * Based on ekmett's contravariant library: * https://hackage.haskell.org/package/contravariant-1.4/docs/Data-Functor-Contravariant-Divisible.html */ +@implicitNotFound("Could not find an instance of ContravariantMonoidal for ${F}") @typeclass trait ContravariantMonoidal[F[_]] extends ContravariantSemigroupal[F] with InvariantMonoidal[F] { /** @@ -24,6 +26,52 @@ import simulacrum.typeclass object ContravariantMonoidal extends SemigroupalArityFunctions { def monoid[F[_], A](implicit f: ContravariantMonoidal[F]): Monoid[F[A]] = new ContravariantMonoidalMonoid[F, A](f) + + /****************************************************************************/ + /* THE FOLLOWING CODE IS MANAGED BY SIMULACRUM; PLEASE DO NOT EDIT!!!! */ + /****************************************************************************/ + /** + * Summon an instance of [[ContravariantMonoidal]] for `F`. + */ + @inline def apply[F[_]](implicit instance: ContravariantMonoidal[F]): ContravariantMonoidal[F] = instance + + trait Ops[F[_], A] { + type TypeClassType <: ContravariantMonoidal[F] + def self: F[A] + val typeClassInstance: TypeClassType + } + trait AllOps[F[_], A] + extends Ops[F, A] + with ContravariantSemigroupal.AllOps[F, A] + with InvariantMonoidal.AllOps[F, A] { + type TypeClassType <: ContravariantMonoidal[F] + } + trait ToContravariantMonoidalOps { + implicit def toContravariantMonoidalOps[F[_], A](target: F[A])(implicit tc: ContravariantMonoidal[F]): Ops[F, A] { + type TypeClassType = ContravariantMonoidal[F] + } = new Ops[F, A] { + type TypeClassType = ContravariantMonoidal[F] + val self: F[A] = target + val typeClassInstance: TypeClassType = tc + } + } + object nonInheritedOps extends ToContravariantMonoidalOps + object ops { + implicit def toAllContravariantMonoidalOps[F[_], A]( + target: F[A] + )(implicit tc: ContravariantMonoidal[F]): AllOps[F, A] { + type TypeClassType = ContravariantMonoidal[F] + } = new AllOps[F, A] { + type TypeClassType = ContravariantMonoidal[F] + val self: F[A] = target + val typeClassInstance: TypeClassType = tc + } + } + + /****************************************************************************/ + /* END OF SIMULACRUM-MANAGED CODE */ + /****************************************************************************/ + } private[cats] class ContravariantMonoidalMonoid[F[_], A](f: ContravariantMonoidal[F]) diff --git a/core/src/main/scala/cats/ContravariantSemigroupal.scala b/core/src/main/scala/cats/ContravariantSemigroupal.scala index 77910a31e0..b2b834ed77 100644 --- a/core/src/main/scala/cats/ContravariantSemigroupal.scala +++ b/core/src/main/scala/cats/ContravariantSemigroupal.scala @@ -1,11 +1,13 @@ package cats import simulacrum.typeclass +import scala.annotation.implicitNotFound /** * [[ContravariantSemigroupal]] is nothing more than something both contravariant * and Semigroupal. It comes up enough to be useful, and composes well */ +@implicitNotFound("Could not find an instance of ContravariantSemigroupal for ${F}") @typeclass trait ContravariantSemigroupal[F[_]] extends InvariantSemigroupal[F] with Contravariant[F] { self => override def composeFunctor[G[_]: Functor]: ContravariantSemigroupal[λ[α => F[G[α]]]] = new ComposedSemigroupal[F, G] { @@ -18,6 +20,51 @@ import simulacrum.typeclass object ContravariantSemigroupal extends SemigroupalArityFunctions { def semigroup[F[_], A](implicit f: ContravariantSemigroupal[F]): Semigroup[F[A]] = new ContravariantSemigroupalSemigroup[F, A](f) + + /****************************************************************************/ + /* THE FOLLOWING CODE IS MANAGED BY SIMULACRUM; PLEASE DO NOT EDIT!!!! */ + /****************************************************************************/ + /** + * Summon an instance of [[ContravariantSemigroupal]] for `F`. + */ + @inline def apply[F[_]](implicit instance: ContravariantSemigroupal[F]): ContravariantSemigroupal[F] = instance + + trait Ops[F[_], A] { + type TypeClassType <: ContravariantSemigroupal[F] + def self: F[A] + val typeClassInstance: TypeClassType + } + trait AllOps[F[_], A] extends Ops[F, A] with InvariantSemigroupal.AllOps[F, A] with Contravariant.AllOps[F, A] { + type TypeClassType <: ContravariantSemigroupal[F] + } + trait ToContravariantSemigroupalOps { + implicit def toContravariantSemigroupalOps[F[_], A]( + target: F[A] + )(implicit tc: ContravariantSemigroupal[F]): Ops[F, A] { + type TypeClassType = ContravariantSemigroupal[F] + } = new Ops[F, A] { + type TypeClassType = ContravariantSemigroupal[F] + val self: F[A] = target + val typeClassInstance: TypeClassType = tc + } + } + object nonInheritedOps extends ToContravariantSemigroupalOps + object ops { + implicit def toAllContravariantSemigroupalOps[F[_], A]( + target: F[A] + )(implicit tc: ContravariantSemigroupal[F]): AllOps[F, A] { + type TypeClassType = ContravariantSemigroupal[F] + } = new AllOps[F, A] { + type TypeClassType = ContravariantSemigroupal[F] + val self: F[A] = target + val typeClassInstance: TypeClassType = tc + } + } + + /****************************************************************************/ + /* END OF SIMULACRUM-MANAGED CODE */ + /****************************************************************************/ + } private[cats] class ContravariantSemigroupalSemigroup[F[_], A](f: ContravariantSemigroupal[F]) extends Semigroup[F[A]] { diff --git a/core/src/main/scala/cats/Distributive.scala b/core/src/main/scala/cats/Distributive.scala index 68df7b67e8..a6694acba7 100644 --- a/core/src/main/scala/cats/Distributive.scala +++ b/core/src/main/scala/cats/Distributive.scala @@ -1,6 +1,8 @@ package cats import simulacrum.typeclass +import scala.annotation.implicitNotFound +@implicitNotFound("Could not find an instance of Distributive for ${F}") @typeclass trait Distributive[F[_]] extends Functor[F] { self => /** @@ -20,3 +22,47 @@ import simulacrum.typeclass implicit def G = G0 } } + +object Distributive { + + /****************************************************************************/ + /* THE FOLLOWING CODE IS MANAGED BY SIMULACRUM; PLEASE DO NOT EDIT!!!! */ + /****************************************************************************/ + /** + * Summon an instance of [[Distributive]] for `F`. + */ + @inline def apply[F[_]](implicit instance: Distributive[F]): Distributive[F] = instance + + trait Ops[F[_], A] { + type TypeClassType <: Distributive[F] + def self: F[A] + val typeClassInstance: TypeClassType + } + trait AllOps[F[_], A] extends Ops[F, A] with Functor.AllOps[F, A] { + type TypeClassType <: Distributive[F] + } + trait ToDistributiveOps { + implicit def toDistributiveOps[F[_], A](target: F[A])(implicit tc: Distributive[F]): Ops[F, A] { + type TypeClassType = Distributive[F] + } = new Ops[F, A] { + type TypeClassType = Distributive[F] + val self: F[A] = target + val typeClassInstance: TypeClassType = tc + } + } + object nonInheritedOps extends ToDistributiveOps + object ops { + implicit def toAllDistributiveOps[F[_], A](target: F[A])(implicit tc: Distributive[F]): AllOps[F, A] { + type TypeClassType = Distributive[F] + } = new AllOps[F, A] { + type TypeClassType = Distributive[F] + val self: F[A] = target + val typeClassInstance: TypeClassType = tc + } + } + + /****************************************************************************/ + /* END OF SIMULACRUM-MANAGED CODE */ + /****************************************************************************/ + +} diff --git a/core/src/main/scala/cats/FlatMap.scala b/core/src/main/scala/cats/FlatMap.scala index 94c0c2fe3c..28ecb7ae53 100644 --- a/core/src/main/scala/cats/FlatMap.scala +++ b/core/src/main/scala/cats/FlatMap.scala @@ -2,6 +2,7 @@ package cats import simulacrum.typeclass import simulacrum.noop +import scala.annotation.implicitNotFound /** * FlatMap type class gives us flatMap, which allows us to have a value @@ -18,6 +19,7 @@ import simulacrum.noop * * Must obey the laws defined in cats.laws.FlatMapLaws. */ +@implicitNotFound("Could not find an instance of FlatMap for ${F}") @typeclass trait FlatMap[F[_]] extends Apply[F] { def flatMap[A, B](fa: F[A])(f: A => F[B]): F[B] @@ -197,3 +199,53 @@ import simulacrum.noop tailRecM(())(_ => feither) } } + +object FlatMap { + + /****************************************************************************/ + /* THE FOLLOWING CODE IS MANAGED BY SIMULACRUM; PLEASE DO NOT EDIT!!!! */ + /****************************************************************************/ + /** + * Summon an instance of [[FlatMap]] for `F`. + */ + @inline def apply[F[_]](implicit instance: FlatMap[F]): FlatMap[F] = instance + + trait Ops[F[_], A] { + type TypeClassType <: FlatMap[F] + def self: F[A] + val typeClassInstance: TypeClassType + def flatMap[B](f: A => F[B]): F[B] = typeClassInstance.flatMap[A, B](self)(f) + def flatten[B](implicit ev$1: A <:< F[B]): F[B] = typeClassInstance.flatten[B](self.asInstanceOf[F[F[B]]]) + def productREval[B](fb: Eval[F[B]]): F[B] = typeClassInstance.productREval[A, B](self)(fb) + def productLEval[B](fb: Eval[F[B]]): F[A] = typeClassInstance.productLEval[A, B](self)(fb) + def mproduct[B](f: A => F[B]): F[(A, B)] = typeClassInstance.mproduct[A, B](self)(f) + def flatTap[B](f: A => F[B]): F[A] = typeClassInstance.flatTap[A, B](self)(f) + } + trait AllOps[F[_], A] extends Ops[F, A] with Apply.AllOps[F, A] { + type TypeClassType <: FlatMap[F] + } + trait ToFlatMapOps { + implicit def toFlatMapOps[F[_], A](target: F[A])(implicit tc: FlatMap[F]): Ops[F, A] { + type TypeClassType = FlatMap[F] + } = new Ops[F, A] { + type TypeClassType = FlatMap[F] + val self: F[A] = target + val typeClassInstance: TypeClassType = tc + } + } + object nonInheritedOps extends ToFlatMapOps + object ops { + implicit def toAllFlatMapOps[F[_], A](target: F[A])(implicit tc: FlatMap[F]): AllOps[F, A] { + type TypeClassType = FlatMap[F] + } = new AllOps[F, A] { + type TypeClassType = FlatMap[F] + val self: F[A] = target + val typeClassInstance: TypeClassType = tc + } + } + + /****************************************************************************/ + /* END OF SIMULACRUM-MANAGED CODE */ + /****************************************************************************/ + +} diff --git a/core/src/main/scala/cats/Foldable.scala b/core/src/main/scala/cats/Foldable.scala index 668614a0bd..dce1dbc1cc 100644 --- a/core/src/main/scala/cats/Foldable.scala +++ b/core/src/main/scala/cats/Foldable.scala @@ -5,6 +5,7 @@ import cats.instances.either._ import cats.kernel.CommutativeMonoid import simulacrum.{noop, typeclass} import Foldable.sentinel +import scala.annotation.implicitNotFound /** * Data structures that can be folded to a summary value. @@ -28,6 +29,7 @@ import Foldable.sentinel * * See: [[http://www.cs.nott.ac.uk/~pszgmh/fold.pdf A tutorial on the universality and expressiveness of fold]] */ +@implicitNotFound("Could not find an instance of Foldable for ${F}") @typeclass trait Foldable[F[_]] extends UnorderedFoldable[F] { self => /** @@ -907,4 +909,97 @@ object Foldable { def fromFoldable[F[_], A](fa: F[A])(implicit F: Foldable[F]): Source[A] = F.foldRight[A, Source[A]](fa, Now(Empty))((a, evalSrc) => Later(cons(a, evalSrc))).value } + + /****************************************************************************/ + /* THE FOLLOWING CODE IS MANAGED BY SIMULACRUM; PLEASE DO NOT EDIT!!!! */ + /****************************************************************************/ + /** + * Summon an instance of [[Foldable]] for `F`. + */ + @inline def apply[F[_]](implicit instance: Foldable[F]): Foldable[F] = instance + + trait Ops[F[_], A] { + type TypeClassType <: Foldable[F] + def self: F[A] + val typeClassInstance: TypeClassType + def foldLeft[B](b: B)(f: (B, A) => B): B = typeClassInstance.foldLeft[A, B](self, b)(f) + def foldRight[B](lb: Eval[B])(f: (A, Eval[B]) => Eval[B]): Eval[B] = typeClassInstance.foldRight[A, B](self, lb)(f) + def foldRightDefer[G[_], B](gb: G[B])(fn: (A, G[B]) => G[B])(implicit ev$1: Defer[G]): G[B] = + typeClassInstance.foldRightDefer[G, A, B](self, gb)(fn) + def reduceLeftToOption[B](f: A => B)(g: (B, A) => B): Option[B] = + typeClassInstance.reduceLeftToOption[A, B](self)(f)(g) + def reduceRightToOption[B](f: A => B)(g: (A, Eval[B]) => Eval[B]): Eval[Option[B]] = + typeClassInstance.reduceRightToOption[A, B](self)(f)(g) + def reduceLeftOption(f: (A, A) => A): Option[A] = typeClassInstance.reduceLeftOption[A](self)(f) + def reduceRightOption(f: (A, Eval[A]) => Eval[A]): Eval[Option[A]] = typeClassInstance.reduceRightOption[A](self)(f) + def minimumOption(implicit A: Order[A]): Option[A] = typeClassInstance.minimumOption[A](self)(A) + def maximumOption(implicit A: Order[A]): Option[A] = typeClassInstance.maximumOption[A](self)(A) + def minimumByOption[B](f: A => B)(implicit ev$1: Order[B]): Option[A] = + typeClassInstance.minimumByOption[A, B](self)(f) + def maximumByOption[B](f: A => B)(implicit ev$1: Order[B]): Option[A] = + typeClassInstance.maximumByOption[A, B](self)(f) + def get(idx: Long): Option[A] = typeClassInstance.get[A](self)(idx) + def collectFirst[B](pf: PartialFunction[A, B]): Option[B] = typeClassInstance.collectFirst[A, B](self)(pf) + def collectFirstSome[B](f: A => Option[B]): Option[B] = typeClassInstance.collectFirstSome[A, B](self)(f) + def collectFoldSome[B](f: A => Option[B])(implicit B: Monoid[B]): B = + typeClassInstance.collectFoldSome[A, B](self)(f)(B) + def fold(implicit A: Monoid[A]): A = typeClassInstance.fold[A](self)(A) + def combineAll(implicit ev$1: Monoid[A]): A = typeClassInstance.combineAll[A](self) + def combineAllOption(implicit ev: Semigroup[A]): Option[A] = typeClassInstance.combineAllOption[A](self)(ev) + def toIterable: Iterable[A] = typeClassInstance.toIterable[A](self) + def foldMap[B](f: A => B)(implicit B: Monoid[B]): B = typeClassInstance.foldMap[A, B](self)(f)(B) + def foldM[G[_], B](z: B)(f: (B, A) => G[B])(implicit G: Monad[G]): G[B] = + typeClassInstance.foldM[G, A, B](self, z)(f)(G) + final def foldLeftM[G[_], B](z: B)(f: (B, A) => G[B])(implicit G: Monad[G]): G[B] = + typeClassInstance.foldLeftM[G, A, B](self, z)(f)(G) + def foldMapM[G[_], B](f: A => G[B])(implicit G: Monad[G], B: Monoid[B]): G[B] = + typeClassInstance.foldMapM[G, A, B](self)(f)(G, B) + def foldMapA[G[_], B](f: A => G[B])(implicit G: Applicative[G], B: Monoid[B]): G[B] = + typeClassInstance.foldMapA[G, A, B](self)(f)(G, B) + def traverse_[G[_], B](f: A => G[B])(implicit G: Applicative[G]): G[Unit] = + typeClassInstance.traverse_[G, A, B](self)(f)(G) + def sequence_[G[_], B](implicit ev$1: A <:< G[B], ev$2: Applicative[G]): G[Unit] = + typeClassInstance.sequence_[G, B](self.asInstanceOf[F[G[B]]]) + def foldK[G[_], B](implicit ev$1: A <:< G[B], G: MonoidK[G]): G[B] = + typeClassInstance.foldK[G, B](self.asInstanceOf[F[G[B]]])(G) + def find(f: A => Boolean): Option[A] = typeClassInstance.find[A](self)(f) + def existsM[G[_]](p: A => G[Boolean])(implicit G: Monad[G]): G[Boolean] = + typeClassInstance.existsM[G, A](self)(p)(G) + def forallM[G[_]](p: A => G[Boolean])(implicit G: Monad[G]): G[Boolean] = + typeClassInstance.forallM[G, A](self)(p)(G) + def toList: List[A] = typeClassInstance.toList[A](self) + def partitionEither[B, C](f: A => Either[B, C])(implicit A: Alternative[F]): (F[B], F[C]) = + typeClassInstance.partitionEither[A, B, C](self)(f)(A) + def filter_(p: A => Boolean): List[A] = typeClassInstance.filter_[A](self)(p) + def takeWhile_(p: A => Boolean): List[A] = typeClassInstance.takeWhile_[A](self)(p) + def dropWhile_(p: A => Boolean): List[A] = typeClassInstance.dropWhile_[A](self)(p) + def intercalate(a: A)(implicit A: Monoid[A]): A = typeClassInstance.intercalate[A](self, a)(A) + } + trait AllOps[F[_], A] extends Ops[F, A] with UnorderedFoldable.AllOps[F, A] { + type TypeClassType <: Foldable[F] + } + trait ToFoldableOps { + implicit def toFoldableOps[F[_], A](target: F[A])(implicit tc: Foldable[F]): Ops[F, A] { + type TypeClassType = Foldable[F] + } = new Ops[F, A] { + type TypeClassType = Foldable[F] + val self: F[A] = target + val typeClassInstance: TypeClassType = tc + } + } + object nonInheritedOps extends ToFoldableOps + object ops { + implicit def toAllFoldableOps[F[_], A](target: F[A])(implicit tc: Foldable[F]): AllOps[F, A] { + type TypeClassType = Foldable[F] + } = new AllOps[F, A] { + type TypeClassType = Foldable[F] + val self: F[A] = target + val typeClassInstance: TypeClassType = tc + } + } + + /****************************************************************************/ + /* END OF SIMULACRUM-MANAGED CODE */ + /****************************************************************************/ + } diff --git a/core/src/main/scala/cats/Functor.scala b/core/src/main/scala/cats/Functor.scala index ea5f34a4f9..06109f1574 100644 --- a/core/src/main/scala/cats/Functor.scala +++ b/core/src/main/scala/cats/Functor.scala @@ -1,6 +1,7 @@ package cats import simulacrum.{noop, typeclass} +import scala.annotation.implicitNotFound /** * Functor. @@ -9,6 +10,7 @@ import simulacrum.{noop, typeclass} * * Must obey the laws defined in cats.laws.FunctorLaws. */ +@implicitNotFound("Could not find an instance of Functor for ${F}") @typeclass trait Functor[F[_]] extends Invariant[F] { self => def map[A, B](fa: F[A])(f: A => B): F[B] @@ -188,3 +190,55 @@ import simulacrum.{noop, typeclass} val G = Contravariant[G] } } + +object Functor { + + /****************************************************************************/ + /* THE FOLLOWING CODE IS MANAGED BY SIMULACRUM; PLEASE DO NOT EDIT!!!! */ + /****************************************************************************/ + /** + * Summon an instance of [[Functor]] for `F`. + */ + @inline def apply[F[_]](implicit instance: Functor[F]): Functor[F] = instance + + trait Ops[F[_], A] { + type TypeClassType <: Functor[F] + def self: F[A] + val typeClassInstance: TypeClassType + def map[B](f: A => B): F[B] = typeClassInstance.map[A, B](self)(f) + final def fmap[B](f: A => B): F[B] = typeClassInstance.fmap[A, B](self)(f) + def widen[B >: A]: F[B] = typeClassInstance.widen[A, B](self) + def void: F[Unit] = typeClassInstance.void[A](self) + def fproduct[B](f: A => B): F[(A, B)] = typeClassInstance.fproduct[A, B](self)(f) + def as[B](b: B): F[B] = typeClassInstance.as[A, B](self, b) + def tupleLeft[B](b: B): F[(B, A)] = typeClassInstance.tupleLeft[A, B](self, b) + def tupleRight[B](b: B): F[(A, B)] = typeClassInstance.tupleRight[A, B](self, b) + } + trait AllOps[F[_], A] extends Ops[F, A] with Invariant.AllOps[F, A] { + type TypeClassType <: Functor[F] + } + trait ToFunctorOps { + implicit def toFunctorOps[F[_], A](target: F[A])(implicit tc: Functor[F]): Ops[F, A] { + type TypeClassType = Functor[F] + } = new Ops[F, A] { + type TypeClassType = Functor[F] + val self: F[A] = target + val typeClassInstance: TypeClassType = tc + } + } + object nonInheritedOps extends ToFunctorOps + object ops { + implicit def toAllFunctorOps[F[_], A](target: F[A])(implicit tc: Functor[F]): AllOps[F, A] { + type TypeClassType = Functor[F] + } = new AllOps[F, A] { + type TypeClassType = Functor[F] + val self: F[A] = target + val typeClassInstance: TypeClassType = tc + } + } + + /****************************************************************************/ + /* END OF SIMULACRUM-MANAGED CODE */ + /****************************************************************************/ + +} diff --git a/core/src/main/scala/cats/FunctorFilter.scala b/core/src/main/scala/cats/FunctorFilter.scala index 7b3b230076..0de36eed1e 100644 --- a/core/src/main/scala/cats/FunctorFilter.scala +++ b/core/src/main/scala/cats/FunctorFilter.scala @@ -1,10 +1,12 @@ package cats import simulacrum.typeclass +import scala.annotation.implicitNotFound /** * `FunctorFilter[F]` allows you to `map` and filter out elements simultaneously. */ +@implicitNotFound("Could not find an instance of FunctorFilter for ${F}") @typeclass trait FunctorFilter[F[_]] extends Serializable { def functor: Functor[F] @@ -74,3 +76,51 @@ trait FunctorFilter[F[_]] extends Serializable { def filterNot[A](fa: F[A])(f: A => Boolean): F[A] = mapFilter(fa)(Some(_).filterNot(f)) } + +object FunctorFilter { + + /****************************************************************************/ + /* THE FOLLOWING CODE IS MANAGED BY SIMULACRUM; PLEASE DO NOT EDIT!!!! */ + /****************************************************************************/ + /** + * Summon an instance of [[FunctorFilter]] for `F`. + */ + @inline def apply[F[_]](implicit instance: FunctorFilter[F]): FunctorFilter[F] = instance + + trait Ops[F[_], A] { + type TypeClassType <: FunctorFilter[F] + def self: F[A] + val typeClassInstance: TypeClassType + def mapFilter[B](f: A => Option[B]): F[B] = typeClassInstance.mapFilter[A, B](self)(f) + def collect[B](f: PartialFunction[A, B]): F[B] = typeClassInstance.collect[A, B](self)(f) + def flattenOption[B](implicit ev$1: A <:< Option[B]): F[B] = + typeClassInstance.flattenOption[B](self.asInstanceOf[F[Option[B]]]) + def filter(f: A => Boolean): F[A] = typeClassInstance.filter[A](self)(f) + def filterNot(f: A => Boolean): F[A] = typeClassInstance.filterNot[A](self)(f) + } + trait AllOps[F[_], A] extends Ops[F, A] + trait ToFunctorFilterOps { + implicit def toFunctorFilterOps[F[_], A](target: F[A])(implicit tc: FunctorFilter[F]): Ops[F, A] { + type TypeClassType = FunctorFilter[F] + } = new Ops[F, A] { + type TypeClassType = FunctorFilter[F] + val self: F[A] = target + val typeClassInstance: TypeClassType = tc + } + } + object nonInheritedOps extends ToFunctorFilterOps + object ops { + implicit def toAllFunctorFilterOps[F[_], A](target: F[A])(implicit tc: FunctorFilter[F]): AllOps[F, A] { + type TypeClassType = FunctorFilter[F] + } = new AllOps[F, A] { + type TypeClassType = FunctorFilter[F] + val self: F[A] = target + val typeClassInstance: TypeClassType = tc + } + } + + /****************************************************************************/ + /* END OF SIMULACRUM-MANAGED CODE */ + /****************************************************************************/ + +} diff --git a/core/src/main/scala/cats/Invariant.scala b/core/src/main/scala/cats/Invariant.scala index 0c391c1e88..b5355843cc 100644 --- a/core/src/main/scala/cats/Invariant.scala +++ b/core/src/main/scala/cats/Invariant.scala @@ -3,11 +3,13 @@ package cats import cats.kernel._ import simulacrum.typeclass import cats.kernel.compat.scalaVersionSpecific._ +import scala.annotation.implicitNotFound /** * Must obey the laws defined in cats.laws.InvariantLaws. */ -@typeclass trait Invariant[F[_]] { self => +@implicitNotFound("Could not find an instance of Invariant for ${F}") +@typeclass trait Invariant[F[_]] extends Serializable { self => /** * Transform an `F[A]` into an `F[B]` by providing a transformation from `A` @@ -121,4 +123,44 @@ object Invariant { } } + + /****************************************************************************/ + /* THE FOLLOWING CODE IS MANAGED BY SIMULACRUM; PLEASE DO NOT EDIT!!!! */ + /****************************************************************************/ + /** + * Summon an instance of [[Invariant]] for `F`. + */ + @inline def apply[F[_]](implicit instance: Invariant[F]): Invariant[F] = instance + + trait Ops[F[_], A] { + type TypeClassType <: Invariant[F] + def self: F[A] + val typeClassInstance: TypeClassType + def imap[B](f: A => B)(g: B => A): F[B] = typeClassInstance.imap[A, B](self)(f)(g) + } + trait AllOps[F[_], A] extends Ops[F, A] + trait ToInvariantOps { + implicit def toInvariantOps[F[_], A](target: F[A])(implicit tc: Invariant[F]): Ops[F, A] { + type TypeClassType = Invariant[F] + } = new Ops[F, A] { + type TypeClassType = Invariant[F] + val self: F[A] = target + val typeClassInstance: TypeClassType = tc + } + } + object nonInheritedOps extends ToInvariantOps + object ops { + implicit def toAllInvariantOps[F[_], A](target: F[A])(implicit tc: Invariant[F]): AllOps[F, A] { + type TypeClassType = Invariant[F] + } = new AllOps[F, A] { + type TypeClassType = Invariant[F] + val self: F[A] = target + val typeClassInstance: TypeClassType = tc + } + } + + /****************************************************************************/ + /* END OF SIMULACRUM-MANAGED CODE */ + /****************************************************************************/ + } diff --git a/core/src/main/scala/cats/InvariantMonoidal.scala b/core/src/main/scala/cats/InvariantMonoidal.scala index 7195ad4c8b..c4de33c58a 100644 --- a/core/src/main/scala/cats/InvariantMonoidal.scala +++ b/core/src/main/scala/cats/InvariantMonoidal.scala @@ -1,12 +1,14 @@ package cats import simulacrum.typeclass +import scala.annotation.implicitNotFound /** * Invariant version of a Monoidal. * * Must obey the laws defined in cats.laws.InvariantMonoidalLaws. */ +@implicitNotFound("Could not find an instance of InvariantMonoidal for ${F}") @typeclass trait InvariantMonoidal[F[_]] extends InvariantSemigroupal[F] { /** @@ -33,6 +35,47 @@ object InvariantMonoidal { */ def monoid[F[_], A](implicit F: InvariantMonoidal[F], A: Monoid[A]): Monoid[F[A]] = new InvariantMonoidalMonoid[F, A](F, A) + + /****************************************************************************/ + /* THE FOLLOWING CODE IS MANAGED BY SIMULACRUM; PLEASE DO NOT EDIT!!!! */ + /****************************************************************************/ + /** + * Summon an instance of [[InvariantMonoidal]] for `F`. + */ + @inline def apply[F[_]](implicit instance: InvariantMonoidal[F]): InvariantMonoidal[F] = instance + + trait Ops[F[_], A] { + type TypeClassType <: InvariantMonoidal[F] + def self: F[A] + val typeClassInstance: TypeClassType + } + trait AllOps[F[_], A] extends Ops[F, A] with InvariantSemigroupal.AllOps[F, A] { + type TypeClassType <: InvariantMonoidal[F] + } + trait ToInvariantMonoidalOps { + implicit def toInvariantMonoidalOps[F[_], A](target: F[A])(implicit tc: InvariantMonoidal[F]): Ops[F, A] { + type TypeClassType = InvariantMonoidal[F] + } = new Ops[F, A] { + type TypeClassType = InvariantMonoidal[F] + val self: F[A] = target + val typeClassInstance: TypeClassType = tc + } + } + object nonInheritedOps extends ToInvariantMonoidalOps + object ops { + implicit def toAllInvariantMonoidalOps[F[_], A](target: F[A])(implicit tc: InvariantMonoidal[F]): AllOps[F, A] { + type TypeClassType = InvariantMonoidal[F] + } = new AllOps[F, A] { + type TypeClassType = InvariantMonoidal[F] + val self: F[A] = target + val typeClassInstance: TypeClassType = tc + } + } + + /****************************************************************************/ + /* END OF SIMULACRUM-MANAGED CODE */ + /****************************************************************************/ + } private[cats] class InvariantMonoidalMonoid[F[_], A](f: InvariantMonoidal[F], monoid: Monoid[A]) diff --git a/core/src/main/scala/cats/InvariantSemigroupal.scala b/core/src/main/scala/cats/InvariantSemigroupal.scala index bb2b28b8c6..da4cd323ac 100644 --- a/core/src/main/scala/cats/InvariantSemigroupal.scala +++ b/core/src/main/scala/cats/InvariantSemigroupal.scala @@ -1,11 +1,13 @@ package cats import simulacrum.typeclass +import scala.annotation.implicitNotFound /** * [[InvariantSemigroupal]] is nothing more than something both invariant * and Semigroupal. It comes up enough to be useful, and composes well */ +@implicitNotFound("Could not find an instance of InvariantSemigroupal for ${F}") @typeclass trait InvariantSemigroupal[F[_]] extends Semigroupal[F] with Invariant[F] { self => def composeApply[G[_]: Apply]: InvariantSemigroupal[λ[α => F[G[α]]]] = @@ -23,6 +25,49 @@ object InvariantSemigroupal extends SemigroupalArityFunctions { */ def semigroup[F[_], A](implicit F: InvariantSemigroupal[F], A: Semigroup[A]): Semigroup[F[A]] = new InvariantSemigroupalSemigroup[F, A](F, A) + + /****************************************************************************/ + /* THE FOLLOWING CODE IS MANAGED BY SIMULACRUM; PLEASE DO NOT EDIT!!!! */ + /****************************************************************************/ + /** + * Summon an instance of [[InvariantSemigroupal]] for `F`. + */ + @inline def apply[F[_]](implicit instance: InvariantSemigroupal[F]): InvariantSemigroupal[F] = instance + + trait Ops[F[_], A] { + type TypeClassType <: InvariantSemigroupal[F] + def self: F[A] + val typeClassInstance: TypeClassType + } + trait AllOps[F[_], A] extends Ops[F, A] with Semigroupal.AllOps[F, A] with Invariant.AllOps[F, A] { + type TypeClassType <: InvariantSemigroupal[F] + } + trait ToInvariantSemigroupalOps { + implicit def toInvariantSemigroupalOps[F[_], A](target: F[A])(implicit tc: InvariantSemigroupal[F]): Ops[F, A] { + type TypeClassType = InvariantSemigroupal[F] + } = new Ops[F, A] { + type TypeClassType = InvariantSemigroupal[F] + val self: F[A] = target + val typeClassInstance: TypeClassType = tc + } + } + object nonInheritedOps extends ToInvariantSemigroupalOps + object ops { + implicit def toAllInvariantSemigroupalOps[F[_], A]( + target: F[A] + )(implicit tc: InvariantSemigroupal[F]): AllOps[F, A] { + type TypeClassType = InvariantSemigroupal[F] + } = new AllOps[F, A] { + type TypeClassType = InvariantSemigroupal[F] + val self: F[A] = target + val typeClassInstance: TypeClassType = tc + } + } + + /****************************************************************************/ + /* END OF SIMULACRUM-MANAGED CODE */ + /****************************************************************************/ + } private[cats] class InvariantSemigroupalSemigroup[F[_], A](f: InvariantSemigroupal[F], sg: Semigroup[A]) diff --git a/core/src/main/scala/cats/Monad.scala b/core/src/main/scala/cats/Monad.scala index c18ff015f7..f6baaf800c 100644 --- a/core/src/main/scala/cats/Monad.scala +++ b/core/src/main/scala/cats/Monad.scala @@ -1,6 +1,7 @@ package cats import simulacrum.{noop, typeclass} +import scala.annotation.implicitNotFound /** * Monad. @@ -11,6 +12,7 @@ import simulacrum.{noop, typeclass} * * Must obey the laws defined in cats.laws.MonadLaws. */ +@implicitNotFound("Could not find an instance of Monad for ${F}") @typeclass trait Monad[F[_]] extends FlatMap[F] with Applicative[F] { override def map[A, B](fa: F[A])(f: A => B): F[B] = flatMap(fa)(a => pure(f(a))) @@ -116,3 +118,52 @@ import simulacrum.{noop, typeclass} iterateWhileM(init)(f)(!p(_)) } + +object Monad { + + /****************************************************************************/ + /* THE FOLLOWING CODE IS MANAGED BY SIMULACRUM; PLEASE DO NOT EDIT!!!! */ + /****************************************************************************/ + /** + * Summon an instance of [[Monad]] for `F`. + */ + @inline def apply[F[_]](implicit instance: Monad[F]): Monad[F] = instance + + trait Ops[F[_], A] { + type TypeClassType <: Monad[F] + def self: F[A] + val typeClassInstance: TypeClassType + def untilM[G[_]](cond: => F[Boolean])(implicit G: Alternative[G]): F[G[A]] = + typeClassInstance.untilM[G, A](self)(cond)(G) + def untilM_(cond: => F[Boolean]): F[Unit] = typeClassInstance.untilM_[A](self)(cond) + def iterateWhile(p: A => Boolean): F[A] = typeClassInstance.iterateWhile[A](self)(p) + def iterateUntil(p: A => Boolean): F[A] = typeClassInstance.iterateUntil[A](self)(p) + } + trait AllOps[F[_], A] extends Ops[F, A] with FlatMap.AllOps[F, A] with Applicative.AllOps[F, A] { + type TypeClassType <: Monad[F] + } + trait ToMonadOps { + implicit def toMonadOps[F[_], A](target: F[A])(implicit tc: Monad[F]): Ops[F, A] { + type TypeClassType = Monad[F] + } = new Ops[F, A] { + type TypeClassType = Monad[F] + val self: F[A] = target + val typeClassInstance: TypeClassType = tc + } + } + object nonInheritedOps extends ToMonadOps + object ops { + implicit def toAllMonadOps[F[_], A](target: F[A])(implicit tc: Monad[F]): AllOps[F, A] { + type TypeClassType = Monad[F] + } = new AllOps[F, A] { + type TypeClassType = Monad[F] + val self: F[A] = target + val typeClassInstance: TypeClassType = tc + } + } + + /****************************************************************************/ + /* END OF SIMULACRUM-MANAGED CODE */ + /****************************************************************************/ + +} diff --git a/core/src/main/scala/cats/MonoidK.scala b/core/src/main/scala/cats/MonoidK.scala index 5e5c1b0823..65aec341b4 100644 --- a/core/src/main/scala/cats/MonoidK.scala +++ b/core/src/main/scala/cats/MonoidK.scala @@ -1,6 +1,7 @@ package cats import simulacrum.typeclass +import scala.annotation.implicitNotFound /** * MonoidK is a universal monoid which operates on kinds. @@ -22,6 +23,7 @@ import simulacrum.typeclass * combination operation and empty value just depend on the * structure of F, but not on the structure of A. */ +@implicitNotFound("Could not find an instance of MonoidK for ${F}") @typeclass trait MonoidK[F[_]] extends SemigroupK[F] { self => /** @@ -50,3 +52,47 @@ import simulacrum.typeclass val F = self } } + +object MonoidK { + + /****************************************************************************/ + /* THE FOLLOWING CODE IS MANAGED BY SIMULACRUM; PLEASE DO NOT EDIT!!!! */ + /****************************************************************************/ + /** + * Summon an instance of [[MonoidK]] for `F`. + */ + @inline def apply[F[_]](implicit instance: MonoidK[F]): MonoidK[F] = instance + + trait Ops[F[_], A] { + type TypeClassType <: MonoidK[F] + def self: F[A] + val typeClassInstance: TypeClassType + } + trait AllOps[F[_], A] extends Ops[F, A] with SemigroupK.AllOps[F, A] { + type TypeClassType <: MonoidK[F] + } + trait ToMonoidKOps { + implicit def toMonoidKOps[F[_], A](target: F[A])(implicit tc: MonoidK[F]): Ops[F, A] { + type TypeClassType = MonoidK[F] + } = new Ops[F, A] { + type TypeClassType = MonoidK[F] + val self: F[A] = target + val typeClassInstance: TypeClassType = tc + } + } + object nonInheritedOps extends ToMonoidKOps + object ops { + implicit def toAllMonoidKOps[F[_], A](target: F[A])(implicit tc: MonoidK[F]): AllOps[F, A] { + type TypeClassType = MonoidK[F] + } = new AllOps[F, A] { + type TypeClassType = MonoidK[F] + val self: F[A] = target + val typeClassInstance: TypeClassType = tc + } + } + + /****************************************************************************/ + /* END OF SIMULACRUM-MANAGED CODE */ + /****************************************************************************/ + +} diff --git a/core/src/main/scala/cats/NonEmptyTraverse.scala b/core/src/main/scala/cats/NonEmptyTraverse.scala index 0da54cbfef..5812562910 100644 --- a/core/src/main/scala/cats/NonEmptyTraverse.scala +++ b/core/src/main/scala/cats/NonEmptyTraverse.scala @@ -1,6 +1,7 @@ package cats import simulacrum.typeclass +import scala.annotation.implicitNotFound /** * NonEmptyTraverse, also known as Traversable1. @@ -8,6 +9,7 @@ import simulacrum.typeclass * `NonEmptyTraverse` is like a non-empty `Traverse`. In addition to the traverse and sequence * methods it provides nonEmptyTraverse and nonEmptySequence methods which require an `Apply` instance instead of `Applicative`. */ +@implicitNotFound("Could not find an instance of NonEmptyTraverse for ${F}") @typeclass trait NonEmptyTraverse[F[_]] extends Traverse[F] with Reducible[F] { self => /** @@ -93,3 +95,55 @@ import simulacrum.typeclass } } + +object NonEmptyTraverse { + + /****************************************************************************/ + /* THE FOLLOWING CODE IS MANAGED BY SIMULACRUM; PLEASE DO NOT EDIT!!!! */ + /****************************************************************************/ + /** + * Summon an instance of [[NonEmptyTraverse]] for `F`. + */ + @inline def apply[F[_]](implicit instance: NonEmptyTraverse[F]): NonEmptyTraverse[F] = instance + + trait Ops[F[_], A] { + type TypeClassType <: NonEmptyTraverse[F] + def self: F[A] + val typeClassInstance: TypeClassType + def nonEmptyTraverse[G[_], B](f: A => G[B])(implicit ev$1: Apply[G]): G[F[B]] = + typeClassInstance.nonEmptyTraverse[G, A, B](self)(f) + def nonEmptySequence[G[_], B](implicit ev$1: A <:< G[B], ev$2: Apply[G]): G[F[B]] = + typeClassInstance.nonEmptySequence[G, B](self.asInstanceOf[F[G[B]]]) + def nonEmptyFlatTraverse[G[_], B](f: A => G[F[B]])(implicit G: Apply[G], F: FlatMap[F]): G[F[B]] = + typeClassInstance.nonEmptyFlatTraverse[G, A, B](self)(f)(G, F) + def nonEmptyFlatSequence[G[_], B](implicit ev$1: A <:< G[F[B]], G: Apply[G], F: FlatMap[F]): G[F[B]] = + typeClassInstance.nonEmptyFlatSequence[G, B](self.asInstanceOf[F[G[F[B]]]])(G, F) + } + trait AllOps[F[_], A] extends Ops[F, A] with Traverse.AllOps[F, A] with Reducible.AllOps[F, A] { + type TypeClassType <: NonEmptyTraverse[F] + } + trait ToNonEmptyTraverseOps { + implicit def toNonEmptyTraverseOps[F[_], A](target: F[A])(implicit tc: NonEmptyTraverse[F]): Ops[F, A] { + type TypeClassType = NonEmptyTraverse[F] + } = new Ops[F, A] { + type TypeClassType = NonEmptyTraverse[F] + val self: F[A] = target + val typeClassInstance: TypeClassType = tc + } + } + object nonInheritedOps extends ToNonEmptyTraverseOps + object ops { + implicit def toAllNonEmptyTraverseOps[F[_], A](target: F[A])(implicit tc: NonEmptyTraverse[F]): AllOps[F, A] { + type TypeClassType = NonEmptyTraverse[F] + } = new AllOps[F, A] { + type TypeClassType = NonEmptyTraverse[F] + val self: F[A] = target + val typeClassInstance: TypeClassType = tc + } + } + + /****************************************************************************/ + /* END OF SIMULACRUM-MANAGED CODE */ + /****************************************************************************/ + +} diff --git a/core/src/main/scala/cats/Reducible.scala b/core/src/main/scala/cats/Reducible.scala index a57ed051d4..dc48fd2466 100644 --- a/core/src/main/scala/cats/Reducible.scala +++ b/core/src/main/scala/cats/Reducible.scala @@ -2,6 +2,7 @@ package cats import cats.data.{Ior, NonEmptyList} import simulacrum.{noop, typeclass} +import scala.annotation.implicitNotFound /** * Data structures that can be reduced to a summary value. @@ -16,6 +17,7 @@ import simulacrum.{noop, typeclass} * - `reduceLeftTo(fa)(f)(g)` eagerly reduces with an additional mapping function * - `reduceRightTo(fa)(f)(g)` lazily reduces with an additional mapping function */ +@implicitNotFound("Could not find an instance of Reducible for ${F}") @typeclass trait Reducible[F[_]] extends Foldable[F] { self => /** @@ -282,6 +284,77 @@ import simulacrum.{noop, typeclass} Some(maximum(fa)) } +object Reducible { + + /****************************************************************************/ + /* THE FOLLOWING CODE IS MANAGED BY SIMULACRUM; PLEASE DO NOT EDIT!!!! */ + /****************************************************************************/ + /** + * Summon an instance of [[Reducible]] for `F`. + */ + @inline def apply[F[_]](implicit instance: Reducible[F]): Reducible[F] = instance + + trait Ops[F[_], A] { + type TypeClassType <: Reducible[F] + def self: F[A] + val typeClassInstance: TypeClassType + def reduceLeft(f: (A, A) => A): A = typeClassInstance.reduceLeft[A](self)(f) + def reduceRight(f: (A, Eval[A]) => Eval[A]): Eval[A] = typeClassInstance.reduceRight[A](self)(f) + def reduce(implicit A: Semigroup[A]): A = typeClassInstance.reduce[A](self)(A) + def reduceK[G[_], B](implicit ev$1: A <:< G[B], G: SemigroupK[G]): G[B] = + typeClassInstance.reduceK[G, B](self.asInstanceOf[F[G[B]]])(G) + def reduceMap[B](f: A => B)(implicit B: Semigroup[B]): B = typeClassInstance.reduceMap[A, B](self)(f)(B) + def reduceLeftTo[B](f: A => B)(g: (B, A) => B): B = typeClassInstance.reduceLeftTo[A, B](self)(f)(g) + def reduceLeftM[G[_], B](f: A => G[B])(g: (B, A) => G[B])(implicit G: FlatMap[G]): G[B] = + typeClassInstance.reduceLeftM[G, A, B](self)(f)(g)(G) + def reduceMapA[G[_], B](f: A => G[B])(implicit G: Apply[G], B: Semigroup[B]): G[B] = + typeClassInstance.reduceMapA[G, A, B](self)(f)(G, B) + def reduceMapM[G[_], B](f: A => G[B])(implicit G: FlatMap[G], B: Semigroup[B]): G[B] = + typeClassInstance.reduceMapM[G, A, B](self)(f)(G, B) + def reduceRightTo[B](f: A => B)(g: (A, Eval[B]) => Eval[B]): Eval[B] = + typeClassInstance.reduceRightTo[A, B](self)(f)(g) + def nonEmptyTraverse_[G[_], B](f: A => G[B])(implicit G: Apply[G]): G[Unit] = + typeClassInstance.nonEmptyTraverse_[G, A, B](self)(f)(G) + def nonEmptySequence_[G[_], B](implicit ev$1: A <:< G[B], G: Apply[G]): G[Unit] = + typeClassInstance.nonEmptySequence_[G, B](self.asInstanceOf[F[G[B]]])(G) + def toNonEmptyList: NonEmptyList[A] = typeClassInstance.toNonEmptyList[A](self) + def minimum(implicit A: Order[A]): A = typeClassInstance.minimum[A](self)(A) + def maximum(implicit A: Order[A]): A = typeClassInstance.maximum[A](self)(A) + def minimumBy[B](f: A => B)(implicit ev$1: Order[B]): A = typeClassInstance.minimumBy[A, B](self)(f) + def maximumBy[B](f: A => B)(implicit ev$1: Order[B]): A = typeClassInstance.maximumBy[A, B](self)(f) + def nonEmptyIntercalate(a: A)(implicit A: Semigroup[A]): A = typeClassInstance.nonEmptyIntercalate[A](self, a)(A) + def nonEmptyPartition[B, C](f: A => Either[B, C]): Ior[NonEmptyList[B], NonEmptyList[C]] = + typeClassInstance.nonEmptyPartition[A, B, C](self)(f) + } + trait AllOps[F[_], A] extends Ops[F, A] with Foldable.AllOps[F, A] { + type TypeClassType <: Reducible[F] + } + trait ToReducibleOps { + implicit def toReducibleOps[F[_], A](target: F[A])(implicit tc: Reducible[F]): Ops[F, A] { + type TypeClassType = Reducible[F] + } = new Ops[F, A] { + type TypeClassType = Reducible[F] + val self: F[A] = target + val typeClassInstance: TypeClassType = tc + } + } + object nonInheritedOps extends ToReducibleOps + object ops { + implicit def toAllReducibleOps[F[_], A](target: F[A])(implicit tc: Reducible[F]): AllOps[F, A] { + type TypeClassType = Reducible[F] + } = new AllOps[F, A] { + type TypeClassType = Reducible[F] + val self: F[A] = target + val typeClassInstance: TypeClassType = tc + } + } + + /****************************************************************************/ + /* END OF SIMULACRUM-MANAGED CODE */ + /****************************************************************************/ + +} + /** * This class defines a `Reducible[F]` in terms of a `Foldable[G]` * together with a `split` method, `F[A]` => `(A, G[A])`. diff --git a/core/src/main/scala/cats/SemigroupK.scala b/core/src/main/scala/cats/SemigroupK.scala index 3afa632164..c3d2109a2e 100644 --- a/core/src/main/scala/cats/SemigroupK.scala +++ b/core/src/main/scala/cats/SemigroupK.scala @@ -2,6 +2,7 @@ package cats import simulacrum.typeclass import cats.data.Ior +import scala.annotation.implicitNotFound /** * SemigroupK is a universal semigroup which operates on kinds. @@ -21,7 +22,8 @@ import cats.data.Ior * The combination operation just depends on the structure of F, * but not the structure of A. */ -@typeclass trait SemigroupK[F[_]] { self => +@implicitNotFound("Could not find an instance of SemigroupK for ${F}") +@typeclass trait SemigroupK[F[_]] extends Serializable { self => /** * Combine two F[A] values. @@ -90,4 +92,46 @@ object SemigroupK { SemigroupK[F].combineK(Functor[F].map(fa)(Ior.left), Functor[F].map(fb)(Ior.right)) def functor: Functor[F] = Functor[F] } + + /****************************************************************************/ + /* THE FOLLOWING CODE IS MANAGED BY SIMULACRUM; PLEASE DO NOT EDIT!!!! */ + /****************************************************************************/ + /** + * Summon an instance of [[SemigroupK]] for `F`. + */ + @inline def apply[F[_]](implicit instance: SemigroupK[F]): SemigroupK[F] = instance + + trait Ops[F[_], A] { + type TypeClassType <: SemigroupK[F] + def self: F[A] + val typeClassInstance: TypeClassType + def combineK(y: F[A]): F[A] = typeClassInstance.combineK[A](self, y) + def <+>(y: F[A]): F[A] = typeClassInstance.combineK[A](self, y) + def sum[B](fb: F[B])(implicit F: Functor[F]): F[Either[A, B]] = typeClassInstance.sum[A, B](self, fb)(F) + } + trait AllOps[F[_], A] extends Ops[F, A] + trait ToSemigroupKOps { + implicit def toSemigroupKOps[F[_], A](target: F[A])(implicit tc: SemigroupK[F]): Ops[F, A] { + type TypeClassType = SemigroupK[F] + } = new Ops[F, A] { + type TypeClassType = SemigroupK[F] + val self: F[A] = target + val typeClassInstance: TypeClassType = tc + } + } + object nonInheritedOps extends ToSemigroupKOps + object ops { + implicit def toAllSemigroupKOps[F[_], A](target: F[A])(implicit tc: SemigroupK[F]): AllOps[F, A] { + type TypeClassType = SemigroupK[F] + } = new AllOps[F, A] { + type TypeClassType = SemigroupK[F] + val self: F[A] = target + val typeClassInstance: TypeClassType = tc + } + } + + /****************************************************************************/ + /* END OF SIMULACRUM-MANAGED CODE */ + /****************************************************************************/ + } diff --git a/core/src/main/scala/cats/Semigroupal.scala b/core/src/main/scala/cats/Semigroupal.scala index 500e9cd010..61d6b6b9d9 100644 --- a/core/src/main/scala/cats/Semigroupal.scala +++ b/core/src/main/scala/cats/Semigroupal.scala @@ -1,6 +1,7 @@ package cats import simulacrum.typeclass +import scala.annotation.implicitNotFound /** * [[Semigroupal]] captures the idea of composing independent effectful values. @@ -12,7 +13,8 @@ import simulacrum.typeclass * That same idea is also manifested in the form of [[Apply]], and indeed [[Apply]] extends both * [[Semigroupal]] and [[Functor]] to illustrate this. */ -@typeclass trait Semigroupal[F[_]] { +@implicitNotFound("Could not find an instance of Semigroupal for ${F}") +@typeclass trait Semigroupal[F[_]] extends Serializable { /** * Combine an `F[A]` and an `F[B]` into an `F[(A, B)]` that maintains the effects of both `fa` and `fb`. @@ -42,4 +44,45 @@ import simulacrum.typeclass def product[A, B](fa: F[A], fb: F[B]): F[(A, B)] } -object Semigroupal extends SemigroupalArityFunctions +object Semigroupal extends SemigroupalArityFunctions { + + /****************************************************************************/ + /* THE FOLLOWING CODE IS MANAGED BY SIMULACRUM; PLEASE DO NOT EDIT!!!! */ + /****************************************************************************/ + /** + * Summon an instance of [[Semigroupal]] for `F`. + */ + @inline def apply[F[_]](implicit instance: Semigroupal[F]): Semigroupal[F] = instance + + trait Ops[F[_], A] { + type TypeClassType <: Semigroupal[F] + def self: F[A] + val typeClassInstance: TypeClassType + def product[B](fb: F[B]): F[(A, B)] = typeClassInstance.product[A, B](self, fb) + } + trait AllOps[F[_], A] extends Ops[F, A] + trait ToSemigroupalOps { + implicit def toSemigroupalOps[F[_], A](target: F[A])(implicit tc: Semigroupal[F]): Ops[F, A] { + type TypeClassType = Semigroupal[F] + } = new Ops[F, A] { + type TypeClassType = Semigroupal[F] + val self: F[A] = target + val typeClassInstance: TypeClassType = tc + } + } + object nonInheritedOps extends ToSemigroupalOps + object ops { + implicit def toAllSemigroupalOps[F[_], A](target: F[A])(implicit tc: Semigroupal[F]): AllOps[F, A] { + type TypeClassType = Semigroupal[F] + } = new AllOps[F, A] { + type TypeClassType = Semigroupal[F] + val self: F[A] = target + val typeClassInstance: TypeClassType = tc + } + } + + /****************************************************************************/ + /* END OF SIMULACRUM-MANAGED CODE */ + /****************************************************************************/ + +} diff --git a/core/src/main/scala/cats/Traverse.scala b/core/src/main/scala/cats/Traverse.scala index 17fc0a5a75..9a02ee44d0 100644 --- a/core/src/main/scala/cats/Traverse.scala +++ b/core/src/main/scala/cats/Traverse.scala @@ -4,6 +4,7 @@ import cats.data.State import cats.data.StateT import simulacrum.typeclass +import scala.annotation.implicitNotFound /** * Traverse, also known as Traversable. @@ -16,6 +17,7 @@ import simulacrum.typeclass * * See: [[https://www.cs.ox.ac.uk/jeremy.gibbons/publications/iterator.pdf The Essence of the Iterator Pattern]] */ +@implicitNotFound("Could not find an instance of Traverse for ${F}") @typeclass trait Traverse[F[_]] extends Functor[F] with Foldable[F] with UnorderedTraverse[F] { self => /** @@ -129,3 +131,63 @@ import simulacrum.typeclass override def unorderedSequence[G[_]: CommutativeApplicative, A](fga: F[G[A]]): G[F[A]] = sequence(fga) } + +object Traverse { + + /****************************************************************************/ + /* THE FOLLOWING CODE IS MANAGED BY SIMULACRUM; PLEASE DO NOT EDIT!!!! */ + /****************************************************************************/ + /** + * Summon an instance of [[Traverse]] for `F`. + */ + @inline def apply[F[_]](implicit instance: Traverse[F]): Traverse[F] = instance + + trait Ops[F[_], A] { + type TypeClassType <: Traverse[F] + def self: F[A] + val typeClassInstance: TypeClassType + def traverse[G[_], B](f: A => G[B])(implicit ev$1: Applicative[G]): G[F[B]] = + typeClassInstance.traverse[G, A, B](self)(f) + def flatTraverse[G[_], B](f: A => G[F[B]])(implicit G: Applicative[G], F: FlatMap[F]): G[F[B]] = + typeClassInstance.flatTraverse[G, A, B](self)(f)(G, F) + def sequence[G[_], B](implicit ev$1: A <:< G[B], ev$2: Applicative[G]): G[F[B]] = + typeClassInstance.sequence[G, B](self.asInstanceOf[F[G[B]]]) + def flatSequence[G[_], B](implicit ev$1: A <:< G[F[B]], G: Applicative[G], F: FlatMap[F]): G[F[B]] = + typeClassInstance.flatSequence[G, B](self.asInstanceOf[F[G[F[B]]]])(G, F) + def mapWithIndex[B](f: (A, Int) => B): F[B] = typeClassInstance.mapWithIndex[A, B](self)(f) + def traverseWithIndexM[G[_], B](f: (A, Int) => G[B])(implicit G: Monad[G]): G[F[B]] = + typeClassInstance.traverseWithIndexM[G, A, B](self)(f)(G) + def zipWithIndex: F[(A, Int)] = typeClassInstance.zipWithIndex[A](self) + } + trait AllOps[F[_], A] + extends Ops[F, A] + with Functor.AllOps[F, A] + with Foldable.AllOps[F, A] + with UnorderedTraverse.AllOps[F, A] { + type TypeClassType <: Traverse[F] + } + trait ToTraverseOps { + implicit def toTraverseOps[F[_], A](target: F[A])(implicit tc: Traverse[F]): Ops[F, A] { + type TypeClassType = Traverse[F] + } = new Ops[F, A] { + type TypeClassType = Traverse[F] + val self: F[A] = target + val typeClassInstance: TypeClassType = tc + } + } + object nonInheritedOps extends ToTraverseOps + object ops { + implicit def toAllTraverseOps[F[_], A](target: F[A])(implicit tc: Traverse[F]): AllOps[F, A] { + type TypeClassType = Traverse[F] + } = new AllOps[F, A] { + type TypeClassType = Traverse[F] + val self: F[A] = target + val typeClassInstance: TypeClassType = tc + } + } + + /****************************************************************************/ + /* END OF SIMULACRUM-MANAGED CODE */ + /****************************************************************************/ + +} diff --git a/core/src/main/scala/cats/TraverseFilter.scala b/core/src/main/scala/cats/TraverseFilter.scala index 7c18be45bb..46b3858a34 100644 --- a/core/src/main/scala/cats/TraverseFilter.scala +++ b/core/src/main/scala/cats/TraverseFilter.scala @@ -1,6 +1,7 @@ package cats import simulacrum.{noop, typeclass} +import scala.annotation.implicitNotFound /** * `TraverseFilter`, also known as `Witherable`, represents list-like structures @@ -10,6 +11,7 @@ import simulacrum.{noop, typeclass} * Based on Haskell's [[https://hackage.haskell.org/package/witherable-0.1.3.3/docs/Data-Witherable.html Data.Witherable]] */ +@implicitNotFound("Could not find an instance of TraverseFilter for ${F}") @typeclass trait TraverseFilter[F[_]] extends FunctorFilter[F] { def traverse: Traverse[F] @@ -85,3 +87,53 @@ trait TraverseFilter[F[_]] extends FunctorFilter[F] { override def mapFilter[A, B](fa: F[A])(f: A => Option[B]): F[B] = traverseFilter[Id, A, B](fa)(f) } + +object TraverseFilter { + + /****************************************************************************/ + /* THE FOLLOWING CODE IS MANAGED BY SIMULACRUM; PLEASE DO NOT EDIT!!!! */ + /****************************************************************************/ + /** + * Summon an instance of [[TraverseFilter]] for `F`. + */ + @inline def apply[F[_]](implicit instance: TraverseFilter[F]): TraverseFilter[F] = instance + + trait Ops[F[_], A] { + type TypeClassType <: TraverseFilter[F] + def self: F[A] + val typeClassInstance: TypeClassType + def traverseFilter[G[_], B](f: A => G[Option[B]])(implicit G: Applicative[G]): G[F[B]] = + typeClassInstance.traverseFilter[G, A, B](self)(f)(G) + def filterA[G[_]](f: A => G[Boolean])(implicit G: Applicative[G]): G[F[A]] = + typeClassInstance.filterA[G, A](self)(f)(G) + def traverseEither[G[_], B, C](f: A => G[Either[C, B]])(g: (A, C) => G[Unit])(implicit G: Monad[G]): G[F[B]] = + typeClassInstance.traverseEither[G, A, B, C](self)(f)(g)(G) + } + trait AllOps[F[_], A] extends Ops[F, A] with FunctorFilter.AllOps[F, A] { + type TypeClassType <: TraverseFilter[F] + } + trait ToTraverseFilterOps { + implicit def toTraverseFilterOps[F[_], A](target: F[A])(implicit tc: TraverseFilter[F]): Ops[F, A] { + type TypeClassType = TraverseFilter[F] + } = new Ops[F, A] { + type TypeClassType = TraverseFilter[F] + val self: F[A] = target + val typeClassInstance: TypeClassType = tc + } + } + object nonInheritedOps extends ToTraverseFilterOps + object ops { + implicit def toAllTraverseFilterOps[F[_], A](target: F[A])(implicit tc: TraverseFilter[F]): AllOps[F, A] { + type TypeClassType = TraverseFilter[F] + } = new AllOps[F, A] { + type TypeClassType = TraverseFilter[F] + val self: F[A] = target + val typeClassInstance: TypeClassType = tc + } + } + + /****************************************************************************/ + /* END OF SIMULACRUM-MANAGED CODE */ + /****************************************************************************/ + +} diff --git a/core/src/main/scala/cats/UnorderedFoldable.scala b/core/src/main/scala/cats/UnorderedFoldable.scala index 683575f3e1..cc82d3d06d 100644 --- a/core/src/main/scala/cats/UnorderedFoldable.scala +++ b/core/src/main/scala/cats/UnorderedFoldable.scala @@ -3,11 +3,13 @@ package cats import cats.instances.long._ import cats.kernel.CommutativeMonoid import simulacrum.{noop, typeclass} +import scala.annotation.implicitNotFound /** * `UnorderedFoldable` is like a `Foldable` for unordered containers. */ -@typeclass trait UnorderedFoldable[F[_]] { +@implicitNotFound("Could not find an instance of UnorderedFoldable for ${F}") +@typeclass trait UnorderedFoldable[F[_]] extends Serializable { def unorderedFoldMap[A, B: CommutativeMonoid](fa: F[A])(f: A => B): B @@ -91,4 +93,51 @@ object UnorderedFoldable { case false => Eval.False } } + + /****************************************************************************/ + /* THE FOLLOWING CODE IS MANAGED BY SIMULACRUM; PLEASE DO NOT EDIT!!!! */ + /****************************************************************************/ + /** + * Summon an instance of [[UnorderedFoldable]] for `F`. + */ + @inline def apply[F[_]](implicit instance: UnorderedFoldable[F]): UnorderedFoldable[F] = instance + + trait Ops[F[_], A] { + type TypeClassType <: UnorderedFoldable[F] + def self: F[A] + val typeClassInstance: TypeClassType + def unorderedFoldMap[B](f: A => B)(implicit ev$1: CommutativeMonoid[B]): B = + typeClassInstance.unorderedFoldMap[A, B](self)(f) + def unorderedFold(implicit ev$1: CommutativeMonoid[A]): A = typeClassInstance.unorderedFold[A](self) + def isEmpty: Boolean = typeClassInstance.isEmpty[A](self) + def nonEmpty: Boolean = typeClassInstance.nonEmpty[A](self) + def exists(p: A => Boolean): Boolean = typeClassInstance.exists[A](self)(p) + def forall(p: A => Boolean): Boolean = typeClassInstance.forall[A](self)(p) + def size: Long = typeClassInstance.size[A](self) + } + trait AllOps[F[_], A] extends Ops[F, A] + trait ToUnorderedFoldableOps { + implicit def toUnorderedFoldableOps[F[_], A](target: F[A])(implicit tc: UnorderedFoldable[F]): Ops[F, A] { + type TypeClassType = UnorderedFoldable[F] + } = new Ops[F, A] { + type TypeClassType = UnorderedFoldable[F] + val self: F[A] = target + val typeClassInstance: TypeClassType = tc + } + } + object nonInheritedOps extends ToUnorderedFoldableOps + object ops { + implicit def toAllUnorderedFoldableOps[F[_], A](target: F[A])(implicit tc: UnorderedFoldable[F]): AllOps[F, A] { + type TypeClassType = UnorderedFoldable[F] + } = new AllOps[F, A] { + type TypeClassType = UnorderedFoldable[F] + val self: F[A] = target + val typeClassInstance: TypeClassType = tc + } + } + + /****************************************************************************/ + /* END OF SIMULACRUM-MANAGED CODE */ + /****************************************************************************/ + } diff --git a/core/src/main/scala/cats/UnorderedTraverse.scala b/core/src/main/scala/cats/UnorderedTraverse.scala index fb246f1d7a..2faab8561a 100644 --- a/core/src/main/scala/cats/UnorderedTraverse.scala +++ b/core/src/main/scala/cats/UnorderedTraverse.scala @@ -1,13 +1,63 @@ package cats import simulacrum.typeclass +import scala.annotation.implicitNotFound /** * `UnorderedTraverse` is like a `Traverse` for unordered containers. */ +@implicitNotFound("Could not find an instance of UnorderedTraverse for ${F}") @typeclass trait UnorderedTraverse[F[_]] extends UnorderedFoldable[F] { def unorderedTraverse[G[_]: CommutativeApplicative, A, B](sa: F[A])(f: A => G[B]): G[F[B]] def unorderedSequence[G[_]: CommutativeApplicative, A](fga: F[G[A]]): G[F[A]] = unorderedTraverse(fga)(identity) } + +object UnorderedTraverse { + + /****************************************************************************/ + /* THE FOLLOWING CODE IS MANAGED BY SIMULACRUM; PLEASE DO NOT EDIT!!!! */ + /****************************************************************************/ + /** + * Summon an instance of [[UnorderedTraverse]] for `F`. + */ + @inline def apply[F[_]](implicit instance: UnorderedTraverse[F]): UnorderedTraverse[F] = instance + + trait Ops[F[_], A] { + type TypeClassType <: UnorderedTraverse[F] + def self: F[A] + val typeClassInstance: TypeClassType + def unorderedTraverse[G[_], B](f: A => G[B])(implicit ev$1: CommutativeApplicative[G]): G[F[B]] = + typeClassInstance.unorderedTraverse[G, A, B](self)(f) + def unorderedSequence[G[_], B](implicit ev$1: A <:< G[B], ev$2: CommutativeApplicative[G]): G[F[B]] = + typeClassInstance.unorderedSequence[G, B](self.asInstanceOf[F[G[B]]]) + } + trait AllOps[F[_], A] extends Ops[F, A] with UnorderedFoldable.AllOps[F, A] { + type TypeClassType <: UnorderedTraverse[F] + } + trait ToUnorderedTraverseOps { + implicit def toUnorderedTraverseOps[F[_], A](target: F[A])(implicit tc: UnorderedTraverse[F]): Ops[F, A] { + type TypeClassType = UnorderedTraverse[F] + } = new Ops[F, A] { + type TypeClassType = UnorderedTraverse[F] + val self: F[A] = target + val typeClassInstance: TypeClassType = tc + } + } + object nonInheritedOps extends ToUnorderedTraverseOps + object ops { + implicit def toAllUnorderedTraverseOps[F[_], A](target: F[A])(implicit tc: UnorderedTraverse[F]): AllOps[F, A] { + type TypeClassType = UnorderedTraverse[F] + } = new AllOps[F, A] { + type TypeClassType = UnorderedTraverse[F] + val self: F[A] = target + val typeClassInstance: TypeClassType = tc + } + } + + /****************************************************************************/ + /* END OF SIMULACRUM-MANAGED CODE */ + /****************************************************************************/ + +} diff --git a/core/src/main/scala/cats/arrow/Arrow.scala b/core/src/main/scala/cats/arrow/Arrow.scala index 017375b36b..a9f6926e9a 100644 --- a/core/src/main/scala/cats/arrow/Arrow.scala +++ b/core/src/main/scala/cats/arrow/Arrow.scala @@ -2,10 +2,12 @@ package cats package arrow import simulacrum.typeclass +import scala.annotation.implicitNotFound /** * Must obey the laws defined in cats.laws.ArrowLaws. */ +@implicitNotFound("Could not find an instance of Arrow for ${F}") @typeclass trait Arrow[F[_, _]] extends Category[F] with Strong[F] { self => /** @@ -69,3 +71,51 @@ import simulacrum.typeclass def merge[A, B, C](f: F[A, B], g: F[A, C]): F[A, (B, C)] = andThen(lift((x: A) => (x, x)), split(f, g)) } + +object Arrow { + + /****************************************************************************/ + /* THE FOLLOWING CODE IS MANAGED BY SIMULACRUM; PLEASE DO NOT EDIT!!!! */ + /****************************************************************************/ + /** + * Summon an instance of [[Arrow]] for `F`. + */ + @inline def apply[F[_, _]](implicit instance: Arrow[F]): Arrow[F] = instance + + trait Ops[F[_, _], A, B] { + type TypeClassType <: Arrow[F] + def self: F[A, B] + val typeClassInstance: TypeClassType + def split[C, D](g: F[C, D]): F[(A, C), (B, D)] = typeClassInstance.split[A, B, C, D](self, g) + def ***[C, D](g: F[C, D]): F[(A, C), (B, D)] = typeClassInstance.split[A, B, C, D](self, g) + def merge[C](g: F[A, C]): F[A, (B, C)] = typeClassInstance.merge[A, B, C](self, g) + def &&&[C](g: F[A, C]): F[A, (B, C)] = typeClassInstance.merge[A, B, C](self, g) + } + trait AllOps[F[_, _], A, B] extends Ops[F, A, B] with Category.AllOps[F, A, B] with Strong.AllOps[F, A, B] { + type TypeClassType <: Arrow[F] + } + trait ToArrowOps { + implicit def toArrowOps[F[_, _], A, B](target: F[A, B])(implicit tc: Arrow[F]): Ops[F, A, B] { + type TypeClassType = Arrow[F] + } = new Ops[F, A, B] { + type TypeClassType = Arrow[F] + val self: F[A, B] = target + val typeClassInstance: TypeClassType = tc + } + } + object nonInheritedOps extends ToArrowOps + object ops { + implicit def toAllArrowOps[F[_, _], A, B](target: F[A, B])(implicit tc: Arrow[F]): AllOps[F, A, B] { + type TypeClassType = Arrow[F] + } = new AllOps[F, A, B] { + type TypeClassType = Arrow[F] + val self: F[A, B] = target + val typeClassInstance: TypeClassType = tc + } + } + + /****************************************************************************/ + /* END OF SIMULACRUM-MANAGED CODE */ + /****************************************************************************/ + +} diff --git a/core/src/main/scala/cats/arrow/ArrowChoice.scala b/core/src/main/scala/cats/arrow/ArrowChoice.scala index c0e7870dbb..c01026829a 100644 --- a/core/src/main/scala/cats/arrow/ArrowChoice.scala +++ b/core/src/main/scala/cats/arrow/ArrowChoice.scala @@ -2,10 +2,12 @@ package cats package arrow import simulacrum.typeclass +import scala.annotation.implicitNotFound /** * Must obey the laws defined in cats.laws.ArrowChoiceLaws. */ +@implicitNotFound("Could not find an instance of ArrowChoice for ${F}") @typeclass trait ArrowChoice[F[_, _]] extends Arrow[F] with Choice[F] { self => /** @@ -41,3 +43,51 @@ import simulacrum.typeclass override def choice[A, B, C](f: F[A, C], g: F[B, C]): F[Either[A, B], C] = rmap(choose(f)(g))(_.fold(identity, identity)) } + +object ArrowChoice { + + /****************************************************************************/ + /* THE FOLLOWING CODE IS MANAGED BY SIMULACRUM; PLEASE DO NOT EDIT!!!! */ + /****************************************************************************/ + /** + * Summon an instance of [[ArrowChoice]] for `F`. + */ + @inline def apply[F[_, _]](implicit instance: ArrowChoice[F]): ArrowChoice[F] = instance + + trait Ops[F[_, _], A, B] { + type TypeClassType <: ArrowChoice[F] + def self: F[A, B] + val typeClassInstance: TypeClassType + def choose[C, D](g: F[C, D]): F[Either[A, C], Either[B, D]] = typeClassInstance.choose[A, C, B, D](self)(g) + def +++[C, D](g: F[C, D]): F[Either[A, C], Either[B, D]] = typeClassInstance.choose[A, C, B, D](self)(g) + def left[C]: F[Either[A, C], Either[B, C]] = typeClassInstance.left[A, B, C](self) + def right[C]: F[Either[C, A], Either[C, B]] = typeClassInstance.right[A, B, C](self) + } + trait AllOps[F[_, _], A, B] extends Ops[F, A, B] with Arrow.AllOps[F, A, B] with Choice.AllOps[F, A, B] { + type TypeClassType <: ArrowChoice[F] + } + trait ToArrowChoiceOps { + implicit def toArrowChoiceOps[F[_, _], A, B](target: F[A, B])(implicit tc: ArrowChoice[F]): Ops[F, A, B] { + type TypeClassType = ArrowChoice[F] + } = new Ops[F, A, B] { + type TypeClassType = ArrowChoice[F] + val self: F[A, B] = target + val typeClassInstance: TypeClassType = tc + } + } + object nonInheritedOps extends ToArrowChoiceOps + object ops { + implicit def toAllArrowChoiceOps[F[_, _], A, B](target: F[A, B])(implicit tc: ArrowChoice[F]): AllOps[F, A, B] { + type TypeClassType = ArrowChoice[F] + } = new AllOps[F, A, B] { + type TypeClassType = ArrowChoice[F] + val self: F[A, B] = target + val typeClassInstance: TypeClassType = tc + } + } + + /****************************************************************************/ + /* END OF SIMULACRUM-MANAGED CODE */ + /****************************************************************************/ + +} diff --git a/core/src/main/scala/cats/arrow/Category.scala b/core/src/main/scala/cats/arrow/Category.scala index abd05ccab0..198cbdbfa4 100644 --- a/core/src/main/scala/cats/arrow/Category.scala +++ b/core/src/main/scala/cats/arrow/Category.scala @@ -2,10 +2,12 @@ package cats package arrow import simulacrum.typeclass +import scala.annotation.implicitNotFound /** * Must obey the laws defined in cats.laws.CategoryLaws. */ +@implicitNotFound("Could not find an instance of Category for ${F}") @typeclass trait Category[F[_, _]] extends Compose[F] { self => def id[A]: F[A, A] @@ -22,3 +24,47 @@ import simulacrum.typeclass def combine(f1: F[A, A], f2: F[A, A]): F[A, A] = self.compose(f1, f2) } } + +object Category { + + /****************************************************************************/ + /* THE FOLLOWING CODE IS MANAGED BY SIMULACRUM; PLEASE DO NOT EDIT!!!! */ + /****************************************************************************/ + /** + * Summon an instance of [[Category]] for `F`. + */ + @inline def apply[F[_, _]](implicit instance: Category[F]): Category[F] = instance + + trait Ops[F[_, _], A, B] { + type TypeClassType <: Category[F] + def self: F[A, B] + val typeClassInstance: TypeClassType + } + trait AllOps[F[_, _], A, B] extends Ops[F, A, B] with Compose.AllOps[F, A, B] { + type TypeClassType <: Category[F] + } + trait ToCategoryOps { + implicit def toCategoryOps[F[_, _], A, B](target: F[A, B])(implicit tc: Category[F]): Ops[F, A, B] { + type TypeClassType = Category[F] + } = new Ops[F, A, B] { + type TypeClassType = Category[F] + val self: F[A, B] = target + val typeClassInstance: TypeClassType = tc + } + } + object nonInheritedOps extends ToCategoryOps + object ops { + implicit def toAllCategoryOps[F[_, _], A, B](target: F[A, B])(implicit tc: Category[F]): AllOps[F, A, B] { + type TypeClassType = Category[F] + } = new AllOps[F, A, B] { + type TypeClassType = Category[F] + val self: F[A, B] = target + val typeClassInstance: TypeClassType = tc + } + } + + /****************************************************************************/ + /* END OF SIMULACRUM-MANAGED CODE */ + /****************************************************************************/ + +} diff --git a/core/src/main/scala/cats/arrow/Choice.scala b/core/src/main/scala/cats/arrow/Choice.scala index e5ee051e0b..da97eb7be2 100644 --- a/core/src/main/scala/cats/arrow/Choice.scala +++ b/core/src/main/scala/cats/arrow/Choice.scala @@ -2,7 +2,9 @@ package cats package arrow import simulacrum.typeclass +import scala.annotation.implicitNotFound +@implicitNotFound("Could not find an instance of Choice for ${F}") @typeclass trait Choice[F[_, _]] extends Category[F] { /** @@ -45,3 +47,49 @@ import simulacrum.typeclass */ def codiagonal[A]: F[Either[A, A], A] = choice(id, id) } + +object Choice { + + /****************************************************************************/ + /* THE FOLLOWING CODE IS MANAGED BY SIMULACRUM; PLEASE DO NOT EDIT!!!! */ + /****************************************************************************/ + /** + * Summon an instance of [[Choice]] for `F`. + */ + @inline def apply[F[_, _]](implicit instance: Choice[F]): Choice[F] = instance + + trait Ops[F[_, _], A, B] { + type TypeClassType <: Choice[F] + def self: F[A, B] + val typeClassInstance: TypeClassType + def choice[C](g: F[C, B]): F[Either[A, C], B] = typeClassInstance.choice[A, C, B](self, g) + def |||[C](g: F[C, B]): F[Either[A, C], B] = typeClassInstance.choice[A, C, B](self, g) + } + trait AllOps[F[_, _], A, B] extends Ops[F, A, B] with Category.AllOps[F, A, B] { + type TypeClassType <: Choice[F] + } + trait ToChoiceOps { + implicit def toChoiceOps[F[_, _], A, B](target: F[A, B])(implicit tc: Choice[F]): Ops[F, A, B] { + type TypeClassType = Choice[F] + } = new Ops[F, A, B] { + type TypeClassType = Choice[F] + val self: F[A, B] = target + val typeClassInstance: TypeClassType = tc + } + } + object nonInheritedOps extends ToChoiceOps + object ops { + implicit def toAllChoiceOps[F[_, _], A, B](target: F[A, B])(implicit tc: Choice[F]): AllOps[F, A, B] { + type TypeClassType = Choice[F] + } = new AllOps[F, A, B] { + type TypeClassType = Choice[F] + val self: F[A, B] = target + val typeClassInstance: TypeClassType = tc + } + } + + /****************************************************************************/ + /* END OF SIMULACRUM-MANAGED CODE */ + /****************************************************************************/ + +} diff --git a/core/src/main/scala/cats/arrow/CommutativeArrow.scala b/core/src/main/scala/cats/arrow/CommutativeArrow.scala index 1e48aa71df..03fc20fdec 100644 --- a/core/src/main/scala/cats/arrow/CommutativeArrow.scala +++ b/core/src/main/scala/cats/arrow/CommutativeArrow.scala @@ -2,6 +2,7 @@ package cats package arrow import simulacrum.typeclass +import scala.annotation.implicitNotFound /** * In a Commutative Arrow F[_, _], the split operation (or `***`) is commutative, @@ -9,4 +10,51 @@ import simulacrum.typeclass * * Must obey the laws in CommutativeArrowLaws */ +@implicitNotFound("Could not find an instance of CommutativeArrow for ${F}") @typeclass trait CommutativeArrow[F[_, _]] extends Arrow[F] + +object CommutativeArrow { + + /****************************************************************************/ + /* THE FOLLOWING CODE IS MANAGED BY SIMULACRUM; PLEASE DO NOT EDIT!!!! */ + /****************************************************************************/ + /** + * Summon an instance of [[CommutativeArrow]] for `F`. + */ + @inline def apply[F[_, _]](implicit instance: CommutativeArrow[F]): CommutativeArrow[F] = instance + + trait Ops[F[_, _], A, B] { + type TypeClassType <: CommutativeArrow[F] + def self: F[A, B] + val typeClassInstance: TypeClassType + } + trait AllOps[F[_, _], A, B] extends Ops[F, A, B] with Arrow.AllOps[F, A, B] { + type TypeClassType <: CommutativeArrow[F] + } + trait ToCommutativeArrowOps { + implicit def toCommutativeArrowOps[F[_, _], A, B](target: F[A, B])(implicit tc: CommutativeArrow[F]): Ops[F, A, B] { + type TypeClassType = CommutativeArrow[F] + } = new Ops[F, A, B] { + type TypeClassType = CommutativeArrow[F] + val self: F[A, B] = target + val typeClassInstance: TypeClassType = tc + } + } + object nonInheritedOps extends ToCommutativeArrowOps + object ops { + implicit def toAllCommutativeArrowOps[F[_, _], A, B]( + target: F[A, B] + )(implicit tc: CommutativeArrow[F]): AllOps[F, A, B] { + type TypeClassType = CommutativeArrow[F] + } = new AllOps[F, A, B] { + type TypeClassType = CommutativeArrow[F] + val self: F[A, B] = target + val typeClassInstance: TypeClassType = tc + } + } + + /****************************************************************************/ + /* END OF SIMULACRUM-MANAGED CODE */ + /****************************************************************************/ + +} diff --git a/core/src/main/scala/cats/arrow/Compose.scala b/core/src/main/scala/cats/arrow/Compose.scala index c520eb5f19..9eb25cfd80 100644 --- a/core/src/main/scala/cats/arrow/Compose.scala +++ b/core/src/main/scala/cats/arrow/Compose.scala @@ -2,6 +2,7 @@ package cats package arrow import simulacrum.typeclass +import scala.annotation.implicitNotFound /** * Must obey the laws defined in cats.laws.ComposeLaws. @@ -18,7 +19,8 @@ import simulacrum.typeclass * res1: Int = 301 * }}} */ -@typeclass trait Compose[F[_, _]] { self => +@implicitNotFound("Could not find an instance of Compose for ${F}") +@typeclass trait Compose[F[_, _]] extends Serializable { self => @simulacrum.op("<<<", alias = true) def compose[A, B, C](f: F[B, C], g: F[A, B]): F[A, C] @@ -37,3 +39,49 @@ import simulacrum.typeclass def combine(f1: F[A, A], f2: F[A, A]): F[A, A] = self.compose(f1, f2) } } + +object Compose { + + /****************************************************************************/ + /* THE FOLLOWING CODE IS MANAGED BY SIMULACRUM; PLEASE DO NOT EDIT!!!! */ + /****************************************************************************/ + /** + * Summon an instance of [[Compose]] for `F`. + */ + @inline def apply[F[_, _]](implicit instance: Compose[F]): Compose[F] = instance + + trait Ops[F[_, _], A, B] { + type TypeClassType <: Compose[F] + def self: F[A, B] + val typeClassInstance: TypeClassType + def compose[C](g: F[C, A]): F[C, B] = typeClassInstance.compose[C, A, B](self, g) + def <<<[C](g: F[C, A]): F[C, B] = typeClassInstance.compose[C, A, B](self, g) + def andThen[C](g: F[B, C]): F[A, C] = typeClassInstance.andThen[A, B, C](self, g) + def >>>[C](g: F[B, C]): F[A, C] = typeClassInstance.andThen[A, B, C](self, g) + } + trait AllOps[F[_, _], A, B] extends Ops[F, A, B] + trait ToComposeOps { + implicit def toComposeOps[F[_, _], A, B](target: F[A, B])(implicit tc: Compose[F]): Ops[F, A, B] { + type TypeClassType = Compose[F] + } = new Ops[F, A, B] { + type TypeClassType = Compose[F] + val self: F[A, B] = target + val typeClassInstance: TypeClassType = tc + } + } + object nonInheritedOps extends ToComposeOps + object ops { + implicit def toAllComposeOps[F[_, _], A, B](target: F[A, B])(implicit tc: Compose[F]): AllOps[F, A, B] { + type TypeClassType = Compose[F] + } = new AllOps[F, A, B] { + type TypeClassType = Compose[F] + val self: F[A, B] = target + val typeClassInstance: TypeClassType = tc + } + } + + /****************************************************************************/ + /* END OF SIMULACRUM-MANAGED CODE */ + /****************************************************************************/ + +} diff --git a/core/src/main/scala/cats/arrow/Profunctor.scala b/core/src/main/scala/cats/arrow/Profunctor.scala index 31ca4281ba..7247f72e87 100644 --- a/core/src/main/scala/cats/arrow/Profunctor.scala +++ b/core/src/main/scala/cats/arrow/Profunctor.scala @@ -2,6 +2,7 @@ package cats package arrow import simulacrum.typeclass +import scala.annotation.implicitNotFound /** * A [[Profunctor]] is a [[Contravariant]] functor on its first type parameter @@ -9,7 +10,8 @@ import simulacrum.typeclass * * Must obey the laws defined in cats.laws.ProfunctorLaws. */ -@typeclass trait Profunctor[F[_, _]] { self => +@implicitNotFound("Could not find an instance of Profunctor for ${F}") +@typeclass trait Profunctor[F[_, _]] extends Serializable { self => /** * Contramap on the first type parameter and map on the second type parameter @@ -40,3 +42,48 @@ 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 { + + /****************************************************************************/ + /* THE FOLLOWING CODE IS MANAGED BY SIMULACRUM; PLEASE DO NOT EDIT!!!! */ + /****************************************************************************/ + /** + * Summon an instance of [[Profunctor]] for `F`. + */ + @inline def apply[F[_, _]](implicit instance: Profunctor[F]): Profunctor[F] = instance + + trait Ops[F[_, _], A, B] { + type TypeClassType <: Profunctor[F] + def self: F[A, B] + val typeClassInstance: TypeClassType + def dimap[C, D](f: C => A)(g: B => D): F[C, D] = typeClassInstance.dimap[A, B, C, D](self)(f)(g) + def lmap[C](f: C => A): F[C, B] = typeClassInstance.lmap[A, B, C](self)(f) + def rmap[C](f: B => C): F[A, C] = typeClassInstance.rmap[A, B, C](self)(f) + } + trait AllOps[F[_, _], A, B] extends Ops[F, A, B] + trait ToProfunctorOps { + implicit def toProfunctorOps[F[_, _], A, B](target: F[A, B])(implicit tc: Profunctor[F]): Ops[F, A, B] { + type TypeClassType = Profunctor[F] + } = new Ops[F, A, B] { + type TypeClassType = Profunctor[F] + val self: F[A, B] = target + val typeClassInstance: TypeClassType = tc + } + } + object nonInheritedOps extends ToProfunctorOps + object ops { + implicit def toAllProfunctorOps[F[_, _], A, B](target: F[A, B])(implicit tc: Profunctor[F]): AllOps[F, A, B] { + type TypeClassType = Profunctor[F] + } = new AllOps[F, A, B] { + type TypeClassType = Profunctor[F] + val self: F[A, B] = target + val typeClassInstance: TypeClassType = tc + } + } + + /****************************************************************************/ + /* END OF SIMULACRUM-MANAGED CODE */ + /****************************************************************************/ + +} diff --git a/core/src/main/scala/cats/arrow/Strong.scala b/core/src/main/scala/cats/arrow/Strong.scala index 46629700a8..e81e6db7ef 100644 --- a/core/src/main/scala/cats/arrow/Strong.scala +++ b/core/src/main/scala/cats/arrow/Strong.scala @@ -2,10 +2,12 @@ package cats package arrow import simulacrum.typeclass +import scala.annotation.implicitNotFound /** * Must obey the laws defined in cats.laws.StrongLaws. */ +@implicitNotFound("Could not find an instance of Strong for ${F}") @typeclass trait Strong[F[_, _]] extends Profunctor[F] { /** @@ -38,3 +40,49 @@ import simulacrum.typeclass */ def second[A, B, C](fa: F[A, B]): F[(C, A), (C, B)] } + +object Strong { + + /****************************************************************************/ + /* THE FOLLOWING CODE IS MANAGED BY SIMULACRUM; PLEASE DO NOT EDIT!!!! */ + /****************************************************************************/ + /** + * Summon an instance of [[Strong]] for `F`. + */ + @inline def apply[F[_, _]](implicit instance: Strong[F]): Strong[F] = instance + + trait Ops[F[_, _], A, B] { + type TypeClassType <: Strong[F] + def self: F[A, B] + val typeClassInstance: TypeClassType + def first[C]: F[(A, C), (B, C)] = typeClassInstance.first[A, B, C](self) + def second[C]: F[(C, A), (C, B)] = typeClassInstance.second[A, B, C](self) + } + trait AllOps[F[_, _], A, B] extends Ops[F, A, B] with Profunctor.AllOps[F, A, B] { + type TypeClassType <: Strong[F] + } + trait ToStrongOps { + implicit def toStrongOps[F[_, _], A, B](target: F[A, B])(implicit tc: Strong[F]): Ops[F, A, B] { + type TypeClassType = Strong[F] + } = new Ops[F, A, B] { + type TypeClassType = Strong[F] + val self: F[A, B] = target + val typeClassInstance: TypeClassType = tc + } + } + object nonInheritedOps extends ToStrongOps + object ops { + implicit def toAllStrongOps[F[_, _], A, B](target: F[A, B])(implicit tc: Strong[F]): AllOps[F, A, B] { + type TypeClassType = Strong[F] + } = new AllOps[F, A, B] { + type TypeClassType = Strong[F] + val self: F[A, B] = target + val typeClassInstance: TypeClassType = tc + } + } + + /****************************************************************************/ + /* END OF SIMULACRUM-MANAGED CODE */ + /****************************************************************************/ + +}