diff --git a/core/src/main/scala/cats/Applicative.scala b/core/src/main/scala/cats/Applicative.scala index 3c3eb683f02..41532316cfa 100644 --- a/core/src/main/scala/cats/Applicative.scala +++ b/core/src/main/scala/cats/Applicative.scala @@ -29,6 +29,9 @@ import cats.std.list._ */ def pureEval[A](x: Eval[A]): F[A] = pure(x.value) + override def map[A, B](fa: F[A])(f: A => B): F[B] = + ap(pure(f))(fa) + /** * Given `fa` and `n`, apply `fa` `n` times to construct an `F[List[A]]` value. */ diff --git a/core/src/main/scala/cats/Apply.scala b/core/src/main/scala/cats/Apply.scala index 87e652278ee..3e41bee3ff9 100644 --- a/core/src/main/scala/cats/Apply.scala +++ b/core/src/main/scala/cats/Apply.scala @@ -16,6 +16,9 @@ trait Apply[F[_]] extends Functor[F] with Cartesian[F] with ApplyArityFunctions[ */ def ap[A, B](ff: F[A => B])(fa: F[A]): F[B] + override def product[A, B](fa: F[A], fb: F[B]): F[(A, B)] = + map2(fa, fb)((_, _)) + /** * ap2 is a binary version of ap, defined in terms of ap. */ @@ -56,7 +59,6 @@ trait CompositeApply[F[_], G[_]] def ap[A, B](f: F[G[A => B]])(fa: F[G[A]]): F[G[B]] = F.ap(F.map(f)(gab => G.ap(gab)(_)))(fa) - def product[A, B](fa: F[G[A]], fb: F[G[B]]): F[G[(A, B)]] = + override def product[A, B](fa: F[G[A]], fb: F[G[B]]): F[G[(A, B)]] = F.map2(fa, fb)(G.product) - } diff --git a/core/src/main/scala/cats/data/Const.scala b/core/src/main/scala/cats/data/Const.scala index 692f6436f6e..32fc1e3b91c 100644 --- a/core/src/main/scala/cats/data/Const.scala +++ b/core/src/main/scala/cats/data/Const.scala @@ -98,10 +98,10 @@ private[data] sealed abstract class ConstInstances0 extends ConstInstances1 { def ap[A, B](f: Const[C, A => B])(fa: Const[C, A]): Const[C, B] = f.retag[B] combine fa.retag[B] - def map[A, B](fa: Const[C, A])(f: A => B): Const[C, B] = + override def map[A, B](fa: Const[C, A])(f: A => B): Const[C, B] = fa.retag[B] - def product[A, B](fa: Const[C, A], fb: Const[C, B]): Const[C, (A, B)] = + override def product[A, B](fa: Const[C, A], fb: Const[C, B]): Const[C, (A, B)] = fa.retag[(A, B)] combine fb.retag[(A, B)] } } @@ -116,7 +116,7 @@ private[data] sealed abstract class ConstInstances1 { def ap[A, B](f: Const[C, A => B])(fa: Const[C, A]): Const[C, B] = fa.retag[B] combine f.retag[B] - def product[A, B](fa: Const[C, A], fb: Const[C, B]): Const[C, (A, B)] = + override def product[A, B](fa: Const[C, A], fb: Const[C, B]): Const[C, (A, B)] = fa.retag[(A, B)] combine fb.retag[(A, B)] def map[A, B](fa: Const[C, A])(f: A => B): Const[C, B] = diff --git a/core/src/main/scala/cats/data/Func.scala b/core/src/main/scala/cats/data/Func.scala index f5f3a742143..54487031ff4 100644 --- a/core/src/main/scala/cats/data/Func.scala +++ b/core/src/main/scala/cats/data/Func.scala @@ -54,7 +54,7 @@ private[data] abstract class FuncInstances1 { sealed trait FuncFunctor[F[_], C] extends Functor[Lambda[X => Func[F, C, X]]] { def F: Functor[F] - def map[A, B](fa: Func[F, C, A])(f: A => B): Func[F, C, B] = + override def map[A, B](fa: Func[F, C, A])(f: A => B): Func[F, C, B] = fa.map(f)(F) } @@ -62,7 +62,7 @@ sealed trait FuncApply[F[_], C] extends Apply[Lambda[X => Func[F, C, X]]] with F def F: Apply[F] def ap[A, B](f: Func[F, C, A => B])(fa: Func[F, C, A]): Func[F, C, B] = Func.func(c => F.ap(f.run(c))(fa.run(c))) - def product[A, B](fa: Func[F, C, A], fb: Func[F, C, B]): Func[F, C, (A, B)] = + override def product[A, B](fa: Func[F, C, A], fb: Func[F, C, B]): Func[F, C, (A, B)] = Func.func(c => F.product(fa.run(c), fb.run(c))) } @@ -121,11 +121,11 @@ private[data] abstract class AppFuncInstances { private[data] sealed trait AppFuncApplicative[F[_], C] extends Applicative[Lambda[X => AppFunc[F, C, X]]] { def F: Applicative[F] - def map[A, B](fa: AppFunc[F, C, A])(f: A => B): AppFunc[F, C, B] = + override def map[A, B](fa: AppFunc[F, C, A])(f: A => B): AppFunc[F, C, B] = fa.map(f) def ap[A, B](f: AppFunc[F, C, A => B])(fa: AppFunc[F, C, A]): AppFunc[F, C, B] = Func.appFunc[F, C, B](c => F.ap(f.run(c))(fa.run(c)))(F) - def product[A, B](fa: AppFunc[F, C, A], fb: AppFunc[F, C, B]): AppFunc[F, C, (A, B)] = + override def product[A, B](fa: AppFunc[F, C, A], fb: AppFunc[F, C, B]): AppFunc[F, C, (A, B)] = Func.appFunc[F, C, (A, B)](c => F.product(fa.run(c), fb.run(c)))(F) def pure[A](a: A): AppFunc[F, C, A] = Func.appFunc[F, C, A](c => F.pure(a))(F) diff --git a/core/src/main/scala/cats/data/Kleisli.scala b/core/src/main/scala/cats/data/Kleisli.scala index f0e827d1e9a..b548a60cfd3 100644 --- a/core/src/main/scala/cats/data/Kleisli.scala +++ b/core/src/main/scala/cats/data/Kleisli.scala @@ -153,10 +153,10 @@ private[data] sealed abstract class KleisliInstances1 extends KleisliInstances2 def ap[B, C](f: Kleisli[F, A, B => C])(fa: Kleisli[F, A, B]): Kleisli[F, A, C] = fa(f) - def map[B, C](fb: Kleisli[F, A, B])(f: B => C): Kleisli[F, A, C] = + override def map[B, C](fb: Kleisli[F, A, B])(f: B => C): Kleisli[F, A, C] = fb.map(f) - def product[B, C](fb: Kleisli[F, A, B], fc: Kleisli[F, A, C]): Kleisli[F, A, (B, C)] = + override def product[B, C](fb: Kleisli[F, A, B], fc: Kleisli[F, A, C]): Kleisli[F, A, (B, C)] = Kleisli(a => Applicative[F].product(fb.run(a), fc.run(a))) } } @@ -166,7 +166,7 @@ private[data] sealed abstract class KleisliInstances2 extends KleisliInstances3 def ap[B, C](f: Kleisli[F, A, B => C])(fa: Kleisli[F, A, B]): Kleisli[F, A, C] = fa(f) - def product[B, C](fb: Kleisli[F, A, B], fc: Kleisli[F, A, C]): Kleisli[F, A, (B, C)] = + override def product[B, C](fb: Kleisli[F, A, B], fc: Kleisli[F, A, C]): Kleisli[F, A, (B, C)] = Kleisli(a => Apply[F].product(fb.run(a), fc.run(a))) def map[B, C](fa: Kleisli[F, A, B])(f: B => C): Kleisli[F, A, C] = diff --git a/core/src/main/scala/cats/data/Prod.scala b/core/src/main/scala/cats/data/Prod.scala index f368e1abef5..c50fc321dbc 100644 --- a/core/src/main/scala/cats/data/Prod.scala +++ b/core/src/main/scala/cats/data/Prod.scala @@ -71,7 +71,7 @@ private[data] sealed abstract class ProdInstances4 { sealed trait ProdFunctor[F[_], G[_]] extends Functor[Lambda[X => Prod[F, G, X]]] { def F: Functor[F] def G: Functor[G] - def map[A, B](fa: Prod[F, G, A])(f: A => B): Prod[F, G, B] = Prod(F.map(fa.first)(f), G.map(fa.second)(f)) + override def map[A, B](fa: Prod[F, G, A])(f: A => B): Prod[F, G, B] = Prod(F.map(fa.first)(f), G.map(fa.second)(f)) } sealed trait ProdApply[F[_], G[_]] extends Apply[Lambda[X => Prod[F, G, X]]] with ProdFunctor[F, G] { @@ -79,7 +79,7 @@ sealed trait ProdApply[F[_], G[_]] extends Apply[Lambda[X => Prod[F, G, X]]] wit def G: Apply[G] def ap[A, B](f: Prod[F, G, A => B])(fa: Prod[F, G, A]): Prod[F, G, B] = Prod(F.ap(f.first)(fa.first), G.ap(f.second)(fa.second)) - def product[A, B](fa: Prod[F, G, A], fb: Prod[F, G, B]): Prod[F, G, (A, B)] = + override def product[A, B](fa: Prod[F, G, A], fb: Prod[F, G, B]): Prod[F, G, (A, B)] = Prod(F.product(fa.first, fb.first), G.product(fa.second, fb.second)) } diff --git a/core/src/main/scala/cats/data/Validated.scala b/core/src/main/scala/cats/data/Validated.scala index 3242858dfc9..22f97f78a6e 100644 --- a/core/src/main/scala/cats/data/Validated.scala +++ b/core/src/main/scala/cats/data/Validated.scala @@ -254,7 +254,7 @@ private[data] sealed abstract class ValidatedInstances extends ValidatedInstance def ap[A,B](f: Validated[E,A=>B])(fa: Validated[E,A]): Validated[E, B] = fa.ap(f)(E) - def product[A, B](fa: Validated[E, A], fb: Validated[E, B]): Validated[E, (A, B)] = + override def product[A, B](fa: Validated[E, A], fb: Validated[E, B]): Validated[E, (A, B)] = fa.product(fb)(E) def handleErrorWith[A](fa: Validated[E, A])(f: E => Validated[E, A]): Validated[E, A] = diff --git a/core/src/main/scala/cats/data/WriterT.scala b/core/src/main/scala/cats/data/WriterT.scala index dacba37d286..97b203ae266 100644 --- a/core/src/main/scala/cats/data/WriterT.scala +++ b/core/src/main/scala/cats/data/WriterT.scala @@ -171,7 +171,7 @@ private[data] sealed trait WriterTApply[F[_], L] extends WriterTFunctor[F, L] wi def ap[A, B](f: WriterT[F, L, A => B])(fa: WriterT[F, L, A]): WriterT[F, L, B] = fa ap f - def product[A, B](fa: WriterT[F, L, A], fb: WriterT[F, L, B]): WriterT[F, L, (A, B)] = + override def product[A, B](fa: WriterT[F, L, A], fb: WriterT[F, L, B]): WriterT[F, L, (A, B)] = WriterT(F0.map(F0.product(fa.run, fb.run)) { case ((l1, a), (l2, b)) => (L0.combine(l1, l2), (a, b)) }) } diff --git a/core/src/main/scala/cats/free/FreeApplicative.scala b/core/src/main/scala/cats/free/FreeApplicative.scala index d21d64ea116..ad9c57aac48 100644 --- a/core/src/main/scala/cats/free/FreeApplicative.scala +++ b/core/src/main/scala/cats/free/FreeApplicative.scala @@ -79,8 +79,8 @@ object FreeApplicative { implicit final def freeApplicative[S[_]]: Applicative[FA[S, ?]] = { new Applicative[FA[S, ?]] { - def product[A, B](fa: FA[S, A], fb: FA[S, B]): FA[S, (A, B)] = ap(fa.map((a: A) => (b: B) => (a, b)))(fb) - def map[A, B](fa: FA[S, A])(f: A => B): FA[S, B] = fa.map(f) + override def product[A, B](fa: FA[S, A], fb: FA[S, B]): FA[S, (A, B)] = ap(fa.map((a: A) => (b: B) => (a, b)))(fb) + override def map[A, B](fa: FA[S, A])(f: A => B): FA[S, B] = fa.map(f) override def ap[A, B](f: FA[S, A => B])(fa: FA[S, A]): FA[S, B] = fa.ap(f) def pure[A](a: A): FA[S, A] = Pure(a) } diff --git a/docs/src/main/tut/validated.md b/docs/src/main/tut/validated.md index bb52438e387..724aeaaa2ec 100644 --- a/docs/src/main/tut/validated.md +++ b/docs/src/main/tut/validated.md @@ -199,9 +199,6 @@ implicit def validatedApplicative[E : Semigroup]: Applicative[Validated[E, ?]] = } def pure[A](x: A): Validated[E, A] = Validated.valid(x) - def map[A, B](fa: Validated[E, A])(f: A => B): Validated[E, B] = fa.map(f) - def product[A, B](fa: Validated[E, A], fb: Validated[E, B]): Validated[E, (A, B)] = - ap(fa.map(a => (b: B) => (a, b)))(fb) } ``` diff --git a/laws/src/main/scala/cats/laws/TraverseLaws.scala b/laws/src/main/scala/cats/laws/TraverseLaws.scala index 9acbbfe11c5..5ae13c2c212 100644 --- a/laws/src/main/scala/cats/laws/TraverseLaws.scala +++ b/laws/src/main/scala/cats/laws/TraverseLaws.scala @@ -44,11 +44,11 @@ trait TraverseLaws[F[_]] extends FunctorLaws[F] with FoldableLaws[F] { val (fm, fn) = f (M.ap(fm)(fam), N.ap(fn)(fan)) } - def map[X, Y](fx: MN[X])(f: X => Y): MN[Y] = { + override def map[X, Y](fx: MN[X])(f: X => Y): MN[Y] = { val (mx, nx) = fx (M.map(mx)(f), N.map(nx)(f)) } - def product[X, Y](fx: MN[X], fy: MN[Y]): MN[(X, Y)] = { + override def product[X, Y](fx: MN[X], fy: MN[Y]): MN[(X, Y)] = { val (mx, nx) = fx val (my, ny) = fy (M.product(mx, my), N.product(nx, ny))