From b40cc923d6d6823f9959c8b70958442ee19a7432 Mon Sep 17 00:00:00 2001 From: Vikraman Choudhury Date: Tue, 27 Oct 2015 18:46:32 -0400 Subject: [PATCH 01/40] Add IdT, the identity monad transformer --- core/src/main/scala/cats/data/IdT.scala | 107 ++++++++++++++++++++++++ 1 file changed, 107 insertions(+) create mode 100644 core/src/main/scala/cats/data/IdT.scala diff --git a/core/src/main/scala/cats/data/IdT.scala b/core/src/main/scala/cats/data/IdT.scala new file mode 100644 index 0000000000..bed9c19440 --- /dev/null +++ b/core/src/main/scala/cats/data/IdT.scala @@ -0,0 +1,107 @@ +package cats +package data + +/** + * `IdT[F[_], A]` is the identity monad transformer. + */ +final case class IdT[F[_], A](value: F[A]) { + + def map[B](f: A => B)(implicit F: Functor[F]): IdT[F, B] = + IdT(F.map(value)(f)) + + def flatMap[B](f: A => IdT[F, B])(implicit F: FlatMap[F]): IdT[F, B] = + IdT(F.flatMap(value)(f.andThen(_.value))) + + def flatMapF[B](f: A => F[B])(implicit F: FlatMap[F]): IdT[F, B] = + IdT(F.flatMap(value)(f)) + + def foldLeft[B](b: B)(f: (B, A) => B)(implicit F: Foldable[F]): B = + F.foldLeft(value, b)(f) + + def foldRight[B](lb: Eval[B])(f: (A, Eval[B]) => Eval[B])(implicit F: Foldable[F]): Eval[B] = + F.foldRight(value, lb)(f) + + def traverse[G[_], B](f: A => G[B])(implicit F: Traverse[F], G: Applicative[G]): G[IdT[F, B]] = + G.map(F.traverse(value)(f))(IdT(_)) + + def ap[B](f: IdT[F, A => B])(implicit F: Apply[F]): IdT[F, B] = + IdT(F.ap(value)(f.value)) + +} + +object IdT extends IdTInstances { + + def pure[F[_], A](a: A)(implicit F: Applicative[F]): IdT[F, A] = + IdT(F.pure(a)) +} + +private[data] sealed trait IdTFunctor[F[_]] extends Functor[IdT[F, ?]] { + implicit val F0: Functor[F] + + def map[A, B](fa: IdT[F, A])(f: A => B): IdT[F, B] = + fa.map(f) +} + +private[data] sealed trait IdTMonad[F[_]] extends Monad[IdT[F, ?]] { + implicit val F0: Monad[F] + + def pure[A](a: A): IdT[F, A] = + IdT.pure(a) + + def flatMap[A, B](fa: IdT[F, A])(f: A => IdT[F, B]): IdT[F, B] = + fa.flatMap(f) +} + +private[data] sealed trait IdTFoldable[F[_]] extends Foldable[IdT[F, ?]] { + implicit val F0: Foldable[F] + + def foldLeft[A, B](fa: IdT[F, A], b: B)(f: (B, A) => B): B = + fa.foldLeft(b)(f) + + def foldRight[A, B](fa: IdT[F, A], lb: Eval[B])(f: (A, Eval[B]) => Eval[B]): Eval[B] = + fa.foldRight(lb)(f) +} + +private[data] sealed trait IdTTraverse[F[_]] extends Traverse[IdT[F, ?]] with IdTFoldable[F] { + implicit val F0: Traverse[F] + + def traverse[G[_]: Applicative, A, B](fa: IdT[F, A])(f: A => G[B]): G[IdT[F, B]] = + fa.traverse(f) +} + +private[data] sealed abstract class IdTInstances1 { + implicit def idTFunctor[F[_]](implicit F: Functor[F]): Functor[IdT[F, ?]] = + new IdTFunctor[F] { + implicit val F0: Functor[F] = F + } +} + +private[data] sealed abstract class IdTInstances0 extends IdTInstances1 { + + implicit def idTMonad[F[_]](implicit F: Monad[F]): Monad[IdT[F, ?]] = + new IdTMonad[F] { + implicit val F0: Monad[F] = F + } + + implicit def idTFoldable[F[_]](implicit F: Foldable[F]): Foldable[IdT[F, ?]] = + new IdTFoldable[F] { + implicit val F0: Foldable[F] = F + } + + implicit def idTOrder[F[_], A](implicit F: Order[F[A]]): Order[IdT[F, A]] = + F.on(_.value) +} + +private[data] sealed abstract class IdTInstances extends IdTInstances0 { + + implicit def idTTraverse[F[_]](implicit F: Traverse[F]): Traverse[IdT[F, ?]] = + new IdTTraverse[F] { + implicit val F0: Traverse[F] = F + } + + implicit def idTEq[F[_], A](implicit F: Eq[F[A]]): Eq[IdT[F, A]] = + F.on(_.value) + + implicit def idTShow[F[_], A](implicit F: Show[F[A]]): Show[IdT[F, A]] = + functor.Contravariant[Show].contramap(F)(_.value) +} From 17a94ca435de326fb47ec35ea1efa851fef0c5ab Mon Sep 17 00:00:00 2001 From: Vikraman Choudhury Date: Tue, 24 Nov 2015 04:26:21 -0500 Subject: [PATCH 02/40] Add tests for IdT --- .../cats/laws/discipline/Arbitrary.scala | 3 +++ .../src/test/scala/cats/tests/IdTTests.scala | 22 +++++++++++++++++++ 2 files changed, 25 insertions(+) create mode 100644 tests/src/test/scala/cats/tests/IdTTests.scala diff --git a/laws/src/main/scala/cats/laws/discipline/Arbitrary.scala b/laws/src/main/scala/cats/laws/discipline/Arbitrary.scala index ee71f8d6aa..a5cabdb8df 100644 --- a/laws/src/main/scala/cats/laws/discipline/Arbitrary.scala +++ b/laws/src/main/scala/cats/laws/discipline/Arbitrary.scala @@ -38,6 +38,9 @@ object arbitrary extends ArbitraryInstances0 { implicit def optionTArbitrary[F[_], A](implicit F: Arbitrary[F[Option[A]]]): Arbitrary[OptionT[F, A]] = Arbitrary(F.arbitrary.map(OptionT.apply)) + implicit def idTArbitrary[F[_], A](implicit F: Arbitrary[F[A]]): Arbitrary[IdT[F, A]] = + Arbitrary(F.arbitrary.map(IdT.apply)) + implicit def evalArbitrary[A: Arbitrary]: Arbitrary[Eval[A]] = Arbitrary(Gen.oneOf( getArbitrary[A].map(Eval.now(_)), diff --git a/tests/src/test/scala/cats/tests/IdTTests.scala b/tests/src/test/scala/cats/tests/IdTTests.scala new file mode 100644 index 0000000000..393bf66f15 --- /dev/null +++ b/tests/src/test/scala/cats/tests/IdTTests.scala @@ -0,0 +1,22 @@ +package cats.tests + +import cats.{Foldable, Functor, Monad, Traverse} +import cats.data.IdT +import cats.laws.discipline.{FoldableTests, FunctorTests, MonadTests, SerializableTests, TraverseTests} +import cats.laws.discipline.arbitrary._ + +class IdTTests extends CatsSuite { + + checkAll("IdT[Functor, Int]", FunctorTests[IdT[List, ?]].functor[Int, Int, Int]) + checkAll("Functor[IdT[List, ?]]", SerializableTests.serializable(Functor[IdT[List, ?]])) + + checkAll("IdT[List, Int]", MonadTests[IdT[List, ?]].monad[Int, Int, Int]) + checkAll("Monad[IdT[List, ?]]", SerializableTests.serializable(Monad[IdT[List, ?]])) + + checkAll("IdT[Option, Int]", FoldableTests[IdT[Option, ?]].foldable[Int, Int]) + checkAll("Foldable[IdT[Option, ?]]", SerializableTests.serializable(Foldable[IdT[Option, ?]])) + + checkAll("IdT[Option, Int]", TraverseTests[IdT[Option, ?]].traverse[Int, Int, Int, Int, Option, Option]) + checkAll("Traverse[IdT[Option, ?]]", SerializableTests.serializable(Traverse[IdT[Option, ?]])) + +} From 818e029128f40b8670f257db7e51d9ed66ac2f3e Mon Sep 17 00:00:00 2001 From: Luke Wyman Date: Mon, 22 Feb 2016 15:26:30 -0700 Subject: [PATCH 03/40] added scaladocs for CoflatMap and Comonad --- core/src/main/scala/cats/CoflatMap.scala | 40 ++++++++++++++++++++++-- core/src/main/scala/cats/Comonad.scala | 24 ++++++++++++-- 2 files changed, 60 insertions(+), 4 deletions(-) diff --git a/core/src/main/scala/cats/CoflatMap.scala b/core/src/main/scala/cats/CoflatMap.scala index 4db0e50668..ff26802c13 100644 --- a/core/src/main/scala/cats/CoflatMap.scala +++ b/core/src/main/scala/cats/CoflatMap.scala @@ -3,11 +3,47 @@ package cats import simulacrum.typeclass /** - * Must obey the laws defined in cats.laws.CoflatMapLaws. - */ + * `CoflatMap` is the dual of `FlatMap`. + * + * Must obey the laws in cats.laws.CoflatMapLaws + */ @typeclass trait CoflatMap[F[_]] extends Functor[F] { + + /** + * `coflatMap` is the dual of `flatMap` on `FlatMap`. It applies + * a value in a Monadic context to a function that takes a value + * in a context and returns a normal value. + * + * Example: + * {{{ + * scala> import cats.std.option._ + * scala> import cats.Monad + * scala> import cats.CoflatMap + * scala> val fa = Monad[Option].pure(3) + * scala> def f(a: Option[Int]): Int = a match { + * | case Some(x) => 2 * x + * | case None => 0 } + * scala> CoflatMap[Option].coflatMap(fa)(f) + * res0: Option[Int] = Some(6) + * }}} + */ def coflatMap[A, B](fa: F[A])(f: F[A] => B): F[B] + /** + * `coflatten` is the dual of `flatten` on `FlatMap`. Whereas flatten removes + * a layer of `F`, coflatten adds a layer of `F` + * + * Example: + * {{{ + * scala> import cats.std.option._ + * scala> import cats.Monad + * scala> import cats.CoflatMap + * scala> val fa = Monad[Option].pure(3) + * fa: Option[Int] = Some(3) + * scala> CoflatMap[Option].coflatten(fa) + * res0: Option[Option[Int]] = Some(Some(3)) + * }}} + */ def coflatten[A](fa: F[A]): F[F[A]] = coflatMap(fa)(fa => fa) } diff --git a/core/src/main/scala/cats/Comonad.scala b/core/src/main/scala/cats/Comonad.scala index b29a17596a..95ac7715e7 100644 --- a/core/src/main/scala/cats/Comonad.scala +++ b/core/src/main/scala/cats/Comonad.scala @@ -2,9 +2,29 @@ package cats import simulacrum.typeclass + /** - * Must obey the laws defined in cats.laws.ComonadLaws. - */ + * Comonad + * + * Comonad is the dual of Monad. Whereas Monads allow for the composition of effectful functions, + * Comonads allow for composition of functions that extract the value from their context. + * + * Must obey the laws defined in cats.laws.ComonadLaws. + */ @typeclass trait Comonad[F[_]] extends CoflatMap[F] { + + /** + * `extract` is the dual of `pure` on Monad (via `Applicative`) + * and extracts the value from its context + * + * Example: + * {{{ + * scala> import cats.Id + * scala> import cats.Comonad + * scala> val id = Id.pure(3) + * scala> Comonad[Id].extract(id) + * res0: cats.Id[Int] = 3 + * }}} + */ def extract[A](x: F[A]): A } From a2ea8ccc6431c7c0fb296c9ed760db0288880c44 Mon Sep 17 00:00:00 2001 From: Adelbert Chang Date: Wed, 2 Mar 2016 16:25:34 -0500 Subject: [PATCH 04/40] Add Bifunctor compose, fixes #899 --- .../main/scala/cats/functor/Bifunctor.scala | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/core/src/main/scala/cats/functor/Bifunctor.scala b/core/src/main/scala/cats/functor/Bifunctor.scala index 0001161d14..7697e59242 100644 --- a/core/src/main/scala/cats/functor/Bifunctor.scala +++ b/core/src/main/scala/cats/functor/Bifunctor.scala @@ -23,8 +23,26 @@ trait Bifunctor[F[_, _]] extends Serializable { self => * apply a function ro the "right" functor */ def rightMap[A,B,C](fab: F[A, B])(f: B => C): F[A,C] = bimap(fab)(identity, f) + + /** The composition of two Bifunctors is itself a Bifunctor */ + def compose[G[_, _]](implicit G0: Bifunctor[G]): Bifunctor[Lambda[(A, B) => F[G[A, B], G[A, B]]]] = + new CompositeBifunctor[F, G] { + val F = self + val G = G0 + } } object Bifunctor { def apply[F[_, _]](implicit ev: Bifunctor[F]): Bifunctor[F] = ev } + +trait CompositeBifunctor[F[_, _], G[_, _]] + extends Bifunctor[Lambda[(A, B) => F[G[A, B], G[A, B]]]] { + def F: Bifunctor[F] + def G: Bifunctor[G] + + def bimap[A, B, C, D](fab: F[G[A, B], G[A, B]])(f: A => C, g: B => D): F[G[C, D], G[C, D]] = { + val innerBimap: G[A, B] => G[C, D] = gab => G.bimap(gab)(f, g) + F.bimap(fab)(innerBimap, innerBimap) + } +} From 2a001aff3596300c496e0e52cc34caea0fd4785f Mon Sep 17 00:00:00 2001 From: Alexandru Nedelcu Date: Fri, 18 Mar 2016 12:41:23 +0200 Subject: [PATCH 05/40] Issue #934 - Make Eval covariant --- core/src/main/scala/cats/Eval.scala | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/core/src/main/scala/cats/Eval.scala b/core/src/main/scala/cats/Eval.scala index 867abe42b1..b0970cc808 100644 --- a/core/src/main/scala/cats/Eval.scala +++ b/core/src/main/scala/cats/Eval.scala @@ -33,7 +33,7 @@ import cats.syntax.all._ * Eval instance -- this can defeat the trampolining and lead to stack * overflows. */ -sealed abstract class Eval[A] extends Serializable { self => +sealed abstract class Eval[+A] extends Serializable { self => /** * Evaluate the computation and return an A value. @@ -279,7 +279,7 @@ object Eval extends EvalInstances { cc.start().asInstanceOf[L], cc.run.asInstanceOf[C] :: c.run.asInstanceOf[C] :: fs) case xx => - loop(c.run(xx.value).asInstanceOf[L], fs) + loop(c.run(xx.value), fs) } case x => fs match { @@ -350,7 +350,7 @@ trait EvalMonoid[A] extends Monoid[Eval[A]] with EvalSemigroup[A] { trait EvalGroup[A] extends Group[Eval[A]] with EvalMonoid[A] { implicit def algebra: Group[A] def inverse(lx: Eval[A]): Eval[A] = - lx.map(_.inverse) + lx.map(_.inverse()) override def remove(lx: Eval[A], ly: Eval[A]): Eval[A] = for { x <- lx; y <- ly } yield x |-| y } From 87063b9439ddcca9e1b672cdc87996d43ca5d743 Mon Sep 17 00:00:00 2001 From: Adelbert Chang Date: Fri, 18 Mar 2016 18:20:46 -0700 Subject: [PATCH 06/40] Add Bifunctor compose test --- .../test/scala/cats/tests/BifunctorTests.scala | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 tests/src/test/scala/cats/tests/BifunctorTests.scala diff --git a/tests/src/test/scala/cats/tests/BifunctorTests.scala b/tests/src/test/scala/cats/tests/BifunctorTests.scala new file mode 100644 index 0000000000..bb5de39ff0 --- /dev/null +++ b/tests/src/test/scala/cats/tests/BifunctorTests.scala @@ -0,0 +1,15 @@ +package cats +package tests + +import cats.functor.Bifunctor +import cats.laws.discipline.{SerializableTests, BifunctorTests} +import cats.laws.discipline.eq.tuple2Eq + +class BifunctorTest extends CatsSuite { + type Tuple2Either[A, B] = (Either[A, B], Either[A, B]) + val tuple2ComposeEither: Bifunctor[Tuple2Either] = + Bifunctor[Tuple2].compose[Either] + + checkAll("Tuple2 compose Either", BifunctorTests(tuple2ComposeEither).bifunctor[Int, Int, Int, String, String, String]) + checkAll("Bifunctor[Tuple2 compose Either]", SerializableTests.serializable(tuple2ComposeEither)) +} From d3f261a4a8f3fc2fe7ac6e500ad90935682df099 Mon Sep 17 00:00:00 2001 From: Luke Wyman Date: Tue, 19 Apr 2016 12:39:59 -0600 Subject: [PATCH 07/40] updated scaladoc comment for cats.Id changes --- core/src/main/scala/cats/Comonad.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/src/main/scala/cats/Comonad.scala b/core/src/main/scala/cats/Comonad.scala index 95ac7715e7..7e8e9c6f88 100644 --- a/core/src/main/scala/cats/Comonad.scala +++ b/core/src/main/scala/cats/Comonad.scala @@ -21,7 +21,7 @@ import simulacrum.typeclass * {{{ * scala> import cats.Id * scala> import cats.Comonad - * scala> val id = Id.pure(3) + * scala> val id: Id[Int] = 3 * scala> Comonad[Id].extract(id) * res0: cats.Id[Int] = 3 * }}} From 05bf655d38b71305348a179b73c2e6c12126a360 Mon Sep 17 00:00:00 2001 From: Julien Richard-Foy Date: Tue, 3 May 2016 10:02:45 +0200 Subject: [PATCH 08/40] Add MonadError.ensure method --- core/src/main/scala/cats/MonadError.scala | 10 ++++++- core/src/main/scala/cats/data/Xor.scala | 2 ++ core/src/main/scala/cats/syntax/all.scala | 1 + .../main/scala/cats/syntax/monadError.scala | 16 ++++++++++++ .../scala/cats/tests/MonadErrorSuite.scala | 26 +++++++++++++++++++ 5 files changed, 54 insertions(+), 1 deletion(-) create mode 100644 core/src/main/scala/cats/syntax/monadError.scala create mode 100644 tests/src/test/scala/cats/tests/MonadErrorSuite.scala diff --git a/core/src/main/scala/cats/MonadError.scala b/core/src/main/scala/cats/MonadError.scala index 763b0b68ff..7748cdd036 100644 --- a/core/src/main/scala/cats/MonadError.scala +++ b/core/src/main/scala/cats/MonadError.scala @@ -5,7 +5,15 @@ package cats * * This type class allows one to abstract over error-handling monads. */ -trait MonadError[F[_], E] extends ApplicativeError[F, E] with Monad[F] +trait MonadError[F[_], E] extends ApplicativeError[F, E] with Monad[F] { + + /** + * Turns a successful value into an error if it does not satisfy a given predicate. + */ + def ensure[A](fa: F[A])(error: => E)(predicate: A => Boolean): F[A] = + flatMap(fa)(a => if (predicate(a)) pure(a) else raiseError(error)) + +} object MonadError { def apply[F[_], E](implicit F: MonadError[F, E]): MonadError[F, E] = F diff --git a/core/src/main/scala/cats/data/Xor.scala b/core/src/main/scala/cats/data/Xor.scala index 470fa448d4..007aceac1e 100644 --- a/core/src/main/scala/cats/data/Xor.scala +++ b/core/src/main/scala/cats/data/Xor.scala @@ -208,6 +208,8 @@ private[data] sealed abstract class XorInstances extends XorInstances1 { fab recover pf override def recoverWith[B](fab: A Xor B)(pf: PartialFunction[A, A Xor B]): A Xor B = fab recoverWith pf + override def ensure[B](fab: A Xor B)(error: => A)(predicate: B => Boolean): A Xor B = + fab.ensure(error)(predicate) } } diff --git a/core/src/main/scala/cats/syntax/all.scala b/core/src/main/scala/cats/syntax/all.scala index bbb196d91b..e325045130 100644 --- a/core/src/main/scala/cats/syntax/all.scala +++ b/core/src/main/scala/cats/syntax/all.scala @@ -22,6 +22,7 @@ trait AllSyntax with InvariantSyntax with ListSyntax with MonadCombineSyntax + with MonadErrorSyntax with MonadFilterSyntax with OptionSyntax with OrderSyntax diff --git a/core/src/main/scala/cats/syntax/monadError.scala b/core/src/main/scala/cats/syntax/monadError.scala new file mode 100644 index 0000000000..93023431d5 --- /dev/null +++ b/core/src/main/scala/cats/syntax/monadError.scala @@ -0,0 +1,16 @@ +package cats +package syntax + +trait MonadErrorSyntax { + + implicit def monadErrorSyntax[F[_], E, A](fa: F[A])(implicit F: MonadError[F, E]): MonadErrorOps[F, E, A] = + new MonadErrorOps(fa) + +} + +final class MonadErrorOps[F[_], E, A](fa: F[A])(implicit F: MonadError[F, E]) { + + def ensure(error: => E)(predicate: A => Boolean): F[A] = + F.ensure(fa)(error)(predicate) + +} diff --git a/tests/src/test/scala/cats/tests/MonadErrorSuite.scala b/tests/src/test/scala/cats/tests/MonadErrorSuite.scala new file mode 100644 index 0000000000..3b752339e1 --- /dev/null +++ b/tests/src/test/scala/cats/tests/MonadErrorSuite.scala @@ -0,0 +1,26 @@ +package cats +package tests + +import cats.data.Xor + +class MonadErrorSuite extends CatsSuite { + + type ErrorOr[A] = String Xor A + + val successful: ErrorOr[Int] = 42.right + val failed: ErrorOr[Int] = "Oops".left + + test("ensure raises an error if the predicate fails") { + monadErrorSyntax(successful).ensure("Error")(i => false) should === ("Error".left) + } + + test("ensure returns the successful value if the predicate succeeds") { + monadErrorSyntax(successful).ensure("Error")(i => true) should === (successful) + } + + test("ensure returns the failure, when applied to a failure") { + monadErrorSyntax(failed).ensure("Error")(i => false) should === (failed) + monadErrorSyntax(failed).ensure("Error")(i => true) should === (failed) + } + +} From 1752755e48d00476b9dc899bd33e2361026e1ae0 Mon Sep 17 00:00:00 2001 From: Julien Richard-Foy Date: Tue, 17 May 2016 15:37:56 +0200 Subject: [PATCH 09/40] Use MonadError[Option, Unit] in tests --- .../test/scala/cats/tests/MonadErrorSuite.scala | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/tests/src/test/scala/cats/tests/MonadErrorSuite.scala b/tests/src/test/scala/cats/tests/MonadErrorSuite.scala index 3b752339e1..4e7ddd7919 100644 --- a/tests/src/test/scala/cats/tests/MonadErrorSuite.scala +++ b/tests/src/test/scala/cats/tests/MonadErrorSuite.scala @@ -1,26 +1,22 @@ package cats package tests -import cats.data.Xor - class MonadErrorSuite extends CatsSuite { - type ErrorOr[A] = String Xor A - - val successful: ErrorOr[Int] = 42.right - val failed: ErrorOr[Int] = "Oops".left + val successful: Option[Int] = 42.some + val failed: Option[Int] = None test("ensure raises an error if the predicate fails") { - monadErrorSyntax(successful).ensure("Error")(i => false) should === ("Error".left) + successful.ensure(())(i => false) should === (None) } test("ensure returns the successful value if the predicate succeeds") { - monadErrorSyntax(successful).ensure("Error")(i => true) should === (successful) + successful.ensure(())(i => true) should === (successful) } test("ensure returns the failure, when applied to a failure") { - monadErrorSyntax(failed).ensure("Error")(i => false) should === (failed) - monadErrorSyntax(failed).ensure("Error")(i => true) should === (failed) + failed.ensure(())(i => false) should === (failed) + failed.ensure(())(i => true) should === (failed) } } From 3efe27fe252b420f2ff25c5780f9fccd9cdf6a92 Mon Sep 17 00:00:00 2001 From: Zainab Ali Date: Fri, 20 May 2016 20:12:11 +0100 Subject: [PATCH 10/40] Adding CoflatMap and tests to WriterT --- core/src/main/scala/cats/data/WriterT.scala | 24 +++++++++++++------ .../cats/laws/discipline/CoflatMapTests.scala | 15 ++++++++---- .../test/scala/cats/tests/WriterTTests.scala | 11 +++++++++ 3 files changed, 39 insertions(+), 11 deletions(-) diff --git a/core/src/main/scala/cats/data/WriterT.scala b/core/src/main/scala/cats/data/WriterT.scala index 2ee07cc5cd..1f7db51055 100644 --- a/core/src/main/scala/cats/data/WriterT.scala +++ b/core/src/main/scala/cats/data/WriterT.scala @@ -87,8 +87,7 @@ private[data] sealed abstract class WriterTInstances0 extends WriterTInstances1 implicit val L0: Monoid[L] = L } - implicit def writerTIdFunctor[L]: Functor[WriterT[Id, L, ?]] = - writerTFunctor[Id, L] + def writerTIdFunctor[L]: Functor[WriterT[Id, L, ?]] = writerTIdCoflatMap implicit def writerTIdFlatMap[L:Semigroup]: FlatMap[WriterT[Id, L, ?]] = writerTFlatMap[Id, L] @@ -111,7 +110,11 @@ private[data] sealed abstract class WriterTInstances1 extends WriterTInstances2 new WriterTMonoid[F, L, V] { implicit val F0: Monoid[F[(L, V)]] = W } + + implicit def writerTIdCoflatMap[L]: CoflatMap[WriterT[Id, L, ?]] = + writerTCoflatMap[Id, L] } + private[data] sealed abstract class WriterTInstances2 extends WriterTInstances3 { implicit def writerTMonadWriter[F[_], L](implicit F: Monad[F], L: Monoid[L]): MonadWriter[WriterT[F, L, ?], L] = new WriterTMonadWriter[F, L] { @@ -131,6 +134,7 @@ private[data] sealed abstract class WriterTInstances3 extends WriterTInstances4 implicit val F0: Alternative[F] = F implicit val L0: Monoid[L] = L } + } private[data] sealed abstract class WriterTInstances4 extends WriterTInstances5 { @@ -168,7 +172,10 @@ private[data] sealed abstract class WriterTInstances6 extends WriterTInstances7 } private[data] sealed abstract class WriterTInstances7 { - implicit def writerTFunctor[F[_], L](implicit F: Functor[F]): Functor[WriterT[F, L, ?]] = new WriterTFunctor[F, L] { + + def writerTFunctor[F[_], L](implicit F: Functor[F]): Functor[WriterT[F, L, ?]] = writerTCoflatMap + + implicit def writerTCoflatMap[F[_], L](implicit F: Functor[F]): WriterTCoflatMap[F, L] = new WriterTCoflatMap[F, L] { implicit val F0: Functor[F] = F } } @@ -259,12 +266,18 @@ private[data] sealed trait WriterTSemigroup[F[_], L, A] extends Semigroup[Writer WriterT(F0.combine(x.run, y.run)) } -private[data] sealed trait WriterTMonoid[F[_], L, A] extends Monoid[WriterT[F, L, A]] with WriterTSemigroup[F, L, A]{ +private[data] sealed trait WriterTMonoid[F[_], L, A] extends Monoid[WriterT[F, L, A]] with WriterTSemigroup[F, L, A] { override implicit def F0: Monoid[F[(L, A)]] def empty: WriterT[F, L, A] = WriterT(F0.empty) } +private[data] sealed trait WriterTCoflatMap[F[_], L] extends CoflatMap[WriterT[F, L, ?]] with WriterTFunctor[F, L] { + + def coflatMap[A, B](fa: WriterT[F, L, A])(f: WriterT[F, L, A] => B): WriterT[F, L, B] = fa.map(_ => f(fa)) +} + + trait WriterTFunctions { def putT[F[_], L, V](vf: F[V])(l: L)(implicit functorF: Functor[F]): WriterT[F, L, V] = WriterT(functorF.map(vf)(v => (l, v))) @@ -281,6 +294,3 @@ trait WriterTFunctions { def valueT[F[_], L, V](vf: F[V])(implicit functorF: Functor[F], monoidL: Monoid[L]): WriterT[F, L, V] = WriterT.putT[F, L, V](vf)(monoidL.empty) } - - - diff --git a/laws/src/main/scala/cats/laws/discipline/CoflatMapTests.scala b/laws/src/main/scala/cats/laws/discipline/CoflatMapTests.scala index 0abeff6ad9..887a2cb9d1 100644 --- a/laws/src/main/scala/cats/laws/discipline/CoflatMapTests.scala +++ b/laws/src/main/scala/cats/laws/discipline/CoflatMapTests.scala @@ -7,18 +7,25 @@ import org.scalacheck.Prop import Prop._ import org.typelevel.discipline.Laws -trait CoflatMapTests[F[_]] extends Laws { +trait CoflatMapTests[F[_]] extends Laws with FunctorTests[F] { def laws: CoflatMapLaws[F] def coflatMap[A: Arbitrary, B: Arbitrary, C: Arbitrary](implicit ArbFA: Arbitrary[F[A]], EqFA: Eq[F[A]], - EqFC: Eq[F[C]] + EqFC: Eq[F[C]], + EqFFA: Eq[F[F[A]]], + EqFB: Eq[F[B]], + EqFFFA: Eq[F[F[F[A]]]] ): RuleSet = { new DefaultRuleSet( name = "coflatMap", - parent = None, - "coflatMap associativity" -> forAll(laws.coflatMapAssociativity[A, B, C] _)) + parent = Some(functor[A, B, C]), + "coflatMap associativity" -> forAll(laws.coflatMapAssociativity[A, B, C] _), + "coflatMap identity" -> forAll(laws.coflatMapIdentity[A, B] _), + "coflatten coherence" -> forAll(laws.coflattenCoherence[A, B] _), + "coflatten throughMap" -> forAll(laws.coflattenThroughMap[A] _) + ) } } diff --git a/tests/src/test/scala/cats/tests/WriterTTests.scala b/tests/src/test/scala/cats/tests/WriterTTests.scala index f6223e879f..d1bb73caa1 100644 --- a/tests/src/test/scala/cats/tests/WriterTTests.scala +++ b/tests/src/test/scala/cats/tests/WriterTTests.scala @@ -268,4 +268,15 @@ class WriterTTests extends CatsSuite { Semigroup[WriterT[Id, Int, Int]] } + + { + // F has a functor + implicit val F: Functor[ListWrapper] = ListWrapper.functor + + CoflatMap[WriterT[ListWrapper, Int, ?]] + checkAll("WriterT[Listwrapper, Int, ?]", CoflatMapTests[WriterT[ListWrapper, Int, ?]].coflatMap[Int, Int, Int]) + + // Id has a Functor + CoflatMap[WriterT[Id, Int, ?]] + } } From 6ab573c528843379b6f4a0c5b29a26b6e14c978d Mon Sep 17 00:00:00 2001 From: Zainab Ali Date: Fri, 20 May 2016 21:35:32 +0100 Subject: [PATCH 11/40] Added Serializable test to WriterT CoflatMap --- tests/src/test/scala/cats/tests/WriterTTests.scala | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/src/test/scala/cats/tests/WriterTTests.scala b/tests/src/test/scala/cats/tests/WriterTTests.scala index d1bb73caa1..8ca9f789aa 100644 --- a/tests/src/test/scala/cats/tests/WriterTTests.scala +++ b/tests/src/test/scala/cats/tests/WriterTTests.scala @@ -270,11 +270,12 @@ class WriterTTests extends CatsSuite { } { - // F has a functor + // F has a Functor implicit val F: Functor[ListWrapper] = ListWrapper.functor CoflatMap[WriterT[ListWrapper, Int, ?]] checkAll("WriterT[Listwrapper, Int, ?]", CoflatMapTests[WriterT[ListWrapper, Int, ?]].coflatMap[Int, Int, Int]) + checkAll("WriterT[ListWrapper, Int, ?]", SerializableTests.serializable(CoflatMap[WriterT[ListWrapper, Int, ?]])) // Id has a Functor CoflatMap[WriterT[Id, Int, ?]] From b1cf1c0089f28acddee81bb05eb6ef7e4b86abec Mon Sep 17 00:00:00 2001 From: Cody Allen Date: Fri, 20 May 2016 18:19:58 -0400 Subject: [PATCH 12/40] Use pygments instead of rouge for syntax highlighting It appears that GitHub is already using rouge instead of pygments for the cats site, because it doesn't support pygments. This change is so I stop getting the following email every time I push the cats website: > You are attempting to use the 'pygments' highlighter, which is currently > unsupported on GitHub Pages. Your site will use 'rouge' for highlighting > instead. To suppress this warning, change the 'highlighter' value to > 'rouge' in your '_config.yml' and ensure the 'pygments' key is unset. --- docs/src/site/_config.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/src/site/_config.yml b/docs/src/site/_config.yml index 79555d8ad3..26c3f77031 100644 --- a/docs/src/site/_config.yml +++ b/docs/src/site/_config.yml @@ -1,6 +1,6 @@ name: Cats Documentation markdown: redcarpet -highlighter: pygments +highlighter: rouge baseurl: /cats apidocs: /cats/api/ sources: /~https://github.com/typelevel/cats/blob/master/ From 128c49478fd1e486d7b5ab6941e0ba238318bfb8 Mon Sep 17 00:00:00 2001 From: Zainab Ali Date: Sat, 21 May 2016 00:11:01 +0100 Subject: [PATCH 13/40] Removing WriterT Functor instance in place of CoflatMap instance --- core/src/main/scala/cats/data/WriterT.scala | 10 ++++------ tests/src/test/scala/cats/tests/WriterTTests.scala | 2 +- 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/core/src/main/scala/cats/data/WriterT.scala b/core/src/main/scala/cats/data/WriterT.scala index 1f7db51055..81ee317e22 100644 --- a/core/src/main/scala/cats/data/WriterT.scala +++ b/core/src/main/scala/cats/data/WriterT.scala @@ -87,8 +87,6 @@ private[data] sealed abstract class WriterTInstances0 extends WriterTInstances1 implicit val L0: Monoid[L] = L } - def writerTIdFunctor[L]: Functor[WriterT[Id, L, ?]] = writerTIdCoflatMap - implicit def writerTIdFlatMap[L:Semigroup]: FlatMap[WriterT[Id, L, ?]] = writerTFlatMap[Id, L] @@ -111,7 +109,7 @@ private[data] sealed abstract class WriterTInstances1 extends WriterTInstances2 implicit val F0: Monoid[F[(L, V)]] = W } - implicit def writerTIdCoflatMap[L]: CoflatMap[WriterT[Id, L, ?]] = + implicit def writerTIdCoflatMap[L]: CoflatMap[WriterT[Id, L, ?]] = writerTCoflatMap[Id, L] } @@ -164,6 +162,7 @@ private[data] sealed abstract class WriterTInstances5 extends WriterTInstances6 } private[data] sealed abstract class WriterTInstances6 extends WriterTInstances7 { + implicit def writerTApply[F[_], L](implicit F: Apply[F], L: Semigroup[L]): Apply[WriterT[F, L, ?]] = new WriterTApply[F, L] { implicit val F0: Apply[F] = F @@ -173,9 +172,8 @@ private[data] sealed abstract class WriterTInstances6 extends WriterTInstances7 private[data] sealed abstract class WriterTInstances7 { - def writerTFunctor[F[_], L](implicit F: Functor[F]): Functor[WriterT[F, L, ?]] = writerTCoflatMap - - implicit def writerTCoflatMap[F[_], L](implicit F: Functor[F]): WriterTCoflatMap[F, L] = new WriterTCoflatMap[F, L] { + implicit def writerTCoflatMap[F[_], L](implicit F: Functor[F]): WriterTCoflatMap[F, L] = + new WriterTCoflatMap[F, L] { implicit val F0: Functor[F] = F } } diff --git a/tests/src/test/scala/cats/tests/WriterTTests.scala b/tests/src/test/scala/cats/tests/WriterTTests.scala index 8ca9f789aa..58dc04505d 100644 --- a/tests/src/test/scala/cats/tests/WriterTTests.scala +++ b/tests/src/test/scala/cats/tests/WriterTTests.scala @@ -101,7 +101,7 @@ class WriterTTests extends CatsSuite { checkAll("Bifunctor[WriterT[ListWrapper, ?, ?]]", SerializableTests.serializable(Bifunctor[WriterT[ListWrapper, ?, ?]])) } - implicit val iso = CartesianTests.Isomorphisms.invariant[WriterT[ListWrapper, ListWrapper[Int], ?]](WriterT.writerTFunctor(ListWrapper.functor)) + implicit val iso = CartesianTests.Isomorphisms.invariant[WriterT[ListWrapper, ListWrapper[Int], ?]](WriterT.writerTCoflatMap(ListWrapper.functor)) // We have varying instances available depending on `F` and `L`. // We also battle some inference issues with `Id`. From 82443c9f68f54c53a9836c89d3cb16e99d208946 Mon Sep 17 00:00:00 2001 From: Zainab Ali Date: Sat, 21 May 2016 15:53:52 +0100 Subject: [PATCH 14/40] Adding check for Functor in WriterT CoflatMap tests --- core/src/main/scala/cats/data/WriterT.scala | 4 ++-- tests/src/test/scala/cats/tests/WriterTTests.scala | 2 ++ 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/core/src/main/scala/cats/data/WriterT.scala b/core/src/main/scala/cats/data/WriterT.scala index 81ee317e22..2c89f43dba 100644 --- a/core/src/main/scala/cats/data/WriterT.scala +++ b/core/src/main/scala/cats/data/WriterT.scala @@ -172,9 +172,9 @@ private[data] sealed abstract class WriterTInstances6 extends WriterTInstances7 private[data] sealed abstract class WriterTInstances7 { - implicit def writerTCoflatMap[F[_], L](implicit F: Functor[F]): WriterTCoflatMap[F, L] = + implicit def writerTCoflatMap[F[_], L](implicit F: Functor[F]): CoflatMap[WriterT[F, L, ?]] = new WriterTCoflatMap[F, L] { - implicit val F0: Functor[F] = F + implicit val F0: Functor[F] = F } } diff --git a/tests/src/test/scala/cats/tests/WriterTTests.scala b/tests/src/test/scala/cats/tests/WriterTTests.scala index 58dc04505d..55bff93d00 100644 --- a/tests/src/test/scala/cats/tests/WriterTTests.scala +++ b/tests/src/test/scala/cats/tests/WriterTTests.scala @@ -273,11 +273,13 @@ class WriterTTests extends CatsSuite { // F has a Functor implicit val F: Functor[ListWrapper] = ListWrapper.functor + Functor[WriterT[ListWrapper, Int, ?]] CoflatMap[WriterT[ListWrapper, Int, ?]] checkAll("WriterT[Listwrapper, Int, ?]", CoflatMapTests[WriterT[ListWrapper, Int, ?]].coflatMap[Int, Int, Int]) checkAll("WriterT[ListWrapper, Int, ?]", SerializableTests.serializable(CoflatMap[WriterT[ListWrapper, Int, ?]])) // Id has a Functor + Functor[WriterT[Id, Int, ?]] CoflatMap[WriterT[Id, Int, ?]] } } From 37e738012c22b9fe5c5ef64b1af681389892db47 Mon Sep 17 00:00:00 2001 From: Kailuo Wang Date: Sat, 21 May 2016 12:19:08 -0400 Subject: [PATCH 15/40] updated sbt to 0.13.11 --- project/build.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/project/build.properties b/project/build.properties index 817bc38df8..43b8278c68 100644 --- a/project/build.properties +++ b/project/build.properties @@ -1 +1 @@ -sbt.version=0.13.9 +sbt.version=0.13.11 From b106f1d11f6156f4aea8c3d3ff34fbfa923ae16a Mon Sep 17 00:00:00 2001 From: Kailuo Wang Date: Fri, 20 May 2016 21:44:47 -0400 Subject: [PATCH 16/40] skip javadoc compilation for 2.10 --- build.sbt | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/build.sbt b/build.sbt index 935d953264..4e7f648fff 100644 --- a/build.sbt +++ b/build.sbt @@ -82,7 +82,7 @@ lazy val commonJvmSettings = Seq( // JVM settings. /~https://github.com/tkawachi/sbt-doctest/issues/52 ) ++ catsDoctestSettings -lazy val catsSettings = buildSettings ++ commonSettings ++ publishSettings ++ scoverageSettings +lazy val catsSettings = buildSettings ++ commonSettings ++ publishSettings ++ scoverageSettings ++ skip210DocSettings lazy val scalacheckVersion = "1.12.5" @@ -106,6 +106,14 @@ def noDocProjects(sv: String): Seq[ProjectReference] = CrossVersion.partialVersi case _ => Nil } +lazy val skip210DocSettings = Seq( + sources in (Compile, doc) := ( + CrossVersion.partialVersion(scalaVersion.value) match { + case Some((2, 10)) => Nil + case _ => (sources in (Compile, doc)).value + }) +) + lazy val docSettings = Seq( autoAPIMappings := true, unidocProjectFilter in (ScalaUnidoc, unidoc) := From 04bfb7bf90d0b58f23acb32c64ecca7f9a9740ea Mon Sep 17 00:00:00 2001 From: Kailuo Wang Date: Sat, 21 May 2016 09:13:59 -0400 Subject: [PATCH 17/40] consolidate skip 210 doc settings --- build.sbt | 30 ++++++++++++++---------------- 1 file changed, 14 insertions(+), 16 deletions(-) diff --git a/build.sbt b/build.sbt index 4e7f648fff..e52b23a6fa 100644 --- a/build.sbt +++ b/build.sbt @@ -82,7 +82,7 @@ lazy val commonJvmSettings = Seq( // JVM settings. /~https://github.com/tkawachi/sbt-doctest/issues/52 ) ++ catsDoctestSettings -lazy val catsSettings = buildSettings ++ commonSettings ++ publishSettings ++ scoverageSettings ++ skip210DocSettings +lazy val catsSettings = buildSettings ++ commonSettings ++ publishSettings ++ scoverageSettings ++ javadocSettings lazy val scalacheckVersion = "1.12.5" @@ -95,29 +95,27 @@ lazy val testingDependencies = Seq( libraryDependencies += "org.typelevel" %%% "catalysts-macros" % "0.0.2" % "test", libraryDependencies += "org.scalatest" %%% "scalatest" % "3.0.0-M7" % "test") + /** - * Remove 2.10 projects from doc generation, as the macros used in the projects - * cause problems generating the documentation on scala 2.10. As the APIs for 2.10 - * and 2.11 are the same this has no effect on the resultant documentation, though - * it does mean that the scaladocs cannot be generated when the build is in 2.10 mode. - */ -def noDocProjects(sv: String): Seq[ProjectReference] = CrossVersion.partialVersion(sv) match { - case Some((2, 10)) => Seq[ProjectReference](coreJVM) - case _ => Nil + * Remove 2.10 projects from doc generation, as the macros used in the projects + * cause problems generating the documentation on scala 2.10. As the APIs for 2.10 + * and 2.11 are the same this has no effect on the resultant documentation, though + * it does mean that the scaladocs cannot be generated when the build is in 2.10 mode. + */ +def docsSourcesAndProjects(sv: String): (Boolean, Seq[ProjectReference]) = + CrossVersion.partialVersion(sv) match { + case Some((2, 10)) => (false, Nil) + case _ => (true, Seq(coreJVM, freeJVM)) } -lazy val skip210DocSettings = Seq( - sources in (Compile, doc) := ( - CrossVersion.partialVersion(scalaVersion.value) match { - case Some((2, 10)) => Nil - case _ => (sources in (Compile, doc)).value - }) +lazy val javadocSettings = Seq( + sources in (Compile, doc) := (if (docsSourcesAndProjects(scalaVersion.value)._1) (sources in (Compile, doc)).value else Nil) ) lazy val docSettings = Seq( autoAPIMappings := true, unidocProjectFilter in (ScalaUnidoc, unidoc) := - inProjects(coreJVM, freeJVM) -- inProjects(noDocProjects(scalaVersion.value): _*), + inProjects(docsSourcesAndProjects(scalaVersion.value)._2:_*), site.addMappingsToSiteDir(mappings in (ScalaUnidoc, packageDoc), "api"), site.addMappingsToSiteDir(tut, "_tut"), ghpagesNoJekyll := false, From b005e1774eae463e45b0ba281508a0320d9f531a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alejandro=20G=C3=B3mez?= Date: Mon, 23 May 2016 16:56:25 +0200 Subject: [PATCH 18/40] Upgade tut-plugin --- project/plugins.sbt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/project/plugins.sbt b/project/plugins.sbt index 6c3ba461f7..0f5dbe47ce 100644 --- a/project/plugins.sbt +++ b/project/plugins.sbt @@ -3,7 +3,7 @@ addSbtPlugin("com.github.gseitz" % "sbt-release" % "1.0.0") addSbtPlugin("com.jsuereth" % "sbt-pgp" % "1.0.0") addSbtPlugin("com.typesafe.sbt" % "sbt-ghpages" % "0.5.3") addSbtPlugin("com.typesafe.sbt" % "sbt-site" % "0.8.1") -addSbtPlugin("org.tpolecat" % "tut-plugin" % "0.4.0") +addSbtPlugin("org.tpolecat" % "tut-plugin" % "0.4.2") addSbtPlugin("pl.project13.scala" % "sbt-jmh" % "0.2.3") addSbtPlugin("org.scalastyle" %% "scalastyle-sbt-plugin" % "0.8.0") addSbtPlugin("org.scoverage" % "sbt-scoverage" % "1.2.0") From 2d3eb7e2f8e4fb1aefd539d0db454dc2152c94f3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alejandro=20G=C3=B3mez?= Date: Mon, 23 May 2016 17:04:17 +0200 Subject: [PATCH 19/40] Change tut blocks to tut:book Closes #1055 --- docs/src/main/tut/applicative.md | 4 ++-- docs/src/main/tut/apply.md | 18 +++++++++--------- docs/src/main/tut/contravariant.md | 6 +++--- docs/src/main/tut/foldable.md | 8 ++++---- docs/src/main/tut/freeapplicative.md | 4 ++-- docs/src/main/tut/freemonad.md | 6 +++--- docs/src/main/tut/functor.md | 12 ++++++------ docs/src/main/tut/id.md | 8 ++++---- docs/src/main/tut/invariant.md | 2 +- docs/src/main/tut/kleisli.md | 2 +- docs/src/main/tut/monad.md | 6 +++--- docs/src/main/tut/monoid.md | 8 ++++---- docs/src/main/tut/semigroup.md | 8 ++++---- docs/src/main/tut/semigroupk.md | 8 ++++---- docs/src/main/tut/state.md | 12 ++++++------ docs/src/main/tut/traverse.md | 8 ++++---- docs/src/main/tut/typeclasses.md | 4 ++-- docs/src/main/tut/validated.md | 10 +++++----- docs/src/main/tut/xor.md | 16 ++++++++-------- 19 files changed, 75 insertions(+), 75 deletions(-) diff --git a/docs/src/main/tut/applicative.md b/docs/src/main/tut/applicative.md index 833c7acc89..9fca90c1d5 100644 --- a/docs/src/main/tut/applicative.md +++ b/docs/src/main/tut/applicative.md @@ -20,7 +20,7 @@ obvious. For `Option`, the `pure` operation wraps the value in `Some`. For `List`, the `pure` operation returns a single element `List`: -```tut +```tut:book import cats._ import cats.std.all._ @@ -34,7 +34,7 @@ you compose one `Applicative` with another, the resulting `pure` operation will lift the passed value into one context, and the result into the other context: -```tut +```tut:book (Applicative[List] compose Applicative[Option]).pure(1) ``` diff --git a/docs/src/main/tut/apply.md b/docs/src/main/tut/apply.md index 9a69e14a66..c2e007f0ef 100644 --- a/docs/src/main/tut/apply.md +++ b/docs/src/main/tut/apply.md @@ -40,7 +40,7 @@ implicit val listApply: Apply[List] = new Apply[List] { Since `Apply` extends `Functor`, we can use the `map` method from `Functor`: -```tut +```tut:book Apply[Option].map(Some(1))(intToString) Apply[Option].map(Some(1))(double) Apply[Option].map(None)(double) @@ -50,7 +50,7 @@ Apply[Option].map(None)(double) And like functors, `Apply` instances also compose: -```tut +```tut:book val listOpt = Apply[List] compose Apply[Option] val plusOne = (x:Int) => x + 1 listOpt.ap(List(Some(plusOne)))(List(Some(1), None, Some(3))) @@ -59,7 +59,7 @@ listOpt.ap(List(Some(plusOne)))(List(Some(1), None, Some(3))) ### ap The `ap` method is a method that `Functor` does not have: -```tut +```tut:book Apply[Option].ap(Some(intToString))(Some(1)) Apply[Option].ap(Some(double))(Some(1)) Apply[Option].ap(Some(double))(None) @@ -74,7 +74,7 @@ accept `N` arguments where `ap` accepts `1`: For example: -```tut +```tut:book val addArity2 = (a: Int, b: Int) => a + b Apply[Option].ap2(Some(addArity2))(Some(1), Some(2)) @@ -86,7 +86,7 @@ Note that if any of the arguments of this example is `None`, the final result is `None` as well. The effects of the context we are operating on are carried through the entire computation: -```tut +```tut:book Apply[Option].ap2(Some(addArity2))(Some(1), None) Apply[Option].ap4(None)(Some(1), Some(2), Some(3), Some(4)) ``` @@ -95,7 +95,7 @@ Apply[Option].ap4(None)(Some(1), Some(2), Some(3), Some(4)) Similarly, `mapN` functions are available: -```tut +```tut:book Apply[Option].map2(Some(1), Some(2))(addArity2) Apply[Option].map3(Some(1), Some(2), Some(3))(addArity3) @@ -105,7 +105,7 @@ Apply[Option].map3(Some(1), Some(2), Some(3))(addArity3) And `tupleN`: -```tut +```tut:book Apply[Option].tuple2(Some(1), Some(2)) Apply[Option].tuple3(Some(1), Some(2), Some(3)) @@ -118,7 +118,7 @@ functions (`apN`, `mapN` and `tupleN`). In order to use it, first import `cats.syntax.all._` or `cats.syntax.cartesian._`. Here we see that the following two functions, `f1` and `f2`, are equivalent: -```tut +```tut:book import cats.syntax.cartesian._ def f1(a: Option[Int], b: Option[Int], c: Option[Int]) = @@ -133,7 +133,7 @@ f2(Some(1), Some(2), Some(3)) All instances created by `|@|` have `map`, `ap`, and `tupled` methods of the appropriate arity: -```tut +```tut:book val option2 = Option(1) |@| Option(2) val option3 = option2 |@| Option.empty[Int] diff --git a/docs/src/main/tut/contravariant.md b/docs/src/main/tut/contravariant.md index 80fc363cb1..df1dea5dc2 100644 --- a/docs/src/main/tut/contravariant.md +++ b/docs/src/main/tut/contravariant.md @@ -40,7 +40,7 @@ If we want to show a `Salary` instance, we can just convert it to a `Money` inst Let's use `Show`'s `Contravariant`: -```tut +```tut:book implicit val showSalary: Show[Salary] = showMoney.contramap(_.size) Salary(Money(1000)).show @@ -52,7 +52,7 @@ Salary(Money(1000)).show `scala.math.Ordering` typeclass defines comparison operations, e.g. `compare`: -```tut +```tut:book Ordering.Int.compare(2, 1) Ordering.Int.compare(1, 2) ``` @@ -67,7 +67,7 @@ In fact, it is just `contramap`, defined in a slightly different way! We supply So let's use it in our advantage and get `Ordering[Money]` for free: -```tut +```tut:book // we need this for `<` to work import scala.math.Ordered._ diff --git a/docs/src/main/tut/foldable.md b/docs/src/main/tut/foldable.md index 81e4ea09fa..a990a635c0 100644 --- a/docs/src/main/tut/foldable.md +++ b/docs/src/main/tut/foldable.md @@ -32,7 +32,7 @@ import cats.implicits._ And examples. -```tut +```tut:book Foldable[List].fold(List("a", "b", "c")) Foldable[List].foldMap(List(1, 2, 4))(_.toString) Foldable[List].foldK(List(List(1,2,3), List(2,3,4))) @@ -95,7 +95,7 @@ Scala's standard library might expect. This will prevent operations which are lazy in their right hand argument to traverse the entire structure unnecessarily. For example, if you have: -```tut +```tut:book val allFalse = Stream.continually(false) ``` @@ -108,7 +108,7 @@ value. Using `foldRight` from the standard library *will* try to consider the entire stream, and thus will eventually cause a stack overflow: -```tut +```tut:book try { allFalse.foldRight(true)(_ && _) } catch { @@ -119,6 +119,6 @@ try { With the lazy `foldRight` on `Foldable`, the calculation terminates after looking at only one value: -```tut +```tut:book Foldable[Stream].foldRight(allFalse, Eval.True)((a,b) => if (a) b else Eval.now(false)).value ``` diff --git a/docs/src/main/tut/freeapplicative.md b/docs/src/main/tut/freeapplicative.md index 80a5605a36..238d44ded1 100644 --- a/docs/src/main/tut/freeapplicative.md +++ b/docs/src/main/tut/freeapplicative.md @@ -71,7 +71,7 @@ val compiler = } ``` -```tut +```tut:book val validator = prog.foldMap[FromString](compiler) validator("1234") validator("12345") @@ -142,7 +142,7 @@ def logValidation[A](validation: Validation[A]): List[String] = validation.foldMap[Log](logCompiler).getConst ``` -```tut +```tut:book logValidation(prog) logValidation(size(5) *> hasNumber *> size(10)) logValidation((hasNumber |@| size(3)).map(_ || _)) diff --git a/docs/src/main/tut/freemonad.md b/docs/src/main/tut/freemonad.md index e84d130f86..d8cf2a2848 100644 --- a/docs/src/main/tut/freemonad.md +++ b/docs/src/main/tut/freemonad.md @@ -252,7 +252,7 @@ under `Monad`). As `Id` is a `Monad`, we can use `foldMap`. To run your `Free` with previous `impureCompiler`: -```tut +```tut:book val result: Option[Int] = program.foldMap(impureCompiler) ``` @@ -291,7 +291,7 @@ val pureCompiler: KVStoreA ~> KVStoreState = new (KVStoreA ~> KVStoreState) { support for pattern matching is limited by the JVM's type erasure, but it's not too hard to get around.) -```tut +```tut:book val result: (Map[String, Any], Option[Int]) = program.foldMap(pureCompiler).run(Map.empty).value ``` @@ -403,7 +403,7 @@ Now if we run our program and type in "snuggles" when prompted, we see something import DataSource._, Interacts._ ``` -```tut +```tut:book val evaled: Unit = program.foldMap(interpreter) ``` diff --git a/docs/src/main/tut/functor.md b/docs/src/main/tut/functor.md index 1d31cd809e..5b8884edca 100644 --- a/docs/src/main/tut/functor.md +++ b/docs/src/main/tut/functor.md @@ -23,7 +23,7 @@ This method takes a function `A => B` and turns an `F[A]` into an method that exists on many classes in the Scala standard library, for example: -```tut +```tut:book Option(1).map(_ + 1) List(1,2,3).map(_ + 1) Vector(1,2,3).map(_.toString) @@ -72,7 +72,7 @@ Without kind-projector, we'd have to write this as something like `List` is a functor which applies the function to each element of the list: -```tut +```tut:book val len: String => Int = _.length Functor[List].map(List("qwer", "adsfg"))(len) ``` @@ -80,7 +80,7 @@ Functor[List].map(List("qwer", "adsfg"))(len) `Option` is a functor which only applies the function when the `Option` value is a `Some`: -```tut +```tut:book Functor[Option].map(Some("adsf"))(len) // Some(x) case: function is applied to x; result is wrapped in Some Functor[Option].map(None)(len) // None case: simply returns None (function is not applied) ``` @@ -91,7 +91,7 @@ Functor[Option].map(None)(len) // None case: simply returns None (function is no We can use `Functor` to "lift" a function from `A => B` to `F[A] => F[B]`: -```tut +```tut:book val lenOption: Option[String] => Option[Int] = Functor[Option].lift(len) lenOption(Some("abcd")) ``` @@ -101,7 +101,7 @@ lenOption(Some("abcd")) `Functor` provides an `fproduct` function which pairs a value with the result of applying a function to that value. -```tut +```tut:book val source = List("a", "aa", "b", "ccccc") Functor[List].fproduct(source)(len).toMap ``` @@ -111,7 +111,7 @@ Functor[List].fproduct(source)(len).toMap Functors compose! Given any functor `F[_]` and any functor `G[_]` we can create a new functor `F[G[_]]` by composing them: -```tut +```tut:book val listOpt = Functor[List] compose Functor[Option] listOpt.map(List(Some(1), None, Some(3)))(_ + 1) val optList = Functor[Option] compose Functor[List] diff --git a/docs/src/main/tut/id.md b/docs/src/main/tut/id.md index 3b48fbad67..05149ba0bc 100644 --- a/docs/src/main/tut/id.md +++ b/docs/src/main/tut/id.md @@ -21,7 +21,7 @@ That is to say that the type Id[A] is just a synonym for A. We can freely treat values of type `A` as values of type `Id[A]`, and vice-versa. -```tut +```tut:book import cats._ val x: Id[Int] = 1 @@ -34,7 +34,7 @@ method, which has type `A => Id[A]` just becomes the identity function. The `map` method from `Functor` just becomes function application: -```tut +```tut:book import cats.Functor val one: Int = 1 @@ -56,7 +56,7 @@ two functions the same, and, in fact, they can have the same implementation, meaning that for `Id`, `flatMap` is also just function application: -```tut +```tut:book import cats.Monad val one: Int = 1 @@ -66,7 +66,7 @@ Monad[Id].flatMap(one)(_ + 1) And that similarly, coflatMap is just function application: -```tut +```tut:book import cats.Comonad Comonad[Id].coflatMap(one)(_ + 1) diff --git a/docs/src/main/tut/invariant.md b/docs/src/main/tut/invariant.md index eb1d6299f7..371a50350a 100644 --- a/docs/src/main/tut/invariant.md +++ b/docs/src/main/tut/invariant.md @@ -102,6 +102,6 @@ val today: Date = longToDate(1449088684104l) val timeLeft: Date = longToDate(1900918893l) ``` -```tut +```tut:book today |+| timeLeft ``` diff --git a/docs/src/main/tut/kleisli.md b/docs/src/main/tut/kleisli.md index 3b03916e0f..8505b7513b 100644 --- a/docs/src/main/tut/kleisli.md +++ b/docs/src/main/tut/kleisli.md @@ -36,7 +36,7 @@ val twiceAsManyCats: Int => String = Thus. -```tut +```tut:book twiceAsManyCats(1) // "2 cats" ``` diff --git a/docs/src/main/tut/monad.md b/docs/src/main/tut/monad.md index 36ecf30cad..c41a7d150e 100644 --- a/docs/src/main/tut/monad.md +++ b/docs/src/main/tut/monad.md @@ -15,7 +15,7 @@ that we have a single context (ie. `F[A]`). The name `flatten` should remind you of the functions of the same name on many classes in the standard library. -```tut +```tut:book Option(Option(1)).flatten Option(None).flatten List(List(1),List(2,3)).flatten @@ -63,7 +63,7 @@ Part of the reason for this is that name `flatMap` has special significance in scala, as for-comprehensions rely on this method to chain together operations in a monadic context. -```tut +```tut:book import scala.reflect.runtime.universe universe.reify( @@ -80,7 +80,7 @@ universe.reify( the results of earlier ones. This is embodied in `ifM`, which lifts an `if` statement into the monadic context. -```tut +```tut:book Monad[List].ifM(List(true, false, true))(List(1, 2), List(3, 4)) ``` diff --git a/docs/src/main/tut/monoid.md b/docs/src/main/tut/monoid.md index b31f6e6662..6acbe6e48f 100644 --- a/docs/src/main/tut/monoid.md +++ b/docs/src/main/tut/monoid.md @@ -34,7 +34,7 @@ import cats.implicits._ Examples. -```tut +```tut:book Monoid[String].empty Monoid[String].combineAll(List("a", "b", "c")) Monoid[String].combineAll(List()) @@ -44,7 +44,7 @@ The advantage of using these type class provided methods, rather than the specific ones for each type, is that we can compose monoids to allow us to operate on more complex types, e.g. -```tut +```tut:book Monoid[Map[String,Int]].combineAll(List(Map("a" -> 1, "b" -> 2), Map("a" -> 3))) Monoid[Map[String,Int]].combineAll(List()) ``` @@ -53,7 +53,7 @@ This is also true if we define our own instances. As an example, let's use [`Foldable`](foldable.html)'s `foldMap`, which maps over values accumulating the results, using the available `Monoid` for the type mapped onto. -```tut +```tut:book val l = List(1, 2, 3, 4, 5) l.foldMap(identity) l.foldMap(i => i.toString) @@ -64,7 +64,7 @@ with a function that produces a tuple, cats also provides a `Monoid` for a tuple that will be valid for any tuple where the types it contains also have a `Monoid` available, thus. -```tut +```tut:book l.foldMap(i => (i, i.toString)) // do both of the above in one pass, hurrah! ``` diff --git a/docs/src/main/tut/semigroup.md b/docs/src/main/tut/semigroup.md index c1045ef563..79d153acf9 100644 --- a/docs/src/main/tut/semigroup.md +++ b/docs/src/main/tut/semigroup.md @@ -37,7 +37,7 @@ import cats.implicits._ Examples. -```tut +```tut:book Semigroup[Int].combine(1, 2) Semigroup[List[Int]].combine(List(1,2,3), List(4,5,6)) Semigroup[Option[Int]].combine(Option(1), Option(2)) @@ -50,14 +50,14 @@ which allow for such combining, e.g. `++` on List, but the value of having a `Semigroup` type class available is that these compose, so for instance, we can say -```tut +```tut:book Map("foo" -> Map("bar" -> 5)).combine(Map("foo" -> Map("bar" -> 6), "baz" -> Map())) Map("foo" -> List(1, 2)).combine(Map("foo" -> List(3,4), "bar" -> List(42))) ``` which is far more likely to be useful than -```tut +```tut:book Map("foo" -> Map("bar" -> 5)) ++ Map("foo" -> Map("bar" -> 6), "baz" -> Map()) Map("foo" -> List(1, 2)) ++ Map("foo" -> List(3,4), "bar" -> List(42)) ``` @@ -78,7 +78,7 @@ val n: Option[Int] = None Thus. -```tut +```tut:book one |+| two n |+| two n |+| n diff --git a/docs/src/main/tut/semigroupk.md b/docs/src/main/tut/semigroupk.md index 1085c6ee56..2cd8cb1f02 100644 --- a/docs/src/main/tut/semigroupk.md +++ b/docs/src/main/tut/semigroupk.md @@ -44,7 +44,7 @@ import cats.std.all._ Examples. -```tut +```tut:book Semigroup[Int].combine(1, 2) Semigroup[List[Int]].combine(List(1,2,3), List(4,5,6)) Semigroup[Option[Int]].combine(Option(1), Option(2)) @@ -67,7 +67,7 @@ and, in fact, the `K` in `SemigroupK` stands for `Kind`. For `List`, the `Semigroup` instance's `combine` operation and the `SemigroupK` instance's `combineK` operation are both list concatenation: -```tut +```tut:book SemigroupK[List].combineK(List(1,2,3), List(4,5,6)) == Semigroup[List[Int]].combine(List(1,2,3), List(4,5,6)) ``` @@ -84,7 +84,7 @@ two of them. Therefore, in the case of `Option` the `SemigroupK[Option].combineK` method has no choice but to use the `orElse` method of Option: -```tut +```tut:book Semigroup[Option[Int]].combine(Some(1), Some(2)) SemigroupK[Option].combineK(Some(1), Some(2)) SemigroupK[Option].combineK(Some(1), None) @@ -108,7 +108,7 @@ val n: Option[Int] = None Thus. -```tut +```tut:book one |+| two one <+> two n |+| two diff --git a/docs/src/main/tut/state.md b/docs/src/main/tut/state.md index 980ccc5cd4..e60ff301b2 100644 --- a/docs/src/main/tut/state.md +++ b/docs/src/main/tut/state.md @@ -41,7 +41,7 @@ def createRobot(): Robot = { } ``` -```tut +```tut:book val robot = createRobot() ``` @@ -62,7 +62,7 @@ def createRobot(): Robot = { } ``` -```tut +```tut:book val robot = createRobot() ``` @@ -114,7 +114,7 @@ def createRobot(seed: Seed): Robot = { val initialSeed = Seed(13L) ``` -```tut +```tut:book val robot = createRobot(initialSeed) ``` @@ -160,13 +160,13 @@ val createRobot: State[Seed, Robot] = At this point, we have not yet created a robot; we have written instructions for creating a robot. We need to pass in an initial seed value, and then we can call `value` to actually create the robot: -```tut +```tut:book val (finalState, robot) = createRobot.run(initialSeed).value ``` If we only care about the robot and not the final state, then we can use `runA`: -```tut +```tut:book val robot = createRobot.runA(initialSeed).value ``` @@ -187,7 +187,7 @@ val createRobot: State[Seed, Robot] = { } ``` -```tut +```tut:book val robot = createRobot.runA(initialSeed).value ``` diff --git a/docs/src/main/tut/traverse.md b/docs/src/main/tut/traverse.md index 9281a90b21..22373a33e9 100644 --- a/docs/src/main/tut/traverse.md +++ b/docs/src/main/tut/traverse.md @@ -41,7 +41,7 @@ hold true in this case? Given just `User => Future[Profile]`, what should we do if we want to fetch profiles for a `List[User]`? We could try familiar combinators like `map`. -```tut +```tut:book def profilesFor(users: List[User]) = users.map(userInfo) ``` @@ -104,7 +104,7 @@ def parseIntValidated(s: String): ValidatedNel[NumberFormatException, Int] = Examples. -```tut +```tut:book val x1 = List("1", "2", "3").traverseU(parseIntXor) val x2 = List("1", "abc", "3").traverseU(parseIntXor) val x3 = List("1", "abc", "def").traverseU(parseIntXor) @@ -187,7 +187,7 @@ Sometimes you may find yourself with a collection of data, each of which is alre for instance a `List[Option[A]]`. To make this easier to work with, you want a `Option[List[A]]`. Given `Option` has an `Applicative` instance, we can traverse over the list with the identity function. -```tut +```tut:book import cats.std.option._ val l1 = List(Option(1), Option(2), Option(3)).traverse(identity) val l2 = List(Option(1), None, Option(3)).traverse(identity) @@ -195,7 +195,7 @@ val l2 = List(Option(1), None, Option(3)).traverse(identity) `Traverse` provides a convenience method `sequence` that does exactly this. -```tut +```tut:book val l1 = List(Option(1), Option(2), Option(3)).sequence val l2 = List(Option(1), None, Option(3)).sequence ``` diff --git a/docs/src/main/tut/typeclasses.md b/docs/src/main/tut/typeclasses.md index 5084b1c5b2..a555c3df9a 100644 --- a/docs/src/main/tut/typeclasses.md +++ b/docs/src/main/tut/typeclasses.md @@ -38,7 +38,7 @@ implicit val stringShow = new Show[String] { and now our call to Log succeeds -```tut +```tut:book log("a string") ``` @@ -67,7 +67,7 @@ implicit def optionShow[A](implicit sa: Show[A]) = new Show[Option[A]] { Now we can call our log function with a `Option[String]` or a `Option[Option[String]]`: -```tut +```tut:book log(Option(Option("hello"))) ``` diff --git a/docs/src/main/tut/validated.md b/docs/src/main/tut/validated.md index ea26d16b8e..e4ba7ead44 100644 --- a/docs/src/main/tut/validated.md +++ b/docs/src/main/tut/validated.md @@ -162,7 +162,7 @@ implicit val readInt: Read[Int] = Read.intRead Any and all errors are reported! -```tut +```tut:book val v1 = parallelValidate(config.parse[String]("url").toValidatedNel, config.parse[Int]("port").toValidatedNel)(ConnectionParams.apply) @@ -224,7 +224,7 @@ case class Person(name: String, age: Int, address: Address) Thus. -```tut +```tut:book val personFromConfig: ValidatedNel[ConfigError, Person] = Apply[ValidatedNel[ConfigError, ?]].map4(config.parse[String]("name").toValidatedNel, config.parse[Int]("age").toValidatedNel, @@ -271,7 +271,7 @@ trait Monad[F[_]] { However, the `ap` behavior defined in terms of `flatMap` does not behave the same as that of our `ap` defined above. Observe: -```tut +```tut:book val v = validatedMonad.tuple2(Validated.invalidNel[String, Int]("oops"), Validated.invalidNel[String, Double]("uh oh")) ``` @@ -294,7 +294,7 @@ If you do want error accumulation but occasionally run into places where you seq ### `andThen` The `andThen` method is similar to `flatMap` (such as `Xor.flatMap`). In the cause of success, it passes the valid value into a function that returns a new `Validated` instance. -```tut +```tut:book val houseNumber = config.parse[Int]("house_number").andThen{ n => if (n >= 0) Validated.valid(n) else Validated.invalid(ParseError("house_number")) @@ -315,7 +315,7 @@ def positive(field: String, i: Int): ConfigError Xor Int = { Thus. -```tut +```tut:book val houseNumber = config.parse[Int]("house_number").withXor{ xor: ConfigError Xor Int => xor.flatMap{ i => positive("house_number", i) diff --git a/docs/src/main/tut/xor.md b/docs/src/main/tut/xor.md index 3873a8f69f..6944f4d673 100644 --- a/docs/src/main/tut/xor.md +++ b/docs/src/main/tut/xor.md @@ -64,7 +64,7 @@ This can be accomplished by using the `Either#right` method, which returns a `Ri instance. `RightProjection` does have `flatMap` and `map` on it, which acts on the right side and ignores the left - this property is referred to as "right-bias." -```tut +```tut:book val e1: Either[String, Int] = Right(5) e1.right.map(_ + 1) @@ -80,7 +80,7 @@ the right side is most often chosen. This is the primary difference between `Xor `Xor` is right-biased. `Xor` also has some more convenient methods on it, but the most crucial one is the right-biased being built-in. -```tut +```tut:book import cats.data.Xor val xor1: Xor[String, Int] = Xor.right(5) @@ -163,7 +163,7 @@ With the composite function that we actually care about, we can pass in strings match on the exception. Because `Xor` is a sealed type (often referred to as an algebraic data type, or ADT), the compiler will complain if we do not check both the `Left` and `Right` case. -```tut +```tut:book magic("123") match { case Xor.Left(_: NumberFormatException) => println("not a number!") case Xor.Left(_: IllegalArgumentException) => println("can't take reciprocal of 0!") @@ -209,7 +209,7 @@ exception classes as error values, we use one of the enumerated cases. Now when match, we get much nicer matching. Moreover, since `Error` is `sealed`, no outside code can add additional subtypes which we might fail to handle. -```tut +```tut:book import XorStyle._ magic("123") match { @@ -337,7 +337,7 @@ def awesome = There will inevitably come a time when your nice `Xor` code will have to interact with exception-throwing code. Handling such situations is easy enough. -```tut +```tut:book val xor: Xor[NumberFormatException, Int] = try { Xor.right("abc".toInt) @@ -350,21 +350,21 @@ However, this can get tedious quickly. `Xor` provides a `catchOnly` method on it that allows you to pass it a function, along with the type of exception you want to catch, and does the above for you. -```tut +```tut:book val xor: Xor[NumberFormatException, Int] = Xor.catchOnly[NumberFormatException]("abc".toInt) ``` If you want to catch all (non-fatal) throwables, you can use `catchNonFatal`. -```tut +```tut:book val xor: Xor[Throwable, Int] = Xor.catchNonFatal("abc".toInt) ``` ## Additional syntax -```tut +```tut:book import cats.syntax.xor._ val xor3: Xor[String, Int] = 7.right[String] From b7a191944dcef442c032625bf362875d4c25aa8f Mon Sep 17 00:00:00 2001 From: Oscar Boykin Date: Mon, 23 May 2016 15:11:54 -1000 Subject: [PATCH 20/40] Add Try instances --- core/src/main/scala/cats/std/all.scala | 1 + core/src/main/scala/cats/std/package.scala | 1 + core/src/main/scala/cats/std/try.scala | 105 ++++++++++++++++++ .../src/test/scala/cats/tests/TryTests.scala | 77 +++++++++++++ 4 files changed, 184 insertions(+) create mode 100644 core/src/main/scala/cats/std/try.scala create mode 100644 tests/src/test/scala/cats/tests/TryTests.scala diff --git a/core/src/main/scala/cats/std/all.scala b/core/src/main/scala/cats/std/all.scala index 0060a5f513..27c80e9d90 100644 --- a/core/src/main/scala/cats/std/all.scala +++ b/core/src/main/scala/cats/std/all.scala @@ -15,4 +15,5 @@ trait AllInstances with BigIntInstances with BigDecimalInstances with FutureInstances + with TryInstances with TupleInstances diff --git a/core/src/main/scala/cats/std/package.scala b/core/src/main/scala/cats/std/package.scala index 9b31e87b51..f49a7fdce7 100644 --- a/core/src/main/scala/cats/std/package.scala +++ b/core/src/main/scala/cats/std/package.scala @@ -28,5 +28,6 @@ package object std { object bigInt extends BigIntInstances object bigDecimal extends BigDecimalInstances + object `try` extends TryInstances object tuple extends TupleInstances } diff --git a/core/src/main/scala/cats/std/try.scala b/core/src/main/scala/cats/std/try.scala new file mode 100644 index 0000000000..7b5789d528 --- /dev/null +++ b/core/src/main/scala/cats/std/try.scala @@ -0,0 +1,105 @@ +package cats +package std + +import cats.syntax.all._ +import cats.data.Xor + +import scala.util.control.NonFatal +import scala.util.{Failure, Success, Try} + +trait TryInstances extends TryInstances1 { + + implicit def tryInstance: MonadError[Try, Throwable] with CoflatMap[Try] = + new TryCoflatMap with MonadError[Try, Throwable]{ + def pure[A](x: A): Try[A] = Success(x) + + override def pureEval[A](x: Eval[A]): Try[A] = x match { + case Now(x) => Success(x) + case _ => Try(x.value) + } + + override def map2[A, B, Z](ta: Try[A], tb: Try[B])(f: (A, B) => Z): Try[Z] = + ta.flatMap(a => tb.map(b => f(a, b))) + + override def map2Eval[A, B, Z](ta: Try[A], tb: Eval[Try[B]])(f: (A, B) => Z): Eval[Try[Z]] = + ta match { + case f@Failure(_) => Now(f.asInstanceOf[Try[Z]]) + case Success(a) => tb.map(_.map(f(a, _))) + } + + def flatMap[A, B](ta: Try[A])(f: A => Try[B]): Try[B] = ta.flatMap(f) + + def handleErrorWith[A](ta: Try[A])(f: Throwable => Try[A]): Try[A] = + ta.recoverWith { case t => f(t) } + + def raiseError[A](e: Throwable): Try[A] = Failure(e) + override def handleError[A](ta: Try[A])(f: Throwable => A): Try[A] = + ta.recover { case t => f(t) } + + override def attempt[A](ta: Try[A]): Try[Throwable Xor A] = + (ta map Xor.right) recover { case NonFatal(t) => Xor.left(t) } + + override def recover[A](ta: Try[A])(pf: PartialFunction[Throwable, A]): Try[A] = + ta.recover(pf) + + override def recoverWith[A](ta: Try[A])(pf: PartialFunction[Throwable, Try[A]]): Try[A] = ta.recoverWith(pf) + + override def map[A, B](ta: Try[A])(f: A => B): Try[B] = ta.map(f) + } + + implicit def tryGroup[A: Group]: Group[Try[A]] = + new TryGroup[A] + + implicit def showTry[A](implicit A: Show[A]): Show[Try[A]] = + new Show[Try[A]] { + def show(fa: Try[A]): String = fa match { + case Success(a) => s"Success(${A.show(a)})" + case Failure(e) => s"Failure($e)" + } + } + implicit def eqTry[A](implicit A: Eq[A]): Eq[Try[A]] = + new Eq[Try[A]] { + def eqv(x: Try[A], y: Try[A]): Boolean = (x, y) match { + case (Success(a), Success(b)) => A.eqv(a, b) + case (Failure(_), Failure(_)) => true // all failures are equivalent + case _ => false + } + } +} + +private[std] sealed trait TryInstances1 extends TryInstances2 { + implicit def tryMonoid[A: Monoid]: Monoid[Try[A]] = + new TryMonoid[A] +} + +private[std] sealed trait TryInstances2 { + implicit def trySemigroup[A: Semigroup]: Semigroup[Try[A]] = + new TrySemigroup[A] +} + +private[cats] abstract class TryCoflatMap extends CoflatMap[Try] { + def map[A, B](ta: Try[A])(f: A => B): Try[B] = ta.map(f) + def coflatMap[A, B](ta: Try[A])(f: Try[A] => B): Try[B] = Try(f(ta)) +} + +private[cats] class TrySemigroup[A: Semigroup] extends Semigroup[Try[A]] { + def combine(fx: Try[A], fy: Try[A]): Try[A] = + for { + x <- fx + y <- fy + } yield x |+| y +} + +private[cats] class TryMonoid[A](implicit A: Monoid[A]) extends TrySemigroup[A] with Monoid[Try[A]] { + def empty: Try[A] = Success(A.empty) +} + +private[cats] class TryGroup[A](implicit A: Group[A]) extends TryMonoid[A] with Group[Try[A]] { + def inverse(fx: Try[A]): Try[A] = + fx.map(_.inverse) + override def remove(fx: Try[A], fy: Try[A]): Try[A] = + for { + x <- fx + y <- fy + } yield x |-| y +} diff --git a/tests/src/test/scala/cats/tests/TryTests.scala b/tests/src/test/scala/cats/tests/TryTests.scala new file mode 100644 index 0000000000..0ccc5d4028 --- /dev/null +++ b/tests/src/test/scala/cats/tests/TryTests.scala @@ -0,0 +1,77 @@ +package cats +package tests + +import cats.laws.{ApplicativeLaws, CoflatMapLaws, FlatMapLaws, MonadLaws} +import cats.laws.discipline._ + +class TryTests extends CatsSuite { + checkAll("Try[Int]", CartesianTests[Try].cartesian[Int, Int, Int]) + checkAll("Cartesian[Try]", SerializableTests.serializable(Cartesian[Try])) + + checkAll("Try[Int]", CoflatMapTests[Try].coflatMap[Int, Int, Int]) + checkAll("CoflatMap[Try]", SerializableTests.serializable(CoflatMap[Try])) + + checkAll("Try with Unit", MonadErrorTests[Try, Unit].monadError[Int, Int, Int]) + checkAll("MonadError[Try, Unit]", SerializableTests.serializable(MonadError[Try, Unit])) + + test("show") { + forAll { fs: Try[String] => + fs.show should === (fs.toString) + } + } + + // The following tests check laws which are a different formulation of + // laws that are checked. Since these laws are more or less duplicates of + // existing laws, we don't check them for all types that have the relevant + // instances. + + test("Kleisli associativity") { + forAll { (l: Long, + f: Long => Try[Int], + g: Int => Try[Char], + h: Char => Try[String]) => + val isEq = FlatMapLaws[Try].kleisliAssociativity(f, g, h, l) + isEq.lhs should === (isEq.rhs) + } + } + + test("Cokleisli associativity") { + forAll { (l: Try[Long], + f: Try[Long] => Int, + g: Try[Int] => Char, + h: Try[Char] => String) => + val isEq = CoflatMapLaws[Try].cokleisliAssociativity(f, g, h, l) + isEq.lhs should === (isEq.rhs) + } + } + + test("applicative composition") { + forAll { (fa: Try[Int], + fab: Try[Int => Long], + fbc: Try[Long => Char]) => + val isEq = ApplicativeLaws[Try].applicativeComposition(fa, fab, fbc) + isEq.lhs should === (isEq.rhs) + } + } + + val monadLaws = MonadLaws[Try] + + test("Kleisli left identity") { + forAll { (a: Int, f: Int => Try[Long]) => + val isEq = monadLaws.kleisliLeftIdentity(a, f) + isEq.lhs should === (isEq.rhs) + } + } + + test("Kleisli right identity") { + forAll { (a: Int, f: Int => Try[Long]) => + val isEq = monadLaws.kleisliRightIdentity(a, f) + isEq.lhs should === (isEq.rhs) + } + } + + test("map2Eval is lazy") { + val bomb: Eval[Try[Int]] = Later(sys.error("boom")) + Try(sys.error("boom0")).map2Eval(bomb)(_ + _).value should === (Failure(new Exception)) + } +} From 71c0d70eba472195eca5cf496b4a13c03fbe7fb9 Mon Sep 17 00:00:00 2001 From: Oscar Boykin Date: Mon, 23 May 2016 15:26:34 -1000 Subject: [PATCH 21/40] add a product implementation --- core/src/main/scala/cats/std/try.scala | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/core/src/main/scala/cats/std/try.scala b/core/src/main/scala/cats/std/try.scala index 7b5789d528..b69154cf1c 100644 --- a/core/src/main/scala/cats/std/try.scala +++ b/core/src/main/scala/cats/std/try.scala @@ -18,12 +18,21 @@ trait TryInstances extends TryInstances1 { case _ => Try(x.value) } - override def map2[A, B, Z](ta: Try[A], tb: Try[B])(f: (A, B) => Z): Try[Z] = - ta.flatMap(a => tb.map(b => f(a, b))) + override def product[A, B](ta: Try[A], tb: Try[B]): Try[(A, B)] = (ta, tb) match { + case (Success(a), Success(b)) => Success((a, b)) + case (f: Failure[_], _) => f.asInstanceOf[Try[(A, B)]] + case (_, f: Failure[_]) => f.asInstanceOf[Try[(A, B)]] + } + + override def map2[A, B, Z](ta: Try[A], tb: Try[B])(f: (A, B) => Z): Try[Z] = (ta, tb) match { + case (Success(a), Success(b)) => Try(f(a, b)) + case (f: Failure[_], _) => f.asInstanceOf[Try[Z]] + case (_, f: Failure[_]) => f.asInstanceOf[Try[Z]] + } override def map2Eval[A, B, Z](ta: Try[A], tb: Eval[Try[B]])(f: (A, B) => Z): Eval[Try[Z]] = ta match { - case f@Failure(_) => Now(f.asInstanceOf[Try[Z]]) + case f: Failure[_] => Now(f.asInstanceOf[Try[Z]]) case Success(a) => tb.map(_.map(f(a, _))) } From b2193de4a0708c4106361bb1a16cd7359995ea71 Mon Sep 17 00:00:00 2001 From: Oscar Boykin Date: Mon, 23 May 2016 15:31:48 -1000 Subject: [PATCH 22/40] actually test map2Eval laziness --- tests/src/test/scala/cats/tests/TryTests.scala | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/tests/src/test/scala/cats/tests/TryTests.scala b/tests/src/test/scala/cats/tests/TryTests.scala index 0ccc5d4028..46370b4a9c 100644 --- a/tests/src/test/scala/cats/tests/TryTests.scala +++ b/tests/src/test/scala/cats/tests/TryTests.scala @@ -71,7 +71,9 @@ class TryTests extends CatsSuite { } test("map2Eval is lazy") { - val bomb: Eval[Try[Int]] = Later(sys.error("boom")) - Try(sys.error("boom0")).map2Eval(bomb)(_ + _).value should === (Failure(new Exception)) + var evals = 0 + val bomb: Eval[Try[Int]] = Later { evals += 1; Success(1) } + Try(sys.error("boom0")).map2Eval(bomb)(_ + _).value + evals should === (0) } } From 94123926004067a90f5c9aa76524678698519e98 Mon Sep 17 00:00:00 2001 From: Oscar Boykin Date: Mon, 23 May 2016 16:00:19 -1000 Subject: [PATCH 23/40] fix the tests --- tests/src/test/scala/cats/tests/TryTests.scala | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/tests/src/test/scala/cats/tests/TryTests.scala b/tests/src/test/scala/cats/tests/TryTests.scala index 46370b4a9c..e280f20aaf 100644 --- a/tests/src/test/scala/cats/tests/TryTests.scala +++ b/tests/src/test/scala/cats/tests/TryTests.scala @@ -4,15 +4,19 @@ package tests import cats.laws.{ApplicativeLaws, CoflatMapLaws, FlatMapLaws, MonadLaws} import cats.laws.discipline._ +import scala.util.{Success, Try} + class TryTests extends CatsSuite { + implicit val eqThrow: Eq[Throwable] = Eq.allEqual + checkAll("Try[Int]", CartesianTests[Try].cartesian[Int, Int, Int]) checkAll("Cartesian[Try]", SerializableTests.serializable(Cartesian[Try])) checkAll("Try[Int]", CoflatMapTests[Try].coflatMap[Int, Int, Int]) checkAll("CoflatMap[Try]", SerializableTests.serializable(CoflatMap[Try])) - checkAll("Try with Unit", MonadErrorTests[Try, Unit].monadError[Int, Int, Int]) - checkAll("MonadError[Try, Unit]", SerializableTests.serializable(MonadError[Try, Unit])) + checkAll("Try with Throwable", MonadErrorTests[Try, Throwable].monadError[Int, Int, Int]) + checkAll("MonadError[Try, Throwable]", SerializableTests.serializable(MonadError[Try, Throwable])) test("show") { forAll { fs: Try[String] => @@ -73,7 +77,7 @@ class TryTests extends CatsSuite { test("map2Eval is lazy") { var evals = 0 val bomb: Eval[Try[Int]] = Later { evals += 1; Success(1) } - Try(sys.error("boom0")).map2Eval(bomb)(_ + _).value + Try[Int](sys.error("boom0")).map2Eval(bomb)(_ + _).value evals should === (0) } } From 42cb7bac9a52337fe1346548ee3a4295140193ae Mon Sep 17 00:00:00 2001 From: Michael Pilquist Date: Tue, 24 May 2016 21:42:06 -0400 Subject: [PATCH 24/40] Fixed a bug in the Order and PartialOrder instances for Tuple2+ where only the first element was used in comparisons --- project/KernelBoiler.scala | 4 ++-- tests/src/test/scala/cats/tests/TupleTests.scala | 13 +++++++++++++ 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/project/KernelBoiler.scala b/project/KernelBoiler.scala index 69a46537fe..bb5553ccd8 100644 --- a/project/KernelBoiler.scala +++ b/project/KernelBoiler.scala @@ -147,13 +147,13 @@ object KernelBoiler { - implicit def tuple${arity}Order[${`A..N`}](implicit ${constraints("Order")}): Order[${`(A..N)`}] = - new Order[${`(A..N)`}] { - def compare(x: ${`(A..N)`}, y: ${`(A..N)`}): Int = - - ${binMethod("compare").find(_ != 0).getOrElse(0)} + - ${binMethod("compare").mkString("Array(", ", ", ")")}.find(_ != 0).getOrElse(0) - } - - implicit def tuple${arity}PartialOrder[${`A..N`}](implicit ${constraints("PartialOrder")}): PartialOrder[${`(A..N)`}] = - new PartialOrder[${`(A..N)`}] { - def partialCompare(x: ${`(A..N)`}, y: ${`(A..N)`}): Double = - - ${binMethod("partialCompare").find(_ != 0.0).getOrElse(0.0)} + - ${binMethod("partialCompare").mkString("Array(", ", ", ")")}.find(_ != 0.0).getOrElse(0.0) - } - - implicit def tuple${arity}Semigroup[${`A..N`}](implicit ${constraints("Semigroup")}): Semigroup[${`(A..N)`}] = diff --git a/tests/src/test/scala/cats/tests/TupleTests.scala b/tests/src/test/scala/cats/tests/TupleTests.scala index fdde8f5545..8dab6e68af 100644 --- a/tests/src/test/scala/cats/tests/TupleTests.scala +++ b/tests/src/test/scala/cats/tests/TupleTests.scala @@ -7,6 +7,19 @@ class TupleTests extends CatsSuite { checkAll("Tuple2", BitraverseTests[Tuple2].bitraverse[Option, Int, Int, Int, String, String, String]) checkAll("Bitraverse[Tuple2]", SerializableTests.serializable(Bitraverse[Tuple2])) + test("eqv") { + val eq = Eq[(Int, Long)] + forAll { t: (Int, Long) => eq.eqv(t, t) should === (true) } + forAll { t: (Int, Long) => eq.eqv(t, t._1 -> (t._2 + 1)) should === (false) } + } + + test("order") { + forAll { t: (Int, Int) => + val u = t.swap + Order[(Int, Int)].compare(t, u) should === (scala.math.Ordering[(Int, Int)].compare(t, u)) + } + } + test("show") { (1, 2).show should === ("(1,2)") From 78ff38a34ab6bce165b42675d46811e2d8e36dbc Mon Sep 17 00:00:00 2001 From: Julien Truffaut Date: Thu, 26 May 2016 12:53:54 +0100 Subject: [PATCH 25/40] fix IdT --- core/src/main/scala/cats/data/IdT.scala | 2 +- tests/src/test/scala/cats/tests/IdTTests.scala | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/core/src/main/scala/cats/data/IdT.scala b/core/src/main/scala/cats/data/IdT.scala index bed9c19440..97cb261960 100644 --- a/core/src/main/scala/cats/data/IdT.scala +++ b/core/src/main/scala/cats/data/IdT.scala @@ -25,7 +25,7 @@ final case class IdT[F[_], A](value: F[A]) { G.map(F.traverse(value)(f))(IdT(_)) def ap[B](f: IdT[F, A => B])(implicit F: Apply[F]): IdT[F, B] = - IdT(F.ap(value)(f.value)) + IdT(F.ap(f.value)(value)) } diff --git a/tests/src/test/scala/cats/tests/IdTTests.scala b/tests/src/test/scala/cats/tests/IdTTests.scala index 393bf66f15..a748178d9f 100644 --- a/tests/src/test/scala/cats/tests/IdTTests.scala +++ b/tests/src/test/scala/cats/tests/IdTTests.scala @@ -2,11 +2,13 @@ package cats.tests import cats.{Foldable, Functor, Monad, Traverse} import cats.data.IdT -import cats.laws.discipline.{FoldableTests, FunctorTests, MonadTests, SerializableTests, TraverseTests} +import cats.laws.discipline.{CartesianTests, FoldableTests, FunctorTests, MonadTests, SerializableTests, TraverseTests} import cats.laws.discipline.arbitrary._ class IdTTests extends CatsSuite { + implicit val iso = CartesianTests.Isomorphisms.invariant[IdT[List, ?]] + checkAll("IdT[Functor, Int]", FunctorTests[IdT[List, ?]].functor[Int, Int, Int]) checkAll("Functor[IdT[List, ?]]", SerializableTests.serializable(Functor[IdT[List, ?]])) From 241140ee930ae5d416fe17846674efe799e8224c Mon Sep 17 00:00:00 2001 From: Oscar Boykin Date: Thu, 26 May 2016 10:31:05 -1000 Subject: [PATCH 26/40] update, remove bad groups --- core/src/main/scala/cats/std/future.scala | 10 ---------- core/src/main/scala/cats/std/package.scala | 2 +- core/src/main/scala/cats/std/try.scala | 22 +++++++--------------- 3 files changed, 8 insertions(+), 26 deletions(-) diff --git a/core/src/main/scala/cats/std/future.scala b/core/src/main/scala/cats/std/future.scala index e1453870d6..c18f7a0fff 100644 --- a/core/src/main/scala/cats/std/future.scala +++ b/core/src/main/scala/cats/std/future.scala @@ -34,9 +34,6 @@ trait FutureInstances extends FutureInstances1 { override def map[A, B](fa: Future[A])(f: A => B): Future[B] = fa.map(f) } - - implicit def futureGroup[A: Group](implicit ec: ExecutionContext): Group[Future[A]] = - new FutureGroup[A] } private[std] sealed trait FutureInstances1 extends FutureInstances2 { @@ -63,10 +60,3 @@ private[cats] class FutureMonoid[A](implicit A: Monoid[A], ec: ExecutionContext) def empty: Future[A] = Future.successful(A.empty) } - -private[cats] class FutureGroup[A](implicit A: Group[A], ec: ExecutionContext) extends FutureMonoid[A] with Group[Future[A]] { - def inverse(fx: Future[A]): Future[A] = - fx.map(_.inverse) - override def remove(fx: Future[A], fy: Future[A]): Future[A] = - (fx zip fy).map { case (x, y) => x |-| y } -} diff --git a/core/src/main/scala/cats/std/package.scala b/core/src/main/scala/cats/std/package.scala index f49a7fdce7..2bc6a91fca 100644 --- a/core/src/main/scala/cats/std/package.scala +++ b/core/src/main/scala/cats/std/package.scala @@ -28,6 +28,6 @@ package object std { object bigInt extends BigIntInstances object bigDecimal extends BigDecimalInstances - object `try` extends TryInstances + object try_ extends TryInstances object tuple extends TupleInstances } diff --git a/core/src/main/scala/cats/std/try.scala b/core/src/main/scala/cats/std/try.scala index b69154cf1c..b8871e881d 100644 --- a/core/src/main/scala/cats/std/try.scala +++ b/core/src/main/scala/cats/std/try.scala @@ -56,9 +56,6 @@ trait TryInstances extends TryInstances1 { override def map[A, B](ta: Try[A])(f: A => B): Try[B] = ta.map(f) } - implicit def tryGroup[A: Group]: Group[Try[A]] = - new TryGroup[A] - implicit def showTry[A](implicit A: Show[A]): Show[Try[A]] = new Show[Try[A]] { def show(fa: Try[A]): String = fa match { @@ -66,11 +63,16 @@ trait TryInstances extends TryInstances1 { case Failure(e) => s"Failure($e)" } } - implicit def eqTry[A](implicit A: Eq[A]): Eq[Try[A]] = + /** + * you may with to do equality by making `implicit val eqT: Eq[Throwable] = Eq.allEqual` + * doing a fine grained equality on Throwable can make the code very execution + * order dependent + */ + implicit def eqTry[A, T](implicit A: Eq[A], T: Eq[Throwable]): Eq[Try[A]] = new Eq[Try[A]] { def eqv(x: Try[A], y: Try[A]): Boolean = (x, y) match { case (Success(a), Success(b)) => A.eqv(a, b) - case (Failure(_), Failure(_)) => true // all failures are equivalent + case (Failure(a), Failure(b)) => T.eqv(a, b) case _ => false } } @@ -102,13 +104,3 @@ private[cats] class TrySemigroup[A: Semigroup] extends Semigroup[Try[A]] { private[cats] class TryMonoid[A](implicit A: Monoid[A]) extends TrySemigroup[A] with Monoid[Try[A]] { def empty: Try[A] = Success(A.empty) } - -private[cats] class TryGroup[A](implicit A: Group[A]) extends TryMonoid[A] with Group[Try[A]] { - def inverse(fx: Try[A]): Try[A] = - fx.map(_.inverse) - override def remove(fx: Try[A], fy: Try[A]): Try[A] = - for { - x <- fx - y <- fy - } yield x |-| y -} From 75b53e4061035553a291376d119322270797c487 Mon Sep 17 00:00:00 2001 From: Oscar Boykin Date: Thu, 26 May 2016 15:23:12 -1000 Subject: [PATCH 27/40] fix typo --- core/src/main/scala/cats/std/try.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/src/main/scala/cats/std/try.scala b/core/src/main/scala/cats/std/try.scala index b8871e881d..a42b015718 100644 --- a/core/src/main/scala/cats/std/try.scala +++ b/core/src/main/scala/cats/std/try.scala @@ -64,7 +64,7 @@ trait TryInstances extends TryInstances1 { } } /** - * you may with to do equality by making `implicit val eqT: Eq[Throwable] = Eq.allEqual` + * you may wish to do equality by making `implicit val eqT: Eq[Throwable] = Eq.allEqual` * doing a fine grained equality on Throwable can make the code very execution * order dependent */ From 65a506c2931b0fe7d79b69e6dfde7cf826a0b126 Mon Sep 17 00:00:00 2001 From: Kailuo Wang Date: Fri, 27 May 2016 09:39:57 -0400 Subject: [PATCH 28/40] renamed implicit vals in std --- core/src/main/scala/cats/std/anyval.scala | 18 +++++++++--------- core/src/main/scala/cats/std/bigDecimal.scala | 2 +- core/src/main/scala/cats/std/bigInt.scala | 2 +- core/src/main/scala/cats/std/either.scala | 12 ++++++------ core/src/main/scala/cats/std/function.scala | 16 ++++++++-------- core/src/main/scala/cats/std/future.scala | 8 ++++---- core/src/main/scala/cats/std/list.scala | 4 ++-- core/src/main/scala/cats/std/map.scala | 4 ++-- core/src/main/scala/cats/std/option.scala | 4 ++-- core/src/main/scala/cats/std/set.scala | 4 ++-- core/src/main/scala/cats/std/stream.scala | 4 ++-- core/src/main/scala/cats/std/string.scala | 2 +- core/src/main/scala/cats/std/tuple.scala | 4 ++-- core/src/main/scala/cats/std/vector.scala | 4 ++-- 14 files changed, 44 insertions(+), 44 deletions(-) diff --git a/core/src/main/scala/cats/std/anyval.scala b/core/src/main/scala/cats/std/anyval.scala index c9d1109a18..5bd6b357ad 100644 --- a/core/src/main/scala/cats/std/anyval.scala +++ b/core/src/main/scala/cats/std/anyval.scala @@ -14,37 +14,37 @@ trait AnyValInstances with TupleInstances trait IntInstances extends cats.kernel.std.IntInstances { - implicit val intShow: Show[Int] = Show.fromToString[Int] + implicit val catsShowForcatsForInt: Show[Int] = Show.fromToString[Int] } trait ByteInstances extends cats.kernel.std.ByteInstances { - implicit val byteShow: Show[Byte] = Show.fromToString[Byte] + implicit val catsShowForByte: Show[Byte] = Show.fromToString[Byte] } trait CharInstances extends cats.kernel.std.CharInstances { - implicit val charShow: Show[Char] = Show.fromToString[Char] + implicit val catsShowForChar: Show[Char] = Show.fromToString[Char] } trait ShortInstances extends cats.kernel.std.ShortInstances { - implicit val shortShow: Show[Short] = Show.fromToString[Short] + implicit val catsShowForShort: Show[Short] = Show.fromToString[Short] } trait LongInstances extends cats.kernel.std.LongInstances { - implicit val longShow: Show[Long] = Show.fromToString[Long] + implicit val catsShowForLong: Show[Long] = Show.fromToString[Long] } trait FloatInstances extends cats.kernel.std.FloatInstances { - implicit val floatShow: Show[Float] = Show.fromToString[Float] + implicit val catsShowForFloat: Show[Float] = Show.fromToString[Float] } trait DoubleInstances extends cats.kernel.std.DoubleInstances { - implicit val doubleShow: Show[Double] = Show.fromToString[Double] + implicit val catsShowForDouble: Show[Double] = Show.fromToString[Double] } trait BooleanInstances extends cats.kernel.std.BooleanInstances { - implicit val booleanShow: Show[Boolean] = Show.fromToString[Boolean] + implicit val catsShowForBoolean: Show[Boolean] = Show.fromToString[Boolean] } trait UnitInstances extends cats.kernel.std.UnitInstances { - implicit val unitShow: Show[Unit] = Show.fromToString[Unit] + implicit val catsShowForUnit: Show[Unit] = Show.fromToString[Unit] } diff --git a/core/src/main/scala/cats/std/bigDecimal.scala b/core/src/main/scala/cats/std/bigDecimal.scala index f3aeac15c3..b61b82798c 100644 --- a/core/src/main/scala/cats/std/bigDecimal.scala +++ b/core/src/main/scala/cats/std/bigDecimal.scala @@ -2,6 +2,6 @@ package cats package std trait BigDecimalInstances { - implicit val bigDecimalShow: Show[BigDecimal] = + implicit val catsShowForBigDecimal: Show[BigDecimal] = Show.fromToString[BigDecimal] } diff --git a/core/src/main/scala/cats/std/bigInt.scala b/core/src/main/scala/cats/std/bigInt.scala index 0c663f734e..4af909c3aa 100644 --- a/core/src/main/scala/cats/std/bigInt.scala +++ b/core/src/main/scala/cats/std/bigInt.scala @@ -2,6 +2,6 @@ package cats package std trait BigIntInstances extends cats.kernel.std.BigIntInstances { - implicit val bigIntShow: Show[BigInt] = + implicit val catsShowForBigInt: Show[BigInt] = Show.fromToString[BigInt] } diff --git a/core/src/main/scala/cats/std/either.scala b/core/src/main/scala/cats/std/either.scala index 567ee29aec..054df7fb62 100644 --- a/core/src/main/scala/cats/std/either.scala +++ b/core/src/main/scala/cats/std/either.scala @@ -2,7 +2,7 @@ package cats package std trait EitherInstances extends EitherInstances1 { - implicit val eitherBitraverse: Bitraverse[Either] = + implicit val catsBitraverseForEither: Bitraverse[Either] = new Bitraverse[Either] { def bitraverse[G[_], A, B, C, D](fab: Either[A, B])(f: A => G[C], g: B => G[D])(implicit G: Applicative[G]): G[Either[C, D]] = fab match { @@ -23,7 +23,7 @@ trait EitherInstances extends EitherInstances1 { } } - implicit def eitherInstances[A]: Monad[Either[A, ?]] with Traverse[Either[A, ?]] = + implicit def catsMonadForEither[A]: Monad[Either[A, ?]] with Traverse[Either[A, ?]] = new Monad[Either[A, ?]] with Traverse[Either[A, ?]] { def pure[B](b: B): Either[A, B] = Right(b) @@ -55,14 +55,14 @@ trait EitherInstances extends EitherInstances1 { fa.fold(_ => lc, b => f(b, lc)) } - implicit def eitherOrder[A, B](implicit A: Order[A], B: Order[B]): Order[Either[A, B]] = new Order[Either[A, B]] { + implicit def catsOrderForEither[A, B](implicit A: Order[A], B: Order[B]): Order[Either[A, B]] = new Order[Either[A, B]] { def compare(x: Either[A, B], y: Either[A, B]): Int = x.fold( a => y.fold(A.compare(a, _), _ => -1), b => y.fold(_ => 1, B.compare(b, _)) ) } - implicit def eitherShow[A, B](implicit A: Show[A], B: Show[B]): Show[Either[A, B]] = + implicit def catsShowForEither[A, B](implicit A: Show[A], B: Show[B]): Show[Either[A, B]] = new Show[Either[A, B]] { def show(f: Either[A, B]): String = f.fold( a => s"Left(${A.show(a)})", @@ -72,7 +72,7 @@ trait EitherInstances extends EitherInstances1 { } private[std] sealed trait EitherInstances1 extends EitherInstances2 { - implicit def eitherPartialOrder[A, B](implicit A: PartialOrder[A], B: PartialOrder[B]): PartialOrder[Either[A, B]] = + implicit def catsPartialOrderForEither[A, B](implicit A: PartialOrder[A], B: PartialOrder[B]): PartialOrder[Either[A, B]] = new PartialOrder[Either[A, B]] { def partialCompare(x: Either[A, B], y: Either[A, B]): Double = x.fold( a => y.fold(A.partialCompare(a, _), _ => -1), @@ -82,7 +82,7 @@ private[std] sealed trait EitherInstances1 extends EitherInstances2 { } private[std] sealed trait EitherInstances2 { - implicit def eitherEq[A, B](implicit A: Eq[A], B: Eq[B]): Eq[Either[A, B]] = new Eq[Either[A, B]] { + implicit def catsEqForEither[A, B](implicit A: Eq[A], B: Eq[B]): Eq[Either[A, B]] = new Eq[Either[A, B]] { def eqv(x: Either[A, B], y: Either[A, B]): Boolean = x.fold( a => y.fold(A.eqv(a, _), _ => false), b => y.fold(_ => false, B.eqv(b, _)) diff --git a/core/src/main/scala/cats/std/function.scala b/core/src/main/scala/cats/std/function.scala index f19d20a816..2face19c59 100644 --- a/core/src/main/scala/cats/std/function.scala +++ b/core/src/main/scala/cats/std/function.scala @@ -7,7 +7,7 @@ import cats.functor.Contravariant private[std] sealed trait Function0Instances { - implicit val function0Instance: Bimonad[Function0] = + implicit val catsBimonadForFunction0: Bimonad[Function0] = new Bimonad[Function0] { def extract[A](x: () => A): A = x() @@ -27,13 +27,13 @@ private[std] sealed trait Function0Instances { } private[std] sealed trait Function1Instances extends Function1Instances0 { - implicit def function1Contravariant[R]: Contravariant[? => R] = + implicit def catsContravariantForFunction1[R]: Contravariant[? => R] = new Contravariant[? => R] { def contramap[T1, T0](fa: T1 => R)(f: T0 => T1): T0 => R = fa.compose(f) } - implicit def function1Covariant[T1]: MonadReader[T1 => ?, T1] = + implicit def catsMonadReaderForFunction1[T1]: MonadReader[T1 => ?, T1] = new MonadReader[T1 => ?, T1] { def pure[R](r: R): T1 => R = _ => r @@ -48,7 +48,7 @@ private[std] sealed trait Function1Instances extends Function1Instances0 { f.compose(fa) } - implicit val function1Instance: Choice[Function1] with Arrow[Function1] = + implicit val catsChoiceForFunction1: Choice[Function1] with Arrow[Function1] = new Choice[Function1] with Arrow[Function1] { def choice[A, B, C](f: A => C, g: B => C): Xor[A, B] => C = _ match { @@ -71,18 +71,18 @@ private[std] sealed trait Function1Instances extends Function1Instances0 { def compose[A, B, C](f: B => C, g: A => B): A => C = f.compose(g) } - implicit def function1Monoid[A,B](implicit M: Monoid[B]): Monoid[A => B] = + implicit def catsMonoidForFunction1[A,B](implicit M: Monoid[B]): Monoid[A => B] = new Function1Monoid[A, B] { def B: Monoid[B] = M } - implicit val function1MonoidK: MonoidK[Lambda[A => A => A]] = + implicit val catsMonoidKForFunction1: MonoidK[Lambda[A => A => A]] = new Function1MonoidK {} } private[std] sealed trait Function1Instances0 { - implicit def function1Semigroup[A,B](implicit S: Semigroup[B]): Semigroup[A => B] = + implicit def catsSemigroupForFunction1[A,B](implicit S: Semigroup[B]): Semigroup[A => B] = new Function1Semigroup[A, B] { def B: Semigroup[B] = S } - implicit val function1SemigroupK: SemigroupK[Lambda[A => A => A]] = + implicit val catsSemigroupKForFunction1: SemigroupK[Lambda[A => A => A]] = new Function1SemigroupK {} } diff --git a/core/src/main/scala/cats/std/future.scala b/core/src/main/scala/cats/std/future.scala index e1453870d6..f9b255a4ff 100644 --- a/core/src/main/scala/cats/std/future.scala +++ b/core/src/main/scala/cats/std/future.scala @@ -9,7 +9,7 @@ import scala.concurrent.{ExecutionContext, Future} trait FutureInstances extends FutureInstances1 { - implicit def futureInstance(implicit ec: ExecutionContext): MonadError[Future, Throwable] with CoflatMap[Future] = + implicit def catsMonadErrorCoFlatMapForFuture(implicit ec: ExecutionContext): MonadError[Future, Throwable] with CoflatMap[Future] = new FutureCoflatMap with MonadError[Future, Throwable]{ def pure[A](x: A): Future[A] = Future.successful(x) @@ -35,17 +35,17 @@ trait FutureInstances extends FutureInstances1 { override def map[A, B](fa: Future[A])(f: A => B): Future[B] = fa.map(f) } - implicit def futureGroup[A: Group](implicit ec: ExecutionContext): Group[Future[A]] = + implicit def catsGroupForFuture[A: Group](implicit ec: ExecutionContext): Group[Future[A]] = new FutureGroup[A] } private[std] sealed trait FutureInstances1 extends FutureInstances2 { - implicit def futureMonoid[A: Monoid](implicit ec: ExecutionContext): Monoid[Future[A]] = + implicit def catsMonoidForFuture[A: Monoid](implicit ec: ExecutionContext): Monoid[Future[A]] = new FutureMonoid[A] } private[std] sealed trait FutureInstances2 { - implicit def futureSemigroup[A: Semigroup](implicit ec: ExecutionContext): Semigroup[Future[A]] = + implicit def catsSemigroupForFuture[A: Semigroup](implicit ec: ExecutionContext): Semigroup[Future[A]] = new FutureSemigroup[A] } diff --git a/core/src/main/scala/cats/std/list.scala b/core/src/main/scala/cats/std/list.scala index 85a5231740..885a93e4fe 100644 --- a/core/src/main/scala/cats/std/list.scala +++ b/core/src/main/scala/cats/std/list.scala @@ -8,7 +8,7 @@ import scala.collection.mutable.ListBuffer trait ListInstances extends cats.kernel.std.ListInstances { - implicit val listInstance: Traverse[List] with MonadCombine[List] with CoflatMap[List] = + implicit val catsTraverseMonadCombineCoflatMapForList: Traverse[List] with MonadCombine[List] with CoflatMap[List] = new Traverse[List] with MonadCombine[List] with CoflatMap[List] { def empty[A]: List[A] = Nil @@ -61,7 +61,7 @@ trait ListInstances extends cats.kernel.std.ListInstances { override def isEmpty[A](fa: List[A]): Boolean = fa.isEmpty } - implicit def listShow[A:Show]: Show[List[A]] = + implicit def catsShowForList[A:Show]: Show[List[A]] = new Show[List[A]] { def show(fa: List[A]): String = fa.map(_.show).mkString("List(", ", ", ")") } diff --git a/core/src/main/scala/cats/std/map.scala b/core/src/main/scala/cats/std/map.scala index 3b6d4d4a2b..00a4b4323e 100644 --- a/core/src/main/scala/cats/std/map.scala +++ b/core/src/main/scala/cats/std/map.scala @@ -3,7 +3,7 @@ package std trait MapInstances extends cats.kernel.std.MapInstances { - implicit def MapShow[A, B](implicit showA: Show[A], showB: Show[B]): Show[Map[A, B]] = + implicit def catsShowForMap[A, B](implicit showA: Show[A], showB: Show[B]): Show[Map[A, B]] = Show.show[Map[A, B]] { m => val body = m.map { case (a, b) => s"${showA.show(a)} -> ${showB.show(b)})" @@ -11,7 +11,7 @@ trait MapInstances extends cats.kernel.std.MapInstances { s"Map($body)" } - implicit def mapInstance[K]: Traverse[Map[K, ?]] with FlatMap[Map[K, ?]] = + implicit def catsTraverseFlatMapForMap[K]: Traverse[Map[K, ?]] with FlatMap[Map[K, ?]] = new Traverse[Map[K, ?]] with FlatMap[Map[K, ?]] { def traverse[G[_], A, B](fa: Map[K, A])(f: (A) => G[B])(implicit G: Applicative[G]): G[Map[K, B]] = { diff --git a/core/src/main/scala/cats/std/option.scala b/core/src/main/scala/cats/std/option.scala index 7ffef7c4bb..c6b4e435c3 100644 --- a/core/src/main/scala/cats/std/option.scala +++ b/core/src/main/scala/cats/std/option.scala @@ -3,7 +3,7 @@ package std trait OptionInstances extends cats.kernel.std.OptionInstances { - implicit val optionInstance: Traverse[Option] with MonadError[Option, Unit] with MonadCombine[Option] with CoflatMap[Option] with Alternative[Option] = + implicit val catsTraverseMonadErrorMonadCombineCoflatMapAlternativeForOption: Traverse[Option] with MonadError[Option, Unit] with MonadCombine[Option] with CoflatMap[Option] with Alternative[Option] = new Traverse[Option] with MonadError[Option, Unit] with MonadCombine[Option] with CoflatMap[Option] with Alternative[Option] { def empty[A]: Option[A] = None @@ -62,7 +62,7 @@ trait OptionInstances extends cats.kernel.std.OptionInstances { fa.isEmpty } - implicit def showOption[A](implicit A: Show[A]): Show[Option[A]] = + implicit def catsShowForOption[A](implicit A: Show[A]): Show[Option[A]] = new Show[Option[A]] { def show(fa: Option[A]): String = fa match { case Some(a) => s"Some(${A.show(a)})" diff --git a/core/src/main/scala/cats/std/set.scala b/core/src/main/scala/cats/std/set.scala index 7ac35ef22e..79dd1e8d9f 100644 --- a/core/src/main/scala/cats/std/set.scala +++ b/core/src/main/scala/cats/std/set.scala @@ -5,7 +5,7 @@ import cats.syntax.show._ trait SetInstances extends cats.kernel.std.SetInstances { - implicit val setInstance: Foldable[Set] with MonoidK[Set] = + implicit val catsFoldableMonoidKForSet: Foldable[Set] with MonoidK[Set] = new Foldable[Set] with MonoidK[Set] { def empty[A]: Set[A] = Set.empty[A] @@ -27,7 +27,7 @@ trait SetInstances extends cats.kernel.std.SetInstances { override def isEmpty[A](fa: Set[A]): Boolean = fa.isEmpty } - implicit def setShow[A:Show]: Show[Set[A]] = new Show[Set[A]] { + implicit def catsShowForSet[A:Show]: Show[Set[A]] = new Show[Set[A]] { def show(fa: Set[A]): String = fa.toIterator.map(_.show).mkString("Set(", ", ", ")") } diff --git a/core/src/main/scala/cats/std/stream.scala b/core/src/main/scala/cats/std/stream.scala index da26f238ba..3f694a7d3e 100644 --- a/core/src/main/scala/cats/std/stream.scala +++ b/core/src/main/scala/cats/std/stream.scala @@ -4,7 +4,7 @@ package std import cats.syntax.show._ trait StreamInstances extends cats.kernel.std.StreamInstances { - implicit val streamInstance: Traverse[Stream] with MonadCombine[Stream] with CoflatMap[Stream] = + implicit val catsTraverseMonadCombineCoflatMapForStream: Traverse[Stream] with MonadCombine[Stream] with CoflatMap[Stream] = new Traverse[Stream] with MonadCombine[Stream] with CoflatMap[Stream] { def empty[A]: Stream[A] = Stream.Empty @@ -55,7 +55,7 @@ trait StreamInstances extends cats.kernel.std.StreamInstances { override def isEmpty[A](fa: Stream[A]): Boolean = fa.isEmpty } - implicit def streamShow[A: Show]: Show[Stream[A]] = + implicit def catsShowForStream[A: Show]: Show[Stream[A]] = new Show[Stream[A]] { def show(fa: Stream[A]): String = if(fa.isEmpty) "Stream()" else s"Stream(${fa.head.show}, ?)" } diff --git a/core/src/main/scala/cats/std/string.scala b/core/src/main/scala/cats/std/string.scala index ca96850460..c947774ccf 100644 --- a/core/src/main/scala/cats/std/string.scala +++ b/core/src/main/scala/cats/std/string.scala @@ -2,6 +2,6 @@ package cats package std trait StringInstances extends cats.kernel.std.StringInstances { - implicit val stringShow: Show[String] = + implicit val catsShowForString: Show[String] = Show.fromToString[String] } diff --git a/core/src/main/scala/cats/std/tuple.scala b/core/src/main/scala/cats/std/tuple.scala index a79d702948..2314f7b709 100644 --- a/core/src/main/scala/cats/std/tuple.scala +++ b/core/src/main/scala/cats/std/tuple.scala @@ -4,7 +4,7 @@ package std trait TupleInstances extends Tuple2Instances with cats.kernel.std.TupleInstances sealed trait Tuple2Instances { - implicit val tuple2Bitraverse: Bitraverse[Tuple2] = + implicit val catsBitraverseForTuple2: Bitraverse[Tuple2] = new Bitraverse[Tuple2] { def bitraverse[G[_]: Applicative, A, B, C, D](fab: (A, B))(f: A => G[C], g: B => G[D]): G[(C, D)] = Applicative[G].tuple2(f(fab._1), g(fab._2)) @@ -16,7 +16,7 @@ sealed trait Tuple2Instances { g(fab._2, f(fab._1, c)) } - implicit def tuple2Show[A, B](implicit aShow: Show[A], bShow: Show[B]): Show[(A, B)] = new Show[(A, B)] { + implicit def catsShowForTuple2[A, B](implicit aShow: Show[A], bShow: Show[B]): Show[(A, B)] = new Show[(A, B)] { override def show(f: (A, B)): String = { s"(${aShow.show(f._1)},${bShow.show(f._2)})" } diff --git a/core/src/main/scala/cats/std/vector.scala b/core/src/main/scala/cats/std/vector.scala index fd6591127a..f67b3c8edc 100644 --- a/core/src/main/scala/cats/std/vector.scala +++ b/core/src/main/scala/cats/std/vector.scala @@ -8,7 +8,7 @@ import scala.collection.+: import scala.collection.immutable.VectorBuilder trait VectorInstances extends cats.kernel.std.VectorInstances { - implicit val vectorInstance: Traverse[Vector] with MonadCombine[Vector] with CoflatMap[Vector] = + implicit val catsTraverseMonadCombineCoflatMapForVector: Traverse[Vector] with MonadCombine[Vector] with CoflatMap[Vector] = new Traverse[Vector] with MonadCombine[Vector] with CoflatMap[Vector] { def empty[A]: Vector[A] = Vector.empty[A] @@ -55,7 +55,7 @@ trait VectorInstances extends cats.kernel.std.VectorInstances { override def isEmpty[A](fa: Vector[A]): Boolean = fa.isEmpty } - implicit def vectorShow[A:Show]: Show[Vector[A]] = + implicit def catsShowForVector[A:Show]: Show[Vector[A]] = new Show[Vector[A]] { def show(fa: Vector[A]): String = fa.map(_.show).mkString("Vector(", ", ", ")") } From 67a846e94666a68560ad0814229cc602b0522658 Mon Sep 17 00:00:00 2001 From: Kailuo Wang Date: Fri, 27 May 2016 09:48:24 -0400 Subject: [PATCH 29/40] fixed typo --- core/src/main/scala/cats/std/anyval.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/src/main/scala/cats/std/anyval.scala b/core/src/main/scala/cats/std/anyval.scala index 5bd6b357ad..404e399249 100644 --- a/core/src/main/scala/cats/std/anyval.scala +++ b/core/src/main/scala/cats/std/anyval.scala @@ -14,7 +14,7 @@ trait AnyValInstances with TupleInstances trait IntInstances extends cats.kernel.std.IntInstances { - implicit val catsShowForcatsForInt: Show[Int] = Show.fromToString[Int] + implicit val catsShowForInt: Show[Int] = Show.fromToString[Int] } trait ByteInstances extends cats.kernel.std.ByteInstances { From 4b3d6f389270132804ca843ad9da4d543fcb0a6d Mon Sep 17 00:00:00 2001 From: Kailuo Wang Date: Fri, 27 May 2016 09:57:25 -0400 Subject: [PATCH 30/40] added some missing typecalsses back to implicit val names --- core/src/main/scala/cats/std/either.scala | 2 +- core/src/main/scala/cats/std/function.scala | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/core/src/main/scala/cats/std/either.scala b/core/src/main/scala/cats/std/either.scala index 054df7fb62..9fde66c71a 100644 --- a/core/src/main/scala/cats/std/either.scala +++ b/core/src/main/scala/cats/std/either.scala @@ -23,7 +23,7 @@ trait EitherInstances extends EitherInstances1 { } } - implicit def catsMonadForEither[A]: Monad[Either[A, ?]] with Traverse[Either[A, ?]] = + implicit def catsMonadTraverseForEither[A]: Monad[Either[A, ?]] with Traverse[Either[A, ?]] = new Monad[Either[A, ?]] with Traverse[Either[A, ?]] { def pure[B](b: B): Either[A, B] = Right(b) diff --git a/core/src/main/scala/cats/std/function.scala b/core/src/main/scala/cats/std/function.scala index 2face19c59..fae6aa4df5 100644 --- a/core/src/main/scala/cats/std/function.scala +++ b/core/src/main/scala/cats/std/function.scala @@ -48,7 +48,7 @@ private[std] sealed trait Function1Instances extends Function1Instances0 { f.compose(fa) } - implicit val catsChoiceForFunction1: Choice[Function1] with Arrow[Function1] = + implicit val catsChoiceArrowForFunction1: Choice[Function1] with Arrow[Function1] = new Choice[Function1] with Arrow[Function1] { def choice[A, B, C](f: A => C, g: B => C): Xor[A, B] => C = _ match { From 495bff7d0b908d51325761f6f496d92c5d66e901 Mon Sep 17 00:00:00 2001 From: Kailuo Wang Date: Fri, 27 May 2016 11:47:36 -0400 Subject: [PATCH 31/40] use full package name for implicit val def names --- core/src/main/scala/cats/std/anyval.scala | 18 +++++++++--------- core/src/main/scala/cats/std/bigDecimal.scala | 2 +- core/src/main/scala/cats/std/bigInt.scala | 2 +- core/src/main/scala/cats/std/either.scala | 12 ++++++------ core/src/main/scala/cats/std/function.scala | 18 +++++++++--------- core/src/main/scala/cats/std/future.scala | 8 ++++---- core/src/main/scala/cats/std/list.scala | 4 ++-- core/src/main/scala/cats/std/map.scala | 4 ++-- core/src/main/scala/cats/std/option.scala | 4 ++-- core/src/main/scala/cats/std/set.scala | 4 ++-- core/src/main/scala/cats/std/stream.scala | 4 ++-- core/src/main/scala/cats/std/string.scala | 2 +- core/src/main/scala/cats/std/tuple.scala | 4 ++-- core/src/main/scala/cats/std/vector.scala | 4 ++-- free/src/main/scala/cats/free/Trampoline.scala | 2 +- .../test/scala/cats/tests/EitherTests.scala | 4 ++-- .../test/scala/cats/tests/FunctionTests.scala | 6 +++--- tests/src/test/scala/cats/tests/SetTests.scala | 3 ++- 18 files changed, 53 insertions(+), 52 deletions(-) diff --git a/core/src/main/scala/cats/std/anyval.scala b/core/src/main/scala/cats/std/anyval.scala index 404e399249..98a09b7f87 100644 --- a/core/src/main/scala/cats/std/anyval.scala +++ b/core/src/main/scala/cats/std/anyval.scala @@ -14,37 +14,37 @@ trait AnyValInstances with TupleInstances trait IntInstances extends cats.kernel.std.IntInstances { - implicit val catsShowForInt: Show[Int] = Show.fromToString[Int] + implicit val catsStdShowForInt: Show[Int] = Show.fromToString[Int] } trait ByteInstances extends cats.kernel.std.ByteInstances { - implicit val catsShowForByte: Show[Byte] = Show.fromToString[Byte] + implicit val catsStdShowForByte: Show[Byte] = Show.fromToString[Byte] } trait CharInstances extends cats.kernel.std.CharInstances { - implicit val catsShowForChar: Show[Char] = Show.fromToString[Char] + implicit val catsStdShowForChar: Show[Char] = Show.fromToString[Char] } trait ShortInstances extends cats.kernel.std.ShortInstances { - implicit val catsShowForShort: Show[Short] = Show.fromToString[Short] + implicit val catsStdShowForShort: Show[Short] = Show.fromToString[Short] } trait LongInstances extends cats.kernel.std.LongInstances { - implicit val catsShowForLong: Show[Long] = Show.fromToString[Long] + implicit val catsStdShowForLong: Show[Long] = Show.fromToString[Long] } trait FloatInstances extends cats.kernel.std.FloatInstances { - implicit val catsShowForFloat: Show[Float] = Show.fromToString[Float] + implicit val catsStdShowForFloat: Show[Float] = Show.fromToString[Float] } trait DoubleInstances extends cats.kernel.std.DoubleInstances { - implicit val catsShowForDouble: Show[Double] = Show.fromToString[Double] + implicit val catsStdShowForDouble: Show[Double] = Show.fromToString[Double] } trait BooleanInstances extends cats.kernel.std.BooleanInstances { - implicit val catsShowForBoolean: Show[Boolean] = Show.fromToString[Boolean] + implicit val catsStdShowForBoolean: Show[Boolean] = Show.fromToString[Boolean] } trait UnitInstances extends cats.kernel.std.UnitInstances { - implicit val catsShowForUnit: Show[Unit] = Show.fromToString[Unit] + implicit val catsStdShowForUnit: Show[Unit] = Show.fromToString[Unit] } diff --git a/core/src/main/scala/cats/std/bigDecimal.scala b/core/src/main/scala/cats/std/bigDecimal.scala index b61b82798c..572bcf24ee 100644 --- a/core/src/main/scala/cats/std/bigDecimal.scala +++ b/core/src/main/scala/cats/std/bigDecimal.scala @@ -2,6 +2,6 @@ package cats package std trait BigDecimalInstances { - implicit val catsShowForBigDecimal: Show[BigDecimal] = + implicit val catsStdShowForBigDecimal: Show[BigDecimal] = Show.fromToString[BigDecimal] } diff --git a/core/src/main/scala/cats/std/bigInt.scala b/core/src/main/scala/cats/std/bigInt.scala index 4af909c3aa..03d680eec9 100644 --- a/core/src/main/scala/cats/std/bigInt.scala +++ b/core/src/main/scala/cats/std/bigInt.scala @@ -2,6 +2,6 @@ package cats package std trait BigIntInstances extends cats.kernel.std.BigIntInstances { - implicit val catsShowForBigInt: Show[BigInt] = + implicit val catsStdShowForBigInt: Show[BigInt] = Show.fromToString[BigInt] } diff --git a/core/src/main/scala/cats/std/either.scala b/core/src/main/scala/cats/std/either.scala index 9fde66c71a..43962597bf 100644 --- a/core/src/main/scala/cats/std/either.scala +++ b/core/src/main/scala/cats/std/either.scala @@ -2,7 +2,7 @@ package cats package std trait EitherInstances extends EitherInstances1 { - implicit val catsBitraverseForEither: Bitraverse[Either] = + implicit val catsStdBitraverseForEither: Bitraverse[Either] = new Bitraverse[Either] { def bitraverse[G[_], A, B, C, D](fab: Either[A, B])(f: A => G[C], g: B => G[D])(implicit G: Applicative[G]): G[Either[C, D]] = fab match { @@ -23,7 +23,7 @@ trait EitherInstances extends EitherInstances1 { } } - implicit def catsMonadTraverseForEither[A]: Monad[Either[A, ?]] with Traverse[Either[A, ?]] = + implicit def catsStdInstancesForEither[A]: Monad[Either[A, ?]] with Traverse[Either[A, ?]] = new Monad[Either[A, ?]] with Traverse[Either[A, ?]] { def pure[B](b: B): Either[A, B] = Right(b) @@ -55,14 +55,14 @@ trait EitherInstances extends EitherInstances1 { fa.fold(_ => lc, b => f(b, lc)) } - implicit def catsOrderForEither[A, B](implicit A: Order[A], B: Order[B]): Order[Either[A, B]] = new Order[Either[A, B]] { + implicit def catsStdOrderForEither[A, B](implicit A: Order[A], B: Order[B]): Order[Either[A, B]] = new Order[Either[A, B]] { def compare(x: Either[A, B], y: Either[A, B]): Int = x.fold( a => y.fold(A.compare(a, _), _ => -1), b => y.fold(_ => 1, B.compare(b, _)) ) } - implicit def catsShowForEither[A, B](implicit A: Show[A], B: Show[B]): Show[Either[A, B]] = + implicit def catsStdShowForEither[A, B](implicit A: Show[A], B: Show[B]): Show[Either[A, B]] = new Show[Either[A, B]] { def show(f: Either[A, B]): String = f.fold( a => s"Left(${A.show(a)})", @@ -72,7 +72,7 @@ trait EitherInstances extends EitherInstances1 { } private[std] sealed trait EitherInstances1 extends EitherInstances2 { - implicit def catsPartialOrderForEither[A, B](implicit A: PartialOrder[A], B: PartialOrder[B]): PartialOrder[Either[A, B]] = + implicit def catsStdPartialOrderForEither[A, B](implicit A: PartialOrder[A], B: PartialOrder[B]): PartialOrder[Either[A, B]] = new PartialOrder[Either[A, B]] { def partialCompare(x: Either[A, B], y: Either[A, B]): Double = x.fold( a => y.fold(A.partialCompare(a, _), _ => -1), @@ -82,7 +82,7 @@ private[std] sealed trait EitherInstances1 extends EitherInstances2 { } private[std] sealed trait EitherInstances2 { - implicit def catsEqForEither[A, B](implicit A: Eq[A], B: Eq[B]): Eq[Either[A, B]] = new Eq[Either[A, B]] { + implicit def catsStdEqForEither[A, B](implicit A: Eq[A], B: Eq[B]): Eq[Either[A, B]] = new Eq[Either[A, B]] { def eqv(x: Either[A, B], y: Either[A, B]): Boolean = x.fold( a => y.fold(A.eqv(a, _), _ => false), b => y.fold(_ => false, B.eqv(b, _)) diff --git a/core/src/main/scala/cats/std/function.scala b/core/src/main/scala/cats/std/function.scala index fae6aa4df5..5d29283179 100644 --- a/core/src/main/scala/cats/std/function.scala +++ b/core/src/main/scala/cats/std/function.scala @@ -7,7 +7,7 @@ import cats.functor.Contravariant private[std] sealed trait Function0Instances { - implicit val catsBimonadForFunction0: Bimonad[Function0] = + implicit val catsStdBimonadForFunction0: Bimonad[Function0] = new Bimonad[Function0] { def extract[A](x: () => A): A = x() @@ -20,20 +20,20 @@ private[std] sealed trait Function0Instances { () => f(fa())() } - implicit def eqFunction0[A](implicit A: Eq[A]): Eq[() => A] = + implicit def catsStdEqForFunction0[A](implicit A: Eq[A]): Eq[() => A] = new Eq[() => A] { def eqv(x: () => A, y: () => A): Boolean = A.eqv(x(), y()) } } private[std] sealed trait Function1Instances extends Function1Instances0 { - implicit def catsContravariantForFunction1[R]: Contravariant[? => R] = + implicit def catsStdContravariantForFunction1[R]: Contravariant[? => R] = new Contravariant[? => R] { def contramap[T1, T0](fa: T1 => R)(f: T0 => T1): T0 => R = fa.compose(f) } - implicit def catsMonadReaderForFunction1[T1]: MonadReader[T1 => ?, T1] = + implicit def catsStdMonadReaderForFunction1[T1]: MonadReader[T1 => ?, T1] = new MonadReader[T1 => ?, T1] { def pure[R](r: R): T1 => R = _ => r @@ -48,7 +48,7 @@ private[std] sealed trait Function1Instances extends Function1Instances0 { f.compose(fa) } - implicit val catsChoiceArrowForFunction1: Choice[Function1] with Arrow[Function1] = + implicit val catsStdInstancesForFunction1: Choice[Function1] with Arrow[Function1] = new Choice[Function1] with Arrow[Function1] { def choice[A, B, C](f: A => C, g: B => C): Xor[A, B] => C = _ match { @@ -71,18 +71,18 @@ private[std] sealed trait Function1Instances extends Function1Instances0 { def compose[A, B, C](f: B => C, g: A => B): A => C = f.compose(g) } - implicit def catsMonoidForFunction1[A,B](implicit M: Monoid[B]): Monoid[A => B] = + implicit def catsStdMonoidForFunction1[A,B](implicit M: Monoid[B]): Monoid[A => B] = new Function1Monoid[A, B] { def B: Monoid[B] = M } - implicit val catsMonoidKForFunction1: MonoidK[Lambda[A => A => A]] = + implicit val catsStdMonoidKForFunction1: MonoidK[Lambda[A => A => A]] = new Function1MonoidK {} } private[std] sealed trait Function1Instances0 { - implicit def catsSemigroupForFunction1[A,B](implicit S: Semigroup[B]): Semigroup[A => B] = + implicit def catsStdSemigroupForFunction1[A,B](implicit S: Semigroup[B]): Semigroup[A => B] = new Function1Semigroup[A, B] { def B: Semigroup[B] = S } - implicit val catsSemigroupKForFunction1: SemigroupK[Lambda[A => A => A]] = + implicit val catsStdSemigroupKForFunction1: SemigroupK[Lambda[A => A => A]] = new Function1SemigroupK {} } diff --git a/core/src/main/scala/cats/std/future.scala b/core/src/main/scala/cats/std/future.scala index f9b255a4ff..40cc5cf556 100644 --- a/core/src/main/scala/cats/std/future.scala +++ b/core/src/main/scala/cats/std/future.scala @@ -9,7 +9,7 @@ import scala.concurrent.{ExecutionContext, Future} trait FutureInstances extends FutureInstances1 { - implicit def catsMonadErrorCoFlatMapForFuture(implicit ec: ExecutionContext): MonadError[Future, Throwable] with CoflatMap[Future] = + implicit def catsStdInstancesForFuture(implicit ec: ExecutionContext): MonadError[Future, Throwable] with CoflatMap[Future] = new FutureCoflatMap with MonadError[Future, Throwable]{ def pure[A](x: A): Future[A] = Future.successful(x) @@ -35,17 +35,17 @@ trait FutureInstances extends FutureInstances1 { override def map[A, B](fa: Future[A])(f: A => B): Future[B] = fa.map(f) } - implicit def catsGroupForFuture[A: Group](implicit ec: ExecutionContext): Group[Future[A]] = + implicit def catsStdGroupForFuture[A: Group](implicit ec: ExecutionContext): Group[Future[A]] = new FutureGroup[A] } private[std] sealed trait FutureInstances1 extends FutureInstances2 { - implicit def catsMonoidForFuture[A: Monoid](implicit ec: ExecutionContext): Monoid[Future[A]] = + implicit def catsStdMonoidForFuture[A: Monoid](implicit ec: ExecutionContext): Monoid[Future[A]] = new FutureMonoid[A] } private[std] sealed trait FutureInstances2 { - implicit def catsSemigroupForFuture[A: Semigroup](implicit ec: ExecutionContext): Semigroup[Future[A]] = + implicit def catsStdSemigroupForFuture[A: Semigroup](implicit ec: ExecutionContext): Semigroup[Future[A]] = new FutureSemigroup[A] } diff --git a/core/src/main/scala/cats/std/list.scala b/core/src/main/scala/cats/std/list.scala index 885a93e4fe..102ad05e71 100644 --- a/core/src/main/scala/cats/std/list.scala +++ b/core/src/main/scala/cats/std/list.scala @@ -8,7 +8,7 @@ import scala.collection.mutable.ListBuffer trait ListInstances extends cats.kernel.std.ListInstances { - implicit val catsTraverseMonadCombineCoflatMapForList: Traverse[List] with MonadCombine[List] with CoflatMap[List] = + implicit val catsStdInstancesForList: Traverse[List] with MonadCombine[List] with CoflatMap[List] = new Traverse[List] with MonadCombine[List] with CoflatMap[List] { def empty[A]: List[A] = Nil @@ -61,7 +61,7 @@ trait ListInstances extends cats.kernel.std.ListInstances { override def isEmpty[A](fa: List[A]): Boolean = fa.isEmpty } - implicit def catsShowForList[A:Show]: Show[List[A]] = + implicit def catsStdShowForList[A:Show]: Show[List[A]] = new Show[List[A]] { def show(fa: List[A]): String = fa.map(_.show).mkString("List(", ", ", ")") } diff --git a/core/src/main/scala/cats/std/map.scala b/core/src/main/scala/cats/std/map.scala index 00a4b4323e..9ee18cb689 100644 --- a/core/src/main/scala/cats/std/map.scala +++ b/core/src/main/scala/cats/std/map.scala @@ -3,7 +3,7 @@ package std trait MapInstances extends cats.kernel.std.MapInstances { - implicit def catsShowForMap[A, B](implicit showA: Show[A], showB: Show[B]): Show[Map[A, B]] = + implicit def catsStdShowForMap[A, B](implicit showA: Show[A], showB: Show[B]): Show[Map[A, B]] = Show.show[Map[A, B]] { m => val body = m.map { case (a, b) => s"${showA.show(a)} -> ${showB.show(b)})" @@ -11,7 +11,7 @@ trait MapInstances extends cats.kernel.std.MapInstances { s"Map($body)" } - implicit def catsTraverseFlatMapForMap[K]: Traverse[Map[K, ?]] with FlatMap[Map[K, ?]] = + implicit def catsStdInstancesForMap[K]: Traverse[Map[K, ?]] with FlatMap[Map[K, ?]] = new Traverse[Map[K, ?]] with FlatMap[Map[K, ?]] { def traverse[G[_], A, B](fa: Map[K, A])(f: (A) => G[B])(implicit G: Applicative[G]): G[Map[K, B]] = { diff --git a/core/src/main/scala/cats/std/option.scala b/core/src/main/scala/cats/std/option.scala index c6b4e435c3..af943b923b 100644 --- a/core/src/main/scala/cats/std/option.scala +++ b/core/src/main/scala/cats/std/option.scala @@ -3,7 +3,7 @@ package std trait OptionInstances extends cats.kernel.std.OptionInstances { - implicit val catsTraverseMonadErrorMonadCombineCoflatMapAlternativeForOption: Traverse[Option] with MonadError[Option, Unit] with MonadCombine[Option] with CoflatMap[Option] with Alternative[Option] = + implicit val catsStdInstancesForOption: Traverse[Option] with MonadError[Option, Unit] with MonadCombine[Option] with CoflatMap[Option] with Alternative[Option] = new Traverse[Option] with MonadError[Option, Unit] with MonadCombine[Option] with CoflatMap[Option] with Alternative[Option] { def empty[A]: Option[A] = None @@ -62,7 +62,7 @@ trait OptionInstances extends cats.kernel.std.OptionInstances { fa.isEmpty } - implicit def catsShowForOption[A](implicit A: Show[A]): Show[Option[A]] = + implicit def catsStdShowForOption[A](implicit A: Show[A]): Show[Option[A]] = new Show[Option[A]] { def show(fa: Option[A]): String = fa match { case Some(a) => s"Some(${A.show(a)})" diff --git a/core/src/main/scala/cats/std/set.scala b/core/src/main/scala/cats/std/set.scala index 79dd1e8d9f..09da1a88de 100644 --- a/core/src/main/scala/cats/std/set.scala +++ b/core/src/main/scala/cats/std/set.scala @@ -5,7 +5,7 @@ import cats.syntax.show._ trait SetInstances extends cats.kernel.std.SetInstances { - implicit val catsFoldableMonoidKForSet: Foldable[Set] with MonoidK[Set] = + implicit val catsStdInstancesForSet: Foldable[Set] with MonoidK[Set] = new Foldable[Set] with MonoidK[Set] { def empty[A]: Set[A] = Set.empty[A] @@ -27,7 +27,7 @@ trait SetInstances extends cats.kernel.std.SetInstances { override def isEmpty[A](fa: Set[A]): Boolean = fa.isEmpty } - implicit def catsShowForSet[A:Show]: Show[Set[A]] = new Show[Set[A]] { + implicit def catsStdShowForSet[A:Show]: Show[Set[A]] = new Show[Set[A]] { def show(fa: Set[A]): String = fa.toIterator.map(_.show).mkString("Set(", ", ", ")") } diff --git a/core/src/main/scala/cats/std/stream.scala b/core/src/main/scala/cats/std/stream.scala index 3f694a7d3e..b2b5595dae 100644 --- a/core/src/main/scala/cats/std/stream.scala +++ b/core/src/main/scala/cats/std/stream.scala @@ -4,7 +4,7 @@ package std import cats.syntax.show._ trait StreamInstances extends cats.kernel.std.StreamInstances { - implicit val catsTraverseMonadCombineCoflatMapForStream: Traverse[Stream] with MonadCombine[Stream] with CoflatMap[Stream] = + implicit val catsStdInstancesForStream: Traverse[Stream] with MonadCombine[Stream] with CoflatMap[Stream] = new Traverse[Stream] with MonadCombine[Stream] with CoflatMap[Stream] { def empty[A]: Stream[A] = Stream.Empty @@ -55,7 +55,7 @@ trait StreamInstances extends cats.kernel.std.StreamInstances { override def isEmpty[A](fa: Stream[A]): Boolean = fa.isEmpty } - implicit def catsShowForStream[A: Show]: Show[Stream[A]] = + implicit def catsStdShowForStream[A: Show]: Show[Stream[A]] = new Show[Stream[A]] { def show(fa: Stream[A]): String = if(fa.isEmpty) "Stream()" else s"Stream(${fa.head.show}, ?)" } diff --git a/core/src/main/scala/cats/std/string.scala b/core/src/main/scala/cats/std/string.scala index c947774ccf..7f46057ea2 100644 --- a/core/src/main/scala/cats/std/string.scala +++ b/core/src/main/scala/cats/std/string.scala @@ -2,6 +2,6 @@ package cats package std trait StringInstances extends cats.kernel.std.StringInstances { - implicit val catsShowForString: Show[String] = + implicit val catsStdShowForString: Show[String] = Show.fromToString[String] } diff --git a/core/src/main/scala/cats/std/tuple.scala b/core/src/main/scala/cats/std/tuple.scala index 2314f7b709..76b9050e06 100644 --- a/core/src/main/scala/cats/std/tuple.scala +++ b/core/src/main/scala/cats/std/tuple.scala @@ -4,7 +4,7 @@ package std trait TupleInstances extends Tuple2Instances with cats.kernel.std.TupleInstances sealed trait Tuple2Instances { - implicit val catsBitraverseForTuple2: Bitraverse[Tuple2] = + implicit val catsStdBitraverseForTuple2: Bitraverse[Tuple2] = new Bitraverse[Tuple2] { def bitraverse[G[_]: Applicative, A, B, C, D](fab: (A, B))(f: A => G[C], g: B => G[D]): G[(C, D)] = Applicative[G].tuple2(f(fab._1), g(fab._2)) @@ -16,7 +16,7 @@ sealed trait Tuple2Instances { g(fab._2, f(fab._1, c)) } - implicit def catsShowForTuple2[A, B](implicit aShow: Show[A], bShow: Show[B]): Show[(A, B)] = new Show[(A, B)] { + implicit def catsStdShowForTuple2[A, B](implicit aShow: Show[A], bShow: Show[B]): Show[(A, B)] = new Show[(A, B)] { override def show(f: (A, B)): String = { s"(${aShow.show(f._1)},${bShow.show(f._2)})" } diff --git a/core/src/main/scala/cats/std/vector.scala b/core/src/main/scala/cats/std/vector.scala index f67b3c8edc..62ead466a3 100644 --- a/core/src/main/scala/cats/std/vector.scala +++ b/core/src/main/scala/cats/std/vector.scala @@ -8,7 +8,7 @@ import scala.collection.+: import scala.collection.immutable.VectorBuilder trait VectorInstances extends cats.kernel.std.VectorInstances { - implicit val catsTraverseMonadCombineCoflatMapForVector: Traverse[Vector] with MonadCombine[Vector] with CoflatMap[Vector] = + implicit val catsStdInstancesForVector: Traverse[Vector] with MonadCombine[Vector] with CoflatMap[Vector] = new Traverse[Vector] with MonadCombine[Vector] with CoflatMap[Vector] { def empty[A]: Vector[A] = Vector.empty[A] @@ -55,7 +55,7 @@ trait VectorInstances extends cats.kernel.std.VectorInstances { override def isEmpty[A](fa: Vector[A]): Boolean = fa.isEmpty } - implicit def catsShowForVector[A:Show]: Show[Vector[A]] = + implicit def catsStdShowForVector[A:Show]: Show[Vector[A]] = new Show[Vector[A]] { def show(fa: Vector[A]): String = fa.map(_.show).mkString("Vector(", ", ", ")") } diff --git a/free/src/main/scala/cats/free/Trampoline.scala b/free/src/main/scala/cats/free/Trampoline.scala index e5f68c06b1..663fd32080 100644 --- a/free/src/main/scala/cats/free/Trampoline.scala +++ b/free/src/main/scala/cats/free/Trampoline.scala @@ -1,7 +1,7 @@ package cats package free -import cats.std.function.function0Instance +import cats.std.function.catsStdBimonadForFunction0 // To workaround SI-7139 `object Trampoline` needs to be defined inside the package object // together with the type alias. diff --git a/tests/src/test/scala/cats/tests/EitherTests.scala b/tests/src/test/scala/cats/tests/EitherTests.scala index d0ab3237ee..97d7d74e08 100644 --- a/tests/src/test/scala/cats/tests/EitherTests.scala +++ b/tests/src/test/scala/cats/tests/EitherTests.scala @@ -20,7 +20,7 @@ class EitherTests extends CatsSuite { checkAll("Either[?, ?]", BitraverseTests[Either].bitraverse[Option, Int, Int, Int, String, String, String]) checkAll("Bitraverse[Either]", SerializableTests.serializable(Bitraverse[Either])) - val partialOrder = eitherPartialOrder[Int, String] + val partialOrder = catsStdPartialOrderForEither[Int, String] val order = implicitly[Order[Either[Int, String]]] val monad = implicitly[Monad[Either[Int, ?]]] val show = implicitly[Show[Either[Int, String]]] @@ -38,7 +38,7 @@ class EitherTests extends CatsSuite { test("implicit instances resolve specifically") { - val eq = eitherEq[Int, String] + val eq = catsStdEqForEither[Int, String] assert(!eq.isInstanceOf[PartialOrder[_]]) assert(!eq.isInstanceOf[Order[_]]) assert(!partialOrder.isInstanceOf[Order[_]]) diff --git a/tests/src/test/scala/cats/tests/FunctionTests.scala b/tests/src/test/scala/cats/tests/FunctionTests.scala index d7ca5cf729..07e65eefcd 100644 --- a/tests/src/test/scala/cats/tests/FunctionTests.scala +++ b/tests/src/test/scala/cats/tests/FunctionTests.scala @@ -32,13 +32,13 @@ class FunctionTests extends CatsSuite { checkAll("Function1[Int, Int]", ContravariantTests[? => Int].contravariant[Int, Int, Int]) checkAll("Contravariant[? => Int]", SerializableTests.serializable(Contravariant[? => Int])) - checkAll("Function1[String, Int]", GroupLaws[Function1[String, Int]].semigroup(function1Semigroup[String, Int])) + checkAll("Function1[String, Int]", GroupLaws[Function1[String, Int]].semigroup(catsStdSemigroupForFunction1[String, Int])) checkAll("Function1[String, Int]", GroupLaws[Function1[String, Int]].monoid) checkAll("Function1[Int, Int]", MonoidKTests[Lambda[A => A => A]].semigroupK[Int]) - checkAll("SemigroupK[Lambda[A => A => A]", SerializableTests.serializable(function1SemigroupK)) + checkAll("SemigroupK[Lambda[A => A => A]", SerializableTests.serializable(catsStdSemigroupKForFunction1)) checkAll("Function1[Int, Int]", MonoidKTests[Lambda[A => A => A]].monoidK[Int]) - checkAll("MonoidK[Lambda[A => A => A]", SerializableTests.serializable(function1MonoidK)) + checkAll("MonoidK[Lambda[A => A => A]", SerializableTests.serializable(catsStdMonoidKForFunction1)) } diff --git a/tests/src/test/scala/cats/tests/SetTests.scala b/tests/src/test/scala/cats/tests/SetTests.scala index e4716df529..663151ac5d 100644 --- a/tests/src/test/scala/cats/tests/SetTests.scala +++ b/tests/src/test/scala/cats/tests/SetTests.scala @@ -22,7 +22,8 @@ class SetTests extends CatsSuite { } test("show keeps separate entries for items that map to identical strings"){ - implicit val intShow: Show[Int] = Show.show(_ => "1") + //note: this val name has to be the same to shadow the cats.std instance + implicit val catsStdShowForInt: Show[Int] = Show.show(_ => "1") // an implementation implemented as set.map(_.show).mkString(", ") would // only show one entry in the result instead of 3, because Set.map combines // duplicate items in the codomain. From 49c7eecdd8618b4a3ee74f2c18469cc8228295c3 Mon Sep 17 00:00:00 2001 From: Kailuo Wang Date: Fri, 27 May 2016 10:43:35 -0400 Subject: [PATCH 32/40] renamed implicit vals in data, part 2 of #1061 --- core/src/main/scala/cats/data/Cokleisli.scala | 12 ++-- core/src/main/scala/cats/data/Const.scala | 22 +++---- core/src/main/scala/cats/data/Coproduct.scala | 14 ++--- core/src/main/scala/cats/data/Func.scala | 6 +- core/src/main/scala/cats/data/Ior.scala | 10 ++-- core/src/main/scala/cats/data/Kleisli.scala | 48 +++++++-------- core/src/main/scala/cats/data/OneAnd.scala | 18 +++--- core/src/main/scala/cats/data/OptionT.scala | 10 ++-- core/src/main/scala/cats/data/Prod.scala | 14 ++--- core/src/main/scala/cats/data/StateT.scala | 4 +- core/src/main/scala/cats/data/Validated.scala | 12 ++-- core/src/main/scala/cats/data/WriterT.scala | 60 +++++++++---------- core/src/main/scala/cats/data/Xor.scala | 18 +++--- core/src/main/scala/cats/data/XorT.scala | 26 ++++---- .../scala/cats/tests/CokleisliTests.scala | 4 +- .../test/scala/cats/tests/ConstTests.scala | 4 +- .../scala/cats/tests/CoproductTests.scala | 4 +- .../src/test/scala/cats/tests/FuncTests.scala | 6 +- .../test/scala/cats/tests/KleisliTests.scala | 36 +++++------ .../test/scala/cats/tests/OneAndTests.scala | 2 +- .../scala/cats/tests/ValidatedTests.scala | 2 +- .../test/scala/cats/tests/WriterTTests.scala | 2 +- .../src/test/scala/cats/tests/XorTTests.scala | 4 +- .../src/test/scala/cats/tests/XorTests.scala | 2 +- 24 files changed, 170 insertions(+), 170 deletions(-) diff --git a/core/src/main/scala/cats/data/Cokleisli.scala b/core/src/main/scala/cats/data/Cokleisli.scala index 4aa36b0d55..a4bfdecb67 100644 --- a/core/src/main/scala/cats/data/Cokleisli.scala +++ b/core/src/main/scala/cats/data/Cokleisli.scala @@ -44,10 +44,10 @@ object Cokleisli extends CokleisliInstances { } private[data] sealed abstract class CokleisliInstances extends CokleisliInstances0 { - implicit def cokleisliArrow[F[_]](implicit ev: Comonad[F]): Arrow[Cokleisli[F, ?, ?]] = + implicit def catsDataArrowForCokleisli[F[_]](implicit ev: Comonad[F]): Arrow[Cokleisli[F, ?, ?]] = new CokleisliArrow[F] { def F: Comonad[F] = ev } - implicit def cokleisliMonad[F[_], A]: Monad[Cokleisli[F, A, ?]] = new Monad[Cokleisli[F, A, ?]] { + implicit def catsDataMonadForCokleisli[F[_], A]: Monad[Cokleisli[F, A, ?]] = new Monad[Cokleisli[F, A, ?]] { def pure[B](x: B): Cokleisli[F, A, B] = Cokleisli.pure(x) @@ -58,18 +58,18 @@ private[data] sealed abstract class CokleisliInstances extends CokleisliInstance fa.map(f) } - implicit def cokleisliMonoidK[F[_]](implicit ev: Comonad[F]): MonoidK[Lambda[A => Cokleisli[F, A, A]]] = + implicit def catsDataMonoidKForCokleisli[F[_]](implicit ev: Comonad[F]): MonoidK[Lambda[A => Cokleisli[F, A, A]]] = new CokleisliMonoidK[F] { def F: Comonad[F] = ev } } private[data] sealed abstract class CokleisliInstances0 { - implicit def cokleisliSplit[F[_]](implicit ev: CoflatMap[F]): Split[Cokleisli[F, ?, ?]] = + implicit def catsDataSplitForCokleisli[F[_]](implicit ev: CoflatMap[F]): Split[Cokleisli[F, ?, ?]] = new CokleisliSplit[F] { def F: CoflatMap[F] = ev } - implicit def cokleisliProfunctor[F[_]](implicit ev: Functor[F]): Profunctor[Cokleisli[F, ?, ?]] = + implicit def catsDataProfunctorForCokleisli[F[_]](implicit ev: Functor[F]): Profunctor[Cokleisli[F, ?, ?]] = new CokleisliProfunctor[F] { def F: Functor[F] = ev } - implicit def cokleisliSemigroupK[F[_]](implicit ev: CoflatMap[F]): SemigroupK[Lambda[A => Cokleisli[F, A, A]]] = + implicit def catsDataSemigroupKForCokleisli[F[_]](implicit ev: CoflatMap[F]): SemigroupK[Lambda[A => Cokleisli[F, A, A]]] = new CokleisliSemigroupK[F] { def F: CoflatMap[F] = ev } } diff --git a/core/src/main/scala/cats/data/Const.scala b/core/src/main/scala/cats/data/Const.scala index 32fc1e3b91..083bd236bf 100644 --- a/core/src/main/scala/cats/data/Const.scala +++ b/core/src/main/scala/cats/data/Const.scala @@ -39,21 +39,21 @@ object Const extends ConstInstances { } private[data] sealed abstract class ConstInstances extends ConstInstances0 { - implicit def constOrder[A: Order, B]: Order[Const[A, B]] = new Order[Const[A, B]] { + implicit def catsDataOrderForConst[A: Order, B]: Order[Const[A, B]] = new Order[Const[A, B]] { def compare(x: Const[A, B], y: Const[A, B]): Int = x compare y } - implicit def constShow[A: Show, B]: Show[Const[A, B]] = new Show[Const[A, B]] { + implicit def catsDataShowForConst[A: Show, B]: Show[Const[A, B]] = new Show[Const[A, B]] { def show(f: Const[A, B]): String = f.show } - implicit def constContravariant[C]: Contravariant[Const[C, ?]] = new Contravariant[Const[C, ?]] { + implicit def catsDataContravariantForConst[C]: Contravariant[Const[C, ?]] = new Contravariant[Const[C, ?]] { override def contramap[A, B](fa: Const[C, A])(f: (B) => A): Const[C, B] = fa.retag[B] } - implicit def constTraverse[C]: Traverse[Const[C, ?]] = new Traverse[Const[C, ?]] { + implicit def catsDataTraverseForConst[C]: Traverse[Const[C, ?]] = new Traverse[Const[C, ?]] { def traverse[G[_]: Applicative, A, B](fa: Const[C, A])(f: A => G[B]): G[Const[C, B]] = fa.traverse(f) @@ -62,7 +62,7 @@ private[data] sealed abstract class ConstInstances extends ConstInstances0 { def foldRight[A, B](fa: Const[C, A], lb: Eval[B])(f: (A, Eval[B]) => Eval[B]): Eval[B] = lb } - implicit def constMonoid[A: Monoid, B]: Monoid[Const[A, B]] = new Monoid[Const[A, B]]{ + implicit def catsDataMonoidForConst[A: Monoid, B]: Monoid[Const[A, B]] = new Monoid[Const[A, B]]{ def empty: Const[A, B] = Const.empty @@ -70,7 +70,7 @@ private[data] sealed abstract class ConstInstances extends ConstInstances0 { x combine y } - implicit val constBifoldable: Bifoldable[Const] = + implicit val catsDataBifoldableForConst: Bifoldable[Const] = new Bifoldable[Const] { def bifoldLeft[A, B, C](fab: Const[A, B], c: C)(f: (C, A) => C, g: (C, B) => C): C = f(c, fab.getConst) @@ -82,16 +82,16 @@ private[data] sealed abstract class ConstInstances extends ConstInstances0 { private[data] sealed abstract class ConstInstances0 extends ConstInstances1 { - implicit def constSemigroup[A: Semigroup, B]: Semigroup[Const[A, B]] = new Semigroup[Const[A, B]] { + implicit def catsDataSemigroupForConst[A: Semigroup, B]: Semigroup[Const[A, B]] = new Semigroup[Const[A, B]] { def combine(x: Const[A, B], y: Const[A, B]): Const[A, B] = x combine y } - implicit def constPartialOrder[A: PartialOrder, B]: PartialOrder[Const[A, B]] = new PartialOrder[Const[A, B]]{ + implicit def catsDataPartialOrderForConst[A: PartialOrder, B]: PartialOrder[Const[A, B]] = new PartialOrder[Const[A, B]]{ def partialCompare(x: Const[A, B], y: Const[A, B]): Double = x partialCompare y } - implicit def constApplicative[C: Monoid]: Applicative[Const[C, ?]] = new Applicative[Const[C, ?]] { + implicit def catsDataApplicativeForConst[C: Monoid]: Applicative[Const[C, ?]] = new Applicative[Const[C, ?]] { def pure[A](x: A): Const[C, A] = Const.empty @@ -107,12 +107,12 @@ private[data] sealed abstract class ConstInstances0 extends ConstInstances1 { } private[data] sealed abstract class ConstInstances1 { - implicit def constEq[A: Eq, B]: Eq[Const[A, B]] = new Eq[Const[A, B]] { + implicit def catsDataEqForConst[A: Eq, B]: Eq[Const[A, B]] = new Eq[Const[A, B]] { def eqv(x: Const[A, B], y: Const[A, B]): Boolean = x === y } - implicit def constApply[C: Semigroup]: Apply[Const[C, ?]] = new Apply[Const[C, ?]] { + implicit def catsDataApplyForConst[C: Semigroup]: Apply[Const[C, ?]] = new Apply[Const[C, ?]] { def ap[A, B](f: Const[C, A => B])(fa: Const[C, A]): Const[C, B] = fa.retag[B] combine f.retag[B] diff --git a/core/src/main/scala/cats/data/Coproduct.scala b/core/src/main/scala/cats/data/Coproduct.scala index 8e963b07a5..1428abd123 100644 --- a/core/src/main/scala/cats/data/Coproduct.scala +++ b/core/src/main/scala/cats/data/Coproduct.scala @@ -105,17 +105,17 @@ object Coproduct extends CoproductInstances { private[data] sealed abstract class CoproductInstances3 { - implicit def coproductEq[F[_], G[_], A](implicit E: Eq[F[A] Xor G[A]]): Eq[Coproduct[F, G, A]] = + implicit def catsDataEqForCoproduct[F[_], G[_], A](implicit E: Eq[F[A] Xor G[A]]): Eq[Coproduct[F, G, A]] = Eq.by(_.run) - implicit def coproductFunctor[F[_], G[_]](implicit F0: Functor[F], G0: Functor[G]): Functor[Coproduct[F, G, ?]] = + implicit def catsDataFunctorForCoproduct[F[_], G[_]](implicit F0: Functor[F], G0: Functor[G]): Functor[Coproduct[F, G, ?]] = new CoproductFunctor[F, G] { implicit def F: Functor[F] = F0 implicit def G: Functor[G] = G0 } - implicit def coproductFoldable[F[_], G[_]](implicit F0: Foldable[F], G0: Foldable[G]): Foldable[Coproduct[F, G, ?]] = + implicit def catsDataFoldableForCoproduct[F[_], G[_]](implicit F0: Foldable[F], G0: Foldable[G]): Foldable[Coproduct[F, G, ?]] = new CoproductFoldable[F, G] { implicit def F: Foldable[F] = F0 @@ -125,7 +125,7 @@ private[data] sealed abstract class CoproductInstances3 { private[data] sealed abstract class CoproductInstances2 extends CoproductInstances3 { - implicit def coproductContravariant[F[_], G[_]](implicit F0: Contravariant[F], G0: Contravariant[G]): Contravariant[Coproduct[F, G, ?]] = + implicit def catsDataContravariantForCoproduct[F[_], G[_]](implicit F0: Contravariant[F], G0: Contravariant[G]): Contravariant[Coproduct[F, G, ?]] = new CoproductContravariant[F, G] { implicit def F: Contravariant[F] = F0 @@ -134,7 +134,7 @@ private[data] sealed abstract class CoproductInstances2 extends CoproductInstanc } private[data] sealed abstract class CoproductInstances1 extends CoproductInstances2 { - implicit def coproductCoflatMap[F[_], G[_]](implicit F0: CoflatMap[F], G0: CoflatMap[G]): CoflatMap[Coproduct[F, G, ?]] = + implicit def catsDataCoflatMapForCoproduct[F[_], G[_]](implicit F0: CoflatMap[F], G0: CoflatMap[G]): CoflatMap[Coproduct[F, G, ?]] = new CoproductCoflatMap[F, G] { implicit def F: CoflatMap[F] = F0 @@ -143,7 +143,7 @@ private[data] sealed abstract class CoproductInstances1 extends CoproductInstanc } private[data] sealed abstract class CoproductInstances0 extends CoproductInstances1 { - implicit def coproductTraverse[F[_], G[_]](implicit F0: Traverse[F], G0: Traverse[G]): Traverse[Coproduct[F, G, ?]] = + implicit def catsDataTraverseForCoproduct[F[_], G[_]](implicit F0: Traverse[F], G0: Traverse[G]): Traverse[Coproduct[F, G, ?]] = new CoproductTraverse[F, G] { implicit def F: Traverse[F] = F0 @@ -153,7 +153,7 @@ private[data] sealed abstract class CoproductInstances0 extends CoproductInstanc sealed abstract class CoproductInstances extends CoproductInstances0 { - implicit def coproductComonad[F[_], G[_]](implicit F0: Comonad[F], G0: Comonad[G]): Comonad[Coproduct[F, G, ?]] = + implicit def catsDataComonadForCoproduct[F[_], G[_]](implicit F0: Comonad[F], G0: Comonad[G]): Comonad[Coproduct[F, G, ?]] = new CoproductComonad[F, G] { implicit def F: Comonad[F] = F0 diff --git a/core/src/main/scala/cats/data/Func.scala b/core/src/main/scala/cats/data/Func.scala index 54487031ff..d8ce1916f3 100644 --- a/core/src/main/scala/cats/data/Func.scala +++ b/core/src/main/scala/cats/data/Func.scala @@ -32,21 +32,21 @@ object Func extends FuncInstances { } private[data] abstract class FuncInstances extends FuncInstances0 { - implicit def funcApplicative[F[_], C](implicit FF: Applicative[F]): Applicative[Lambda[X => Func[F, C, X]]] = + implicit def catsDataApplicativeForFunc[F[_], C](implicit FF: Applicative[F]): Applicative[Lambda[X => Func[F, C, X]]] = new FuncApplicative[F, C] { def F: Applicative[F] = FF } } private[data] abstract class FuncInstances0 extends FuncInstances1 { - implicit def funcApply[F[_], C](implicit FF: Apply[F]): Apply[Lambda[X => Func[F, C, X]]] = + implicit def catsDataApplyForFunc[F[_], C](implicit FF: Apply[F]): Apply[Lambda[X => Func[F, C, X]]] = new FuncApply[F, C] { def F: Apply[F] = FF } } private[data] abstract class FuncInstances1 { - implicit def funcFunctor[F[_], C](implicit FF: Functor[F]): Functor[Lambda[X => Func[F, C, X]]] = + implicit def catsDataFunctorForFunc[F[_], C](implicit FF: Functor[F]): Functor[Lambda[X => Func[F, C, X]]] = new FuncFunctor[F, C] { def F: Functor[F] = FF } diff --git a/core/src/main/scala/cats/data/Ior.scala b/core/src/main/scala/cats/data/Ior.scala index 8ad8e6e6f6..4c60724314 100644 --- a/core/src/main/scala/cats/data/Ior.scala +++ b/core/src/main/scala/cats/data/Ior.scala @@ -132,20 +132,20 @@ object Ior extends IorInstances with IorFunctions { } private[data] sealed abstract class IorInstances extends IorInstances0 { - implicit def iorEq[A: Eq, B: Eq]: Eq[A Ior B] = new Eq[A Ior B] { + implicit def catsDataEqForIor[A: Eq, B: Eq]: Eq[A Ior B] = new Eq[A Ior B] { def eqv(x: A Ior B, y: A Ior B): Boolean = x === y } - implicit def iorShow[A: Show, B: Show]: Show[A Ior B] = new Show[A Ior B] { + implicit def catsDataShowForIor[A: Show, B: Show]: Show[A Ior B] = new Show[A Ior B] { def show(f: A Ior B): String = f.show } - implicit def iorMonad[A: Semigroup]: Monad[A Ior ?] = new Monad[A Ior ?] { + implicit def catsDataMonadForIor[A: Semigroup]: Monad[A Ior ?] = new Monad[A Ior ?] { def pure[B](b: B): A Ior B = Ior.right(b) def flatMap[B, C](fa: A Ior B)(f: B => A Ior C): A Ior C = fa.flatMap(f) } - implicit def iorBifunctor: Bifunctor[Ior] = + implicit def catsDataBifunctorForIor: Bifunctor[Ior] = new Bifunctor[Ior] { override def bimap[A, B, C, D](fab: A Ior B)(f: A => C, g: B => D): C Ior D = fab.bimap(f, g) } @@ -153,7 +153,7 @@ private[data] sealed abstract class IorInstances extends IorInstances0 { private[data] sealed abstract class IorInstances0 { - implicit def iorInstances[A]: Traverse[A Ior ?] with Functor[A Ior ?] = new Traverse[A Ior ?] with Functor[A Ior ?] { + implicit def catsDataTraverseFunctorForIor[A]: Traverse[A Ior ?] with Functor[A Ior ?] = new Traverse[A Ior ?] with Functor[A Ior ?] { def traverse[F[_]: Applicative, B, C](fa: A Ior B)(f: B => F[C]): F[A Ior C] = fa.traverse(f) def foldLeft[B, C](fa: A Ior B, b: C)(f: (C, B) => C): C = diff --git a/core/src/main/scala/cats/data/Kleisli.scala b/core/src/main/scala/cats/data/Kleisli.scala index 83c3ca502e..ea4b58c33c 100644 --- a/core/src/main/scala/cats/data/Kleisli.scala +++ b/core/src/main/scala/cats/data/Kleisli.scala @@ -79,22 +79,22 @@ private[data] sealed trait KleisliFunctions { private[data] sealed abstract class KleisliInstances extends KleisliInstances0 { - implicit def kleisliMonoid[F[_], A, B](implicit M: Monoid[F[B]]): Monoid[Kleisli[F, A, B]] = + implicit def catsDataMonoidForKleisli[F[_], A, B](implicit M: Monoid[F[B]]): Monoid[Kleisli[F, A, B]] = new KleisliMonoid[F, A, B] { def FB: Monoid[F[B]] = M } - implicit def kleisliMonoidK[F[_]](implicit M: Monad[F]): MonoidK[Lambda[A => Kleisli[F, A, A]]] = + implicit def catsDataMonoidKForKleisli[F[_]](implicit M: Monad[F]): MonoidK[Lambda[A => Kleisli[F, A, A]]] = new KleisliMonoidK[F] { def F: Monad[F] = M } - implicit val kleisliIdMonoidK: MonoidK[Lambda[A => Kleisli[Id, A, A]]] = - kleisliMonoidK[Id] + implicit val catsDataMonoidKForKleisliId: MonoidK[Lambda[A => Kleisli[Id, A, A]]] = + catsDataMonoidKForKleisli[Id] - implicit def kleisliArrow[F[_]](implicit ev: Monad[F]): Arrow[Kleisli[F, ?, ?]] = + implicit def catsDataArrowForKleisli[F[_]](implicit ev: Monad[F]): Arrow[Kleisli[F, ?, ?]] = new KleisliArrow[F] { def F: Monad[F] = ev } - implicit val kleisliIdArrow: Arrow[Kleisli[Id, ?, ?]] = - kleisliArrow[Id] + implicit val catsDataArrowForKleisliId: Arrow[Kleisli[Id, ?, ?]] = + catsDataArrowForKleisli[Id] - implicit def kleisliChoice[F[_]](implicit ev: Monad[F]): Choice[Kleisli[F, ?, ?]] = + implicit def catsDataChoiceForKleisli[F[_]](implicit ev: Monad[F]): Choice[Kleisli[F, ?, ?]] = new Choice[Kleisli[F, ?, ?]] { def id[A]: Kleisli[F, A, A] = Kleisli(ev.pure(_)) @@ -105,37 +105,37 @@ private[data] sealed abstract class KleisliInstances extends KleisliInstances0 { f.compose(g) } - implicit val kleisliIdChoice: Choice[Kleisli[Id, ?, ?]] = - kleisliChoice[Id] + implicit val catsDataChoiceForKleisliId: Choice[Kleisli[Id, ?, ?]] = + catsDataChoiceForKleisli[Id] - implicit def kleisliIdMonadReader[A]: MonadReader[Kleisli[Id, A, ?], A] = - kleisliMonadReader[Id, A] + implicit def catsDataMonadReaderForKleisliId[A]: MonadReader[Kleisli[Id, A, ?], A] = + catsDataMonadReaderForKleisli[Id, A] - implicit def kleisliContravariant[F[_], C]: Contravariant[Kleisli[F, ?, C]] = + implicit def catsDataContravariantForKleisli[F[_], C]: Contravariant[Kleisli[F, ?, C]] = new Contravariant[Kleisli[F, ?, C]] { override def contramap[A, B](fa: Kleisli[F, A, C])(f: (B) => A): Kleisli[F, B, C] = fa.local(f) } - implicit def kleisliTransLift[A]: TransLift.AuxId[Kleisli[?[_], A, ?]] = + implicit def catsDataTransLiftForKleisli[A]: TransLift.AuxId[Kleisli[?[_], A, ?]] = new TransLift[Kleisli[?[_], A, ?]] { type TC[M[_]] = Trivial def liftT[M[_], B](ma: M[B])(implicit ev: Trivial): Kleisli[M, A, B] = Kleisli[M, A, B](a => ma) } - implicit def kleisliApplicativeError[F[_], A, E](implicit AE: ApplicativeError[F, E]): ApplicativeError[Kleisli[F, A, ?], E] + implicit def catsDataApplicativeErrorForKleisli[F[_], A, E](implicit AE: ApplicativeError[F, E]): ApplicativeError[Kleisli[F, A, ?], E] = new KleisliApplicativeError[F, A, E] { implicit def AF: ApplicativeError[F, E] = AE } } private[data] sealed abstract class KleisliInstances0 extends KleisliInstances1 { - implicit def kleisliSplit[F[_]](implicit ev: FlatMap[F]): Split[Kleisli[F, ?, ?]] = + implicit def catsDataSplitForKleisli[F[_]](implicit ev: FlatMap[F]): Split[Kleisli[F, ?, ?]] = new KleisliSplit[F] { def F: FlatMap[F] = ev } - implicit def kleisliStrong[F[_]](implicit ev: Functor[F]): Strong[Kleisli[F, ?, ?]] = + implicit def catsDataStrongForKleisli[F[_]](implicit ev: Functor[F]): Strong[Kleisli[F, ?, ?]] = new KleisliStrong[F] { def F: Functor[F] = ev } - implicit def kleisliFlatMap[F[_]: FlatMap, A]: FlatMap[Kleisli[F, A, ?]] = new FlatMap[Kleisli[F, A, ?]] { + implicit def catsDataFlatMapForKleisli[F[_]: FlatMap, A]: FlatMap[Kleisli[F, A, ?]] = new FlatMap[Kleisli[F, A, ?]] { def flatMap[B, C](fa: Kleisli[F, A, B])(f: B => Kleisli[F, A, C]): Kleisli[F, A, C] = fa.flatMap(f) @@ -143,22 +143,22 @@ private[data] sealed abstract class KleisliInstances0 extends KleisliInstances1 fa.map(f) } - implicit def kleisliSemigroup[F[_], A, B](implicit M: Semigroup[F[B]]): Semigroup[Kleisli[F, A, B]] = + implicit def catsDataSemigroupForKleisli[F[_], A, B](implicit M: Semigroup[F[B]]): Semigroup[Kleisli[F, A, B]] = new KleisliSemigroup[F, A, B] { def FB: Semigroup[F[B]] = M } - implicit def kleisliSemigroupK[F[_]](implicit ev: FlatMap[F]): SemigroupK[Lambda[A => Kleisli[F, A, A]]] = + implicit def catsDataSemigroupKForKleisli[F[_]](implicit ev: FlatMap[F]): SemigroupK[Lambda[A => Kleisli[F, A, A]]] = new KleisliSemigroupK[F] { def F: FlatMap[F] = ev } } private[data] sealed abstract class KleisliInstances1 extends KleisliInstances2 { - implicit def kleisliApplicative[F[_], A](implicit A : Applicative[F]): Applicative[Kleisli[F, A, ?]] = new KleisliApplicative[F, A] { + implicit def catsDataApplicativeForKleisli[F[_], A](implicit A : Applicative[F]): Applicative[Kleisli[F, A, ?]] = new KleisliApplicative[F, A] { implicit def F: Applicative[F] = A } } private[data] sealed abstract class KleisliInstances2 extends KleisliInstances3 { - implicit def kleisliApply[F[_]: Apply, A]: Apply[Kleisli[F, A, ?]] = new Apply[Kleisli[F, A, ?]] { + implicit def catsDataApplyForKleisli[F[_]: Apply, A]: Apply[Kleisli[F, A, ?]] = new Apply[Kleisli[F, A, ?]] { def ap[B, C](f: Kleisli[F, A, B => C])(fa: Kleisli[F, A, B]): Kleisli[F, A, C] = fa.ap(f) @@ -171,7 +171,7 @@ private[data] sealed abstract class KleisliInstances2 extends KleisliInstances3 } private[data] sealed abstract class KleisliInstances3 extends KleisliInstances4 { - implicit def kleisliFunctor[F[_]: Functor, A]: Functor[Kleisli[F, A, ?]] = new Functor[Kleisli[F, A, ?]] { + implicit def catsDataFunctorForKleisli[F[_]: Functor, A]: Functor[Kleisli[F, A, ?]] = new Functor[Kleisli[F, A, ?]] { def map[B, C](fa: Kleisli[F, A, B])(f: B => C): Kleisli[F, A, C] = fa.map(f) } @@ -179,7 +179,7 @@ private[data] sealed abstract class KleisliInstances3 extends KleisliInstances4 private[data] sealed abstract class KleisliInstances4 { - implicit def kleisliMonadReader[F[_]: Monad, A]: MonadReader[Kleisli[F, A, ?], A] = + implicit def catsDataMonadReaderForKleisli[F[_]: Monad, A]: MonadReader[Kleisli[F, A, ?], A] = new MonadReader[Kleisli[F, A, ?], A] { def pure[B](x: B): Kleisli[F, A, B] = Kleisli.pure[F, A, B](x) diff --git a/core/src/main/scala/cats/data/OneAnd.scala b/core/src/main/scala/cats/data/OneAnd.scala index 84f81d9bc7..1541ceeaff 100644 --- a/core/src/main/scala/cats/data/OneAnd.scala +++ b/core/src/main/scala/cats/data/OneAnd.scala @@ -96,29 +96,29 @@ final case class OneAnd[F[_], A](head: A, tail: F[A]) { private[data] sealed trait OneAndInstances extends OneAndLowPriority2 { - implicit def oneAndEq[A, F[_]](implicit A: Eq[A], FA: Eq[F[A]]): Eq[OneAnd[F, A]] = + implicit def catsDataEqForOneAnd[A, F[_]](implicit A: Eq[A], FA: Eq[F[A]]): Eq[OneAnd[F, A]] = new Eq[OneAnd[F, A]]{ def eqv(x: OneAnd[F, A], y: OneAnd[F, A]): Boolean = x === y } - implicit def oneAndShow[A, F[_]](implicit A: Show[A], FA: Show[F[A]]): Show[OneAnd[F, A]] = + implicit def catsDataShowForOneAnd[A, F[_]](implicit A: Show[A], FA: Show[F[A]]): Show[OneAnd[F, A]] = Show.show[OneAnd[F, A]](_.show) - implicit def oneAndSemigroupK[F[_]: MonadCombine]: SemigroupK[OneAnd[F, ?]] = + implicit def catsDataSemigroupKForOneAnd[F[_]: MonadCombine]: SemigroupK[OneAnd[F, ?]] = new SemigroupK[OneAnd[F, ?]] { def combineK[A](a: OneAnd[F, A], b: OneAnd[F, A]): OneAnd[F, A] = a combine b } - implicit def oneAndSemigroup[F[_]: MonadCombine, A]: Semigroup[OneAnd[F, A]] = - oneAndSemigroupK[F].algebra + implicit def catsDataSemigroupForOneAnd[F[_]: MonadCombine, A]: Semigroup[OneAnd[F, A]] = + catsDataSemigroupKForOneAnd[F].algebra - implicit def oneAndReducible[F[_]](implicit F: Foldable[F]): Reducible[OneAnd[F, ?]] = + implicit def catsDataReducibleForOneAnd[F[_]](implicit F: Foldable[F]): Reducible[OneAnd[F, ?]] = new NonEmptyReducible[OneAnd[F,?], F] { override def split[A](fa: OneAnd[F,A]): (A, F[A]) = (fa.head, fa.tail) } - implicit def oneAndMonad[F[_]](implicit monad: MonadCombine[F]): Monad[OneAnd[F, ?]] = + implicit def catsDataMonadForOneAnd[F[_]](implicit monad: MonadCombine[F]): Monad[OneAnd[F, ?]] = new Monad[OneAnd[F, ?]] { override def map[A, B](fa: OneAnd[F, A])(f: A => B): OneAnd[F, B] = fa map f @@ -158,7 +158,7 @@ trait OneAndLowPriority0 { } trait OneAndLowPriority1 extends OneAndLowPriority0 { - implicit def oneAndFunctor[F[_]](implicit F: Functor[F]): Functor[OneAnd[F, ?]] = + implicit def catsDataFunctorForOneAnd[F[_]](implicit F: Functor[F]): Functor[OneAnd[F, ?]] = new Functor[OneAnd[F, ?]] { def map[A, B](fa: OneAnd[F, A])(f: A => B): OneAnd[F, B] = fa map f @@ -167,7 +167,7 @@ trait OneAndLowPriority1 extends OneAndLowPriority0 { } trait OneAndLowPriority2 extends OneAndLowPriority1 { - implicit def oneAndTraverse[F[_]](implicit F: Traverse[F]): Traverse[OneAnd[F, ?]] = + implicit def catsDataTraverseForOneAnd[F[_]](implicit F: Traverse[F]): Traverse[OneAnd[F, ?]] = new Traverse[OneAnd[F, ?]] { def traverse[G[_], A, B](fa: OneAnd[F, A])(f: (A) => G[B])(implicit G: Applicative[G]): G[OneAnd[F, B]] = { G.map2Eval(f(fa.head), Always(F.traverse(fa.tail)(f)))(OneAnd(_, _)).value diff --git a/core/src/main/scala/cats/data/OptionT.scala b/core/src/main/scala/cats/data/OptionT.scala index 6db53b4243..91575a4510 100644 --- a/core/src/main/scala/cats/data/OptionT.scala +++ b/core/src/main/scala/cats/data/OptionT.scala @@ -133,14 +133,14 @@ object OptionT extends OptionTInstances { } private[data] sealed trait OptionTInstances1 { - implicit def optionTFunctor[F[_]:Functor]: Functor[OptionT[F, ?]] = + implicit def catsDataFunctorForOptionT[F[_]:Functor]: Functor[OptionT[F, ?]] = new Functor[OptionT[F, ?]] { override def map[A, B](fa: OptionT[F, A])(f: A => B): OptionT[F, B] = fa.map(f) } // do NOT change this to val! I know it looks like it should work, and really I agree, but it doesn't (for... reasons) - implicit def optionTTransLift: TransLift.Aux[OptionT, Functor] = + implicit def catsDataTransLiftForOptionT: TransLift.Aux[OptionT, Functor] = new TransLift[OptionT] { type TC[M[_]] = Functor[M] @@ -150,7 +150,7 @@ private[data] sealed trait OptionTInstances1 { private[data] sealed trait OptionTInstances extends OptionTInstances1 { - implicit def optionTMonad[F[_]](implicit F: Monad[F]): Monad[OptionT[F, ?]] = + implicit def catsDataMonadForOptionT[F[_]](implicit F: Monad[F]): Monad[OptionT[F, ?]] = new Monad[OptionT[F, ?]] { def pure[A](a: A): OptionT[F, A] = OptionT.pure(a) @@ -161,9 +161,9 @@ private[data] sealed trait OptionTInstances extends OptionTInstances1 { fa.map(f) } - implicit def optionTEq[F[_], A](implicit FA: Eq[F[Option[A]]]): Eq[OptionT[F, A]] = + implicit def catsDataEqForOptionT[F[_], A](implicit FA: Eq[F[Option[A]]]): Eq[OptionT[F, A]] = FA.on(_.value) - implicit def optionTShow[F[_], A](implicit F: Show[F[Option[A]]]): Show[OptionT[F, A]] = + implicit def catsDataShowForOptionT[F[_], A](implicit F: Show[F[Option[A]]]): Show[OptionT[F, A]] = functor.Contravariant[Show].contramap(F)(_.value) } diff --git a/core/src/main/scala/cats/data/Prod.scala b/core/src/main/scala/cats/data/Prod.scala index 202c49a234..2db91594c8 100644 --- a/core/src/main/scala/cats/data/Prod.scala +++ b/core/src/main/scala/cats/data/Prod.scala @@ -11,47 +11,47 @@ final case class Prod[F[_], G[_], A](first: F[A], second: G[A]) object Prod extends ProdInstances private[data] sealed abstract class ProdInstances extends ProdInstances0 { - implicit def prodAlternative[F[_], G[_]](implicit FF: Alternative[F], GG: Alternative[G]): Alternative[Lambda[X => Prod[F, G, X]]] = new ProdAlternative[F, G] { + implicit def catsDataAlternativeForProd[F[_], G[_]](implicit FF: Alternative[F], GG: Alternative[G]): Alternative[Lambda[X => Prod[F, G, X]]] = new ProdAlternative[F, G] { def F: Alternative[F] = FF def G: Alternative[G] = GG } - implicit def prodEq[F[_], G[_], A](implicit FF: Eq[F[A]], GG: Eq[G[A]]): Eq[Prod[F, G, A]] = new Eq[Prod[F, G, A]] { + implicit def catsDataEqForProd[F[_], G[_], A](implicit FF: Eq[F[A]], GG: Eq[G[A]]): Eq[Prod[F, G, A]] = new Eq[Prod[F, G, A]] { def eqv(x: Prod[F, G, A], y: Prod[F, G, A]): Boolean = FF.eqv(x.first, y.first) && GG.eqv(x.second, y.second) } } private[data] sealed abstract class ProdInstances0 extends ProdInstances1 { - implicit def prodMonoidK[F[_], G[_]](implicit FF: MonoidK[F], GG: MonoidK[G]): MonoidK[Lambda[X => Prod[F, G, X]]] = new ProdMonoidK[F, G] { + implicit def catsDataMonoidKForProd[F[_], G[_]](implicit FF: MonoidK[F], GG: MonoidK[G]): MonoidK[Lambda[X => Prod[F, G, X]]] = new ProdMonoidK[F, G] { def F: MonoidK[F] = FF def G: MonoidK[G] = GG } } private[data] sealed abstract class ProdInstances1 extends ProdInstances2 { - implicit def prodSemigroupK[F[_], G[_]](implicit FF: SemigroupK[F], GG: SemigroupK[G]): SemigroupK[Lambda[X => Prod[F, G, X]]] = new ProdSemigroupK[F, G] { + implicit def catsDataSemigroupKForProd[F[_], G[_]](implicit FF: SemigroupK[F], GG: SemigroupK[G]): SemigroupK[Lambda[X => Prod[F, G, X]]] = new ProdSemigroupK[F, G] { def F: SemigroupK[F] = FF def G: SemigroupK[G] = GG } } private[data] sealed abstract class ProdInstances2 extends ProdInstances3 { - implicit def prodApplicative[F[_], G[_]](implicit FF: Applicative[F], GG: Applicative[G]): Applicative[Lambda[X => Prod[F, G, X]]] = new ProdApplicative[F, G] { + implicit def catsDataApplicativeForProd[F[_], G[_]](implicit FF: Applicative[F], GG: Applicative[G]): Applicative[Lambda[X => Prod[F, G, X]]] = new ProdApplicative[F, G] { def F: Applicative[F] = FF def G: Applicative[G] = GG } } private[data] sealed abstract class ProdInstances3 extends ProdInstances4 { - implicit def prodApply[F[_], G[_]](implicit FF: Apply[F], GG: Apply[G]): Apply[Lambda[X => Prod[F, G, X]]] = new ProdApply[F, G] { + implicit def catsDataApplyForProd[F[_], G[_]](implicit FF: Apply[F], GG: Apply[G]): Apply[Lambda[X => Prod[F, G, X]]] = new ProdApply[F, G] { def F: Apply[F] = FF def G: Apply[G] = GG } } private[data] sealed abstract class ProdInstances4 { - implicit def prodFunctor[F[_], G[_]](implicit FF: Functor[F], GG: Functor[G]): Functor[Lambda[X => Prod[F, G, X]]] = new ProdFunctor[F, G] { + implicit def catsDataFunctorForProd[F[_], G[_]](implicit FF: Functor[F], GG: Functor[G]): Functor[Lambda[X => Prod[F, G, X]]] = new ProdFunctor[F, G] { def F: Functor[F] = FF def G: Functor[G] = GG } diff --git a/core/src/main/scala/cats/data/StateT.scala b/core/src/main/scala/cats/data/StateT.scala index f3a2f2b3f4..e8f1406ac0 100644 --- a/core/src/main/scala/cats/data/StateT.scala +++ b/core/src/main/scala/cats/data/StateT.scala @@ -136,7 +136,7 @@ object StateT extends StateTInstances { } private[data] sealed abstract class StateTInstances { - implicit def stateTMonadState[F[_], S](implicit F: Monad[F]): MonadState[StateT[F, S, ?], S] = + implicit def catsDataMonadStateForStateT[F[_], S](implicit F: Monad[F]): MonadState[StateT[F, S, ?], S] = new MonadState[StateT[F, S, ?], S] { def pure[A](a: A): StateT[F, S, A] = StateT.pure(a) @@ -152,7 +152,7 @@ private[data] sealed abstract class StateTInstances { fa.map(f) } - implicit def stateTLift[S]: TransLift.Aux[StateT[?[_], S, ?], Applicative] = + implicit def catsDataLiftForStateT[S]: TransLift.Aux[StateT[?[_], S, ?], Applicative] = new TransLift[StateT[?[_], S, ?]] { type TC[M[_]] = Applicative[M] diff --git a/core/src/main/scala/cats/data/Validated.scala b/core/src/main/scala/cats/data/Validated.scala index 6a26c710ed..0d52616c4a 100644 --- a/core/src/main/scala/cats/data/Validated.scala +++ b/core/src/main/scala/cats/data/Validated.scala @@ -225,7 +225,7 @@ object Validated extends ValidatedInstances with ValidatedFunctions{ private[data] sealed abstract class ValidatedInstances extends ValidatedInstances1 { - implicit def validatedSemigroupK[A](implicit A: Semigroup[A]): SemigroupK[Validated[A,?]] = + implicit def catsDataSemigroupKForValidated[A](implicit A: Semigroup[A]): SemigroupK[Validated[A,?]] = new SemigroupK[Validated[A,?]] { def combineK[B](x: Validated[A,B], y: Validated[A,B]): Validated[A,B] = x match { case v @ Valid(_) => v @@ -236,22 +236,22 @@ private[data] sealed abstract class ValidatedInstances extends ValidatedInstance } } - implicit def validatedMonoid[A, B](implicit A: Semigroup[A], B: Monoid[B]): Monoid[Validated[A, B]] = new Monoid[Validated[A, B]] { + implicit def catsDataMonoidForValidated[A, B](implicit A: Semigroup[A], B: Monoid[B]): Monoid[Validated[A, B]] = new Monoid[Validated[A, B]] { def empty: Validated[A, B] = Valid(B.empty) def combine(x: Validated[A, B], y: Validated[A, B]): Validated[A, B] = x combine y } - implicit def validatedOrder[A: Order, B: Order]: Order[Validated[A,B]] = new Order[Validated[A,B]] { + implicit def catsDataOrderForValidated[A: Order, B: Order]: Order[Validated[A,B]] = new Order[Validated[A,B]] { def compare(x: Validated[A,B], y: Validated[A,B]): Int = x compare y override def partialCompare(x: Validated[A,B], y: Validated[A,B]): Double = x partialCompare y override def eqv(x: Validated[A,B], y: Validated[A,B]): Boolean = x === y } - implicit def validatedShow[A, B](implicit A: Show[A], B: Show[B]): Show[Validated[A,B]] = new Show[Validated[A,B]] { + implicit def catsDataShowForValidated[A, B](implicit A: Show[A], B: Show[B]): Show[Validated[A,B]] = new Show[Validated[A,B]] { def show(f: Validated[A,B]): String = f.show } - implicit val validatedBitraverse: Bitraverse[Validated] = + implicit val catsDataBitraverseForValidated: Bitraverse[Validated] = new Bitraverse[Validated] { def bitraverse[G[_], A, B, C, D](fab: Validated[A, B])(f: A => G[C], g: B => G[D])(implicit G: Applicative[G]): G[Validated[C, D]] = fab match { @@ -278,7 +278,7 @@ private[data] sealed abstract class ValidatedInstances extends ValidatedInstance fab.leftMap(f) } - implicit def validatedInstances[E](implicit E: Semigroup[E]): Traverse[Validated[E, ?]] with ApplicativeError[Validated[E, ?], E] = + implicit def catsDataInstancesForValidated[E](implicit E: Semigroup[E]): Traverse[Validated[E, ?]] with ApplicativeError[Validated[E, ?], E] = new Traverse[Validated[E, ?]] with ApplicativeError[Validated[E, ?], E] { def traverse[F[_]: Applicative, A, B](fa: Validated[E,A])(f: A => F[B]): F[Validated[E,B]] = fa.traverse(f) diff --git a/core/src/main/scala/cats/data/WriterT.scala b/core/src/main/scala/cats/data/WriterT.scala index 2c89f43dba..9df6c5013a 100644 --- a/core/src/main/scala/cats/data/WriterT.scala +++ b/core/src/main/scala/cats/data/WriterT.scala @@ -52,19 +52,19 @@ object WriterT extends WriterTInstances with WriterTFunctions private[data] sealed abstract class WriterTInstances extends WriterTInstances0 { - implicit def writerTIdMonad[L:Monoid]: Monad[WriterT[Id, L, ?]] = - writerTMonadWriter[Id, L] + implicit def catsDataMonadForWriterTId[L:Monoid]: Monad[WriterT[Id, L, ?]] = + catsDataMonadWriterForWriterT[Id, L] - implicit def writerTIdEq[L: Eq, V: Eq]: Eq[WriterT[Id, L, V]] = - writerTEq[Id, L, V] + implicit def catsDataEqForWriterTId[L: Eq, V: Eq]: Eq[WriterT[Id, L, V]] = + catsDataEqForWriterT[Id, L, V] - implicit def writerTBifunctor[F[_]:Functor]: Bifunctor[WriterT[F, ?, ?]] = + implicit def catsDataBifunctorForWriterT[F[_]:Functor]: Bifunctor[WriterT[F, ?, ?]] = new Bifunctor[WriterT[F, ?, ?]] { def bimap[A, B, C, D](fab: WriterT[F, A, B])(f: A => C, g: B => D): WriterT[F, C, D] = fab.bimap(f, g) } - implicit def writerTTransLift[W](implicit W: Monoid[W]): TransLift.Aux[WriterT[?[_], W, ?], Functor] = + implicit def catsDataTransLiftForWriterT[W](implicit W: Monoid[W]): TransLift.Aux[WriterT[?[_], W, ?], Functor] = new TransLift[WriterT[?[_], W, ?]] { type TC[M[_]] = Functor[M] @@ -72,62 +72,63 @@ private[data] sealed abstract class WriterTInstances extends WriterTInstances0 { WriterT(Functor[M].map(ma)((W.empty, _))) } - implicit def writerTShow[F[_], L, V](implicit F: Show[F[(L, V)]]): Show[WriterT[F, L, V]] = new Show[WriterT[F, L, V]] { + implicit def catsDataShowForWriterT[F[_], L, V](implicit F: Show[F[(L, V)]]): Show[WriterT[F, L, V]] = new Show[WriterT[F, L, V]] { override def show(f: WriterT[F, L, V]): String = f.show } - implicit def writerTIdMonoid[L:Monoid, V:Monoid]: Monoid[WriterT[Id, L, V]] = - writerTMonoid[Id, L, V] + implicit def catsDataMonoidForWriterTId[L:Monoid, V:Monoid]: Monoid[WriterT[Id, L, V]] = + catsDataMonoidForWriterT[Id, L, V] } private[data] sealed abstract class WriterTInstances0 extends WriterTInstances1 { - implicit def writerTMonadCombine[F[_], L](implicit F: MonadCombine[F], L: Monoid[L]): MonadCombine[WriterT[F, L, ?]] = + implicit def catsDataMonadCombineForWriterT[F[_], L](implicit F: MonadCombine[F], L: Monoid[L]): MonadCombine[WriterT[F, L, ?]] = new WriterTMonadCombine[F, L] { implicit val F0: MonadCombine[F] = F implicit val L0: Monoid[L] = L } - implicit def writerTIdFlatMap[L:Semigroup]: FlatMap[WriterT[Id, L, ?]] = - writerTFlatMap[Id, L] + implicit def catsDataFlatMapForWriterTId[L:Semigroup]: FlatMap[WriterT[Id, L, ?]] = + catsDataFlatMapForWriterT[Id, L] - implicit def writerTEq[F[_], L, V](implicit F: Eq[F[(L, V)]]): Eq[WriterT[F, L, V]] = + implicit def catsDataEqForWriterT[F[_], L, V](implicit F: Eq[F[(L, V)]]): Eq[WriterT[F, L, V]] = F.on(_.run) - implicit def writerTIdSemigroup[L:Semigroup, V:Semigroup]: Semigroup[WriterT[Id, L, V]] = - writerTSemigroup[Id, L, V] + implicit def catsDataSemigroupForWriterTId[L:Semigroup, V:Semigroup]: Semigroup[WriterT[Id, L, V]] = + catsDataSemigroupForWriterT[Id, L, V] } private[data] sealed abstract class WriterTInstances1 extends WriterTInstances2 { - implicit def writerTMonadFilter[F[_], L](implicit F: MonadFilter[F], L: Monoid[L]): MonadFilter[WriterT[F, L, ?]] = + implicit def catsDataMonadFilterForWriterT[F[_], L](implicit F: MonadFilter[F], L: Monoid[L]): MonadFilter[WriterT[F, L, ?]] = new WriterTMonadFilter[F, L] { implicit val F0: MonadFilter[F] = F implicit val L0: Monoid[L] = L } - implicit def writerTMonoid[F[_], L, V](implicit W: Monoid[F[(L, V)]]): Monoid[WriterT[F, L, V]] = + implicit def catsDataMonoidForWriterT[F[_], L, V](implicit W: Monoid[F[(L, V)]]): Monoid[WriterT[F, L, V]] = new WriterTMonoid[F, L, V] { implicit val F0: Monoid[F[(L, V)]] = W } - implicit def writerTIdCoflatMap[L]: CoflatMap[WriterT[Id, L, ?]] = - writerTCoflatMap[Id, L] + implicit def catsDataCoflatMapForWriterTId[L]: CoflatMap[WriterT[Id, L, ?]] = + catsDataCoflatMapForWriterT[Id, L] + } private[data] sealed abstract class WriterTInstances2 extends WriterTInstances3 { - implicit def writerTMonadWriter[F[_], L](implicit F: Monad[F], L: Monoid[L]): MonadWriter[WriterT[F, L, ?], L] = + implicit def catsDataMonadWriterForWriterT[F[_], L](implicit F: Monad[F], L: Monoid[L]): MonadWriter[WriterT[F, L, ?], L] = new WriterTMonadWriter[F, L] { implicit val F0: Monad[F] = F implicit val L0: Monoid[L] = L } - implicit def writerTSemigroup[F[_], L, V](implicit W: Semigroup[F[(L, V)]]): Semigroup[WriterT[F, L, V]] = + implicit def catsDataSemigroupForWriterT[F[_], L, V](implicit W: Semigroup[F[(L, V)]]): Semigroup[WriterT[F, L, V]] = new WriterTSemigroup[F, L, V] { implicit val F0: Semigroup[F[(L, V)]] = W } } private[data] sealed abstract class WriterTInstances3 extends WriterTInstances4 { - implicit def writerTAlternative[F[_], L](implicit F: Alternative[F], L: Monoid[L]): Alternative[WriterT[F, L, ?]] = + implicit def catsDataAlternativeForWriterT[F[_], L](implicit F: Alternative[F], L: Monoid[L]): Alternative[WriterT[F, L, ?]] = new WriterTAlternative[F, L] { implicit val F0: Alternative[F] = F implicit val L0: Monoid[L] = L @@ -136,34 +137,33 @@ private[data] sealed abstract class WriterTInstances3 extends WriterTInstances4 } private[data] sealed abstract class WriterTInstances4 extends WriterTInstances5 { - implicit def writerTApplicative[F[_], L](implicit F: Applicative[F], L: Monoid[L]): Applicative[WriterT[F, L, ?]] = + implicit def catsDataApplicativeForWriterT[F[_], L](implicit F: Applicative[F], L: Monoid[L]): Applicative[WriterT[F, L, ?]] = new WriterTApplicative[F, L] { implicit val F0: Applicative[F] = F implicit val L0: Monoid[L] = L } - implicit def writerTMonoidK[F[_], L](implicit F: MonoidK[F]): MonoidK[WriterT[F, L, ?]] = + implicit def catsDataMonoidKForWriterT[F[_], L](implicit F: MonoidK[F]): MonoidK[WriterT[F, L, ?]] = new WriterTMonoidK[F, L] { implicit val F0: MonoidK[F] = F } } private[data] sealed abstract class WriterTInstances5 extends WriterTInstances6 { - implicit def writerTFlatMap[F[_], L](implicit F: FlatMap[F], L: Semigroup[L]): FlatMap[WriterT[F, L, ?]] = + implicit def catsDataFlatMapForWriterT[F[_], L](implicit F: FlatMap[F], L: Semigroup[L]): FlatMap[WriterT[F, L, ?]] = new WriterTFlatMap[F, L] { implicit val F0: FlatMap[F] = F implicit val L0: Semigroup[L] = L } - implicit def writerTSemigroupK[F[_], L](implicit F: SemigroupK[F]): SemigroupK[WriterT[F, L, ?]] = + implicit def catsDataSemigroupKForWriterT[F[_], L](implicit F: SemigroupK[F]): SemigroupK[WriterT[F, L, ?]] = new WriterTSemigroupK[F, L] { implicit val F0: SemigroupK[F] = F } } private[data] sealed abstract class WriterTInstances6 extends WriterTInstances7 { - - implicit def writerTApply[F[_], L](implicit F: Apply[F], L: Semigroup[L]): Apply[WriterT[F, L, ?]] = + implicit def catsDataApplyForWriterT[F[_], L](implicit F: Apply[F], L: Semigroup[L]): Apply[WriterT[F, L, ?]] = new WriterTApply[F, L] { implicit val F0: Apply[F] = F implicit val L0: Semigroup[L] = L @@ -172,10 +172,10 @@ private[data] sealed abstract class WriterTInstances6 extends WriterTInstances7 private[data] sealed abstract class WriterTInstances7 { - implicit def writerTCoflatMap[F[_], L](implicit F: Functor[F]): CoflatMap[WriterT[F, L, ?]] = + implicit def catsDataCoflatMapForWriterT[F[_], L](implicit F: Functor[F]): CoflatMap[WriterT[F, L, ?]] = new WriterTCoflatMap[F, L] { implicit val F0: Functor[F] = F - } + } } private[data] sealed trait WriterTFunctor[F[_], L] extends Functor[WriterT[F, L, ?]] { diff --git a/core/src/main/scala/cats/data/Xor.scala b/core/src/main/scala/cats/data/Xor.scala index 427fd011c1..d8a6a4a2b3 100644 --- a/core/src/main/scala/cats/data/Xor.scala +++ b/core/src/main/scala/cats/data/Xor.scala @@ -186,25 +186,25 @@ object Xor extends XorInstances with XorFunctions { } private[data] sealed abstract class XorInstances extends XorInstances1 { - implicit def xorOrder[A: Order, B: Order]: Order[A Xor B] = + implicit def catsDataOrderForXor[A: Order, B: Order]: Order[A Xor B] = new Order[A Xor B] { def compare(x: A Xor B, y: A Xor B): Int = x compare y override def partialCompare(x: A Xor B, y: A Xor B): Double = x partialCompare y override def eqv(x: A Xor B, y: A Xor B): Boolean = x === y } - implicit def xorShow[A, B](implicit A: Show[A], B: Show[B]): Show[A Xor B] = + implicit def catsDataShowForXor[A, B](implicit A: Show[A], B: Show[B]): Show[A Xor B] = new Show[A Xor B] { def show(f: A Xor B): String = f.show } - implicit def xorMonoid[A, B](implicit B: Monoid[B]): Monoid[A Xor B] = + implicit def catsDataMonoidForXor[A, B](implicit B: Monoid[B]): Monoid[A Xor B] = new Monoid[A Xor B] { def empty: A Xor B = Xor.Right(B.empty) def combine(x: A Xor B, y: A Xor B): A Xor B = x combine y } - implicit def xorSemigroupK[L]: SemigroupK[Xor[L,?]] = + implicit def catsDataSemigroupKForXor[L]: SemigroupK[Xor[L,?]] = new SemigroupK[Xor[L,?]] { def combineK[A](x: Xor[L,A], y: Xor[L,A]): Xor[L,A] = x match { case Xor.Left(_) => y @@ -212,7 +212,7 @@ private[data] sealed abstract class XorInstances extends XorInstances1 { } } - implicit val xorBitraverse: Bitraverse[Xor] = + implicit val catsDataBitraverseForXor: Bitraverse[Xor] = new Bitraverse[Xor] { def bitraverse[G[_], A, B, C, D](fab: Xor[A, B])(f: A => G[C], g: B => G[D])(implicit G: Applicative[G]): G[Xor[C, D]] = fab match { @@ -233,7 +233,7 @@ private[data] sealed abstract class XorInstances extends XorInstances1 { } } - implicit def xorInstances[A]: Traverse[A Xor ?] with MonadError[Xor[A, ?], A] = + implicit def catsDataInstancesForXor[A]: Traverse[A Xor ?] with MonadError[Xor[A, ?], A] = new Traverse[A Xor ?] with MonadError[Xor[A, ?], A] { def traverse[F[_]: Applicative, B, C](fa: A Xor B)(f: B => F[C]): F[A Xor C] = fa.traverse(f) def foldLeft[B, C](fa: A Xor B, c: C)(f: (C, B) => C): C = fa.foldLeft(c)(f) @@ -259,19 +259,19 @@ private[data] sealed abstract class XorInstances extends XorInstances1 { private[data] sealed abstract class XorInstances1 extends XorInstances2 { - implicit def xorSemigroup[A, B](implicit B: Semigroup[B]): Semigroup[A Xor B] = + implicit def catsDataSemigroupForXor[A, B](implicit B: Semigroup[B]): Semigroup[A Xor B] = new Semigroup[A Xor B] { def combine(x: A Xor B, y: A Xor B): A Xor B = x combine y } - implicit def xorPartialOrder[A: PartialOrder, B: PartialOrder]: PartialOrder[A Xor B] = new PartialOrder[A Xor B] { + implicit def catsDataPartialOrderForXor[A: PartialOrder, B: PartialOrder]: PartialOrder[A Xor B] = new PartialOrder[A Xor B] { def partialCompare(x: A Xor B, y: A Xor B): Double = x partialCompare y override def eqv(x: A Xor B, y: A Xor B): Boolean = x === y } } private[data] sealed abstract class XorInstances2 { - implicit def xorEq[A: Eq, B: Eq]: Eq[A Xor B] = + implicit def catsDataEqForXor[A: Eq, B: Eq]: Eq[A Xor B] = new Eq[A Xor B] { def eqv(x: A Xor B, y: A Xor B): Boolean = x === y } diff --git a/core/src/main/scala/cats/data/XorT.scala b/core/src/main/scala/cats/data/XorT.scala index 2fdf95282e..555f9c1b39 100644 --- a/core/src/main/scala/cats/data/XorT.scala +++ b/core/src/main/scala/cats/data/XorT.scala @@ -218,27 +218,27 @@ trait XorTFunctions { private[data] abstract class XorTInstances extends XorTInstances1 { /* TODO violates right absorbtion, right distributivity, and left distributivity -- re-enable when MonadCombine laws are split in to weak/strong - implicit def xorTMonadCombine[F[_], L](implicit F: Monad[F], L: Monoid[L]): MonadCombine[XorT[F, L, ?]] = { + implicit def catsDataMonadCombineForXorT[F[_], L](implicit F: Monad[F], L: Monoid[L]): MonadCombine[XorT[F, L, ?]] = { implicit val F0 = F implicit val L0 = L new XorTMonadCombine[F, L] { implicit val F = F0; implicit val L = L0 } } */ - implicit def xorTOrder[F[_], L, R](implicit F: Order[F[L Xor R]]): Order[XorT[F, L, R]] = + implicit def catsDataOrderForXorT[F[_], L, R](implicit F: Order[F[L Xor R]]): Order[XorT[F, L, R]] = new XorTOrder[F, L, R] { val F0: Order[F[L Xor R]] = F } - implicit def xorTShow[F[_], L, R](implicit sh: Show[F[L Xor R]]): Show[XorT[F, L, R]] = + implicit def catsDataShowForXorT[F[_], L, R](implicit sh: Show[F[L Xor R]]): Show[XorT[F, L, R]] = functor.Contravariant[Show].contramap(sh)(_.value) - implicit def xorTBifunctor[F[_]](implicit F: Functor[F]): Bifunctor[XorT[F, ?, ?]] = + implicit def catsDataBifunctorForXorT[F[_]](implicit F: Functor[F]): Bifunctor[XorT[F, ?, ?]] = new Bifunctor[XorT[F, ?, ?]] { override def bimap[A, B, C, D](fab: XorT[F, A, B])(f: A => C, g: B => D): XorT[F, C, D] = fab.bimap(f, g) } - implicit def xorTTraverse[F[_], L](implicit F: Traverse[F]): Traverse[XorT[F, L, ?]] = + implicit def catsDataTraverseForXorT[F[_], L](implicit F: Traverse[F]): Traverse[XorT[F, L, ?]] = new XorTTraverse[F, L] { val F0: Traverse[F] = F } @@ -255,36 +255,36 @@ private[data] abstract class XorTInstances extends XorTInstances1 { private[data] abstract class XorTInstances1 extends XorTInstances2 { /* TODO violates monadFilter right empty law -- re-enable when MonadFilter laws are split in to weak/strong - implicit def xorTMonadFilter[F[_], L](implicit F: Monad[F], L: Monoid[L]): MonadFilter[XorT[F, L, ?]] = { + implicit def catsDataMonadFilterForXorT[F[_], L](implicit F: Monad[F], L: Monoid[L]): MonadFilter[XorT[F, L, ?]] = { implicit val F0 = F implicit val L0 = L new XorTMonadFilter[F, L] { implicit val F = F0; implicit val L = L0 } } */ - implicit def xorTFoldable[F[_], L](implicit F: Foldable[F]): Foldable[XorT[F, L, ?]] = + implicit def catsDataFoldableForXorT[F[_], L](implicit F: Foldable[F]): Foldable[XorT[F, L, ?]] = new XorTFoldable[F, L] { val F0: Foldable[F] = F } - implicit def xorTPartialOrder[F[_], L, R](implicit F: PartialOrder[F[L Xor R]]): PartialOrder[XorT[F, L, R]] = + implicit def catsDataPartialOrderForXorT[F[_], L, R](implicit F: PartialOrder[F[L Xor R]]): PartialOrder[XorT[F, L, R]] = new XorTPartialOrder[F, L, R] { val F0: PartialOrder[F[L Xor R]] = F } - implicit def xorTBitraverse[F[_]](implicit F: Traverse[F]): Bitraverse[XorT[F, ?, ?]] = + implicit def catsDataBitraverseForXorT[F[_]](implicit F: Traverse[F]): Bitraverse[XorT[F, ?, ?]] = new XorTBitraverse[F] { val F0: Traverse[F] = F } } private[data] abstract class XorTInstances2 extends XorTInstances3 { - implicit def xorTMonadError[F[_], L](implicit F: Monad[F]): MonadError[XorT[F, L, ?], L] = { + implicit def catsDataMonadErrorForXorT[F[_], L](implicit F: Monad[F]): MonadError[XorT[F, L, ?], L] = { implicit val F0 = F new XorTMonadError[F, L] { implicit val F = F0 } } - implicit def xorTSemigroupK[F[_], L](implicit F: Monad[F]): SemigroupK[XorT[F, L, ?]] = + implicit def catsDataSemigroupKForXorT[F[_], L](implicit F: Monad[F]): SemigroupK[XorT[F, L, ?]] = new SemigroupK[XorT[F,L,?]] { def combineK[A](x: XorT[F,L,A], y: XorT[F, L, A]): XorT[F, L, A] = XorT(F.flatMap(x.value) { @@ -293,14 +293,14 @@ private[data] abstract class XorTInstances2 extends XorTInstances3 { }) } - implicit def xorTEq[F[_], L, R](implicit F: Eq[F[L Xor R]]): Eq[XorT[F, L, R]] = + implicit def catsDataEqForXorT[F[_], L, R](implicit F: Eq[F[L Xor R]]): Eq[XorT[F, L, R]] = new XorTEq[F, L, R] { val F0: Eq[F[L Xor R]] = F } } private[data] abstract class XorTInstances3 { - implicit def xorTFunctor[F[_], L](implicit F: Functor[F]): Functor[XorT[F, L, ?]] = { + implicit def catsDataFunctorForXorT[F[_], L](implicit F: Functor[F]): Functor[XorT[F, L, ?]] = { implicit val F0 = F new XorTFunctor[F, L] { implicit val F = F0 } } diff --git a/tests/src/test/scala/cats/tests/CokleisliTests.scala b/tests/src/test/scala/cats/tests/CokleisliTests.scala index 084a23ec52..a158f1aeef 100644 --- a/tests/src/test/scala/cats/tests/CokleisliTests.scala +++ b/tests/src/test/scala/cats/tests/CokleisliTests.scala @@ -57,13 +57,13 @@ class CokleisliTests extends SlowCatsSuite { cokleisliEqE[NonEmptyList, A](oneAndArbitrary, Eq[A]) { - implicit val cokleisliMonoidK = Cokleisli.cokleisliMonoidK[NonEmptyList] + implicit val cokleisliMonoidK = Cokleisli.catsDataMonoidKForCokleisli[NonEmptyList] checkAll("Cokleisli[NonEmptyList, Int, Int]", MonoidKTests[CokleisliNELE].monoidK[Int]) checkAll("MonoidK[Lambda[A => Cokleisli[NonEmptyList, A, A]]]", SerializableTests.serializable(cokleisliMonoidK)) } { - implicit val cokleisliSemigroupK = Cokleisli.cokleisliSemigroupK[NonEmptyList] + implicit val cokleisliSemigroupK = Cokleisli.catsDataSemigroupKForCokleisli[NonEmptyList] checkAll("Cokleisli[NonEmptyList, Int, Int]", SemigroupKTests[CokleisliNELE].semigroupK[Int]) checkAll("SemigroupK[Lambda[A => Cokleisli[NonEmptyList, A, A]]]", SerializableTests.serializable(cokleisliSemigroupK)) } diff --git a/tests/src/test/scala/cats/tests/ConstTests.scala b/tests/src/test/scala/cats/tests/ConstTests.scala index 1b487575ea..fafce196bc 100644 --- a/tests/src/test/scala/cats/tests/ConstTests.scala +++ b/tests/src/test/scala/cats/tests/ConstTests.scala @@ -10,7 +10,7 @@ import cats.laws.discipline.arbitrary.{constArbitrary, oneAndArbitrary} class ConstTests extends CatsSuite { - implicit val iso = CartesianTests.Isomorphisms.invariant[Const[String, ?]](Const.constTraverse) + implicit val iso = CartesianTests.Isomorphisms.invariant[Const[String, ?]](Const.catsDataTraverseForConst) checkAll("Const[String, Int]", CartesianTests[Const[String, ?]].cartesian[Int, Int, Int]) checkAll("Cartesian[Const[String, ?]]", SerializableTests.serializable(Cartesian[Const[String, ?]])) @@ -24,7 +24,7 @@ class ConstTests extends CatsSuite { // Get Apply[Const[C : Semigroup, ?]], not Applicative[Const[C : Monoid, ?]] { implicit def nonEmptyListSemigroup[A]: Semigroup[NonEmptyList[A]] = SemigroupK[NonEmptyList].algebra - implicit val iso = CartesianTests.Isomorphisms.invariant[Const[NonEmptyList[String], ?]](Const.constContravariant) + implicit val iso = CartesianTests.Isomorphisms.invariant[Const[NonEmptyList[String], ?]](Const.catsDataContravariantForConst) checkAll("Apply[Const[NonEmptyList[String], Int]]", ApplyTests[Const[NonEmptyList[String], ?]].apply[Int, Int, Int]) checkAll("Apply[Const[NonEmptyList[String], ?]]", SerializableTests.serializable(Apply[Const[NonEmptyList[String], ?]])) } diff --git a/tests/src/test/scala/cats/tests/CoproductTests.scala b/tests/src/test/scala/cats/tests/CoproductTests.scala index 6c0279efd2..ff6a40e324 100644 --- a/tests/src/test/scala/cats/tests/CoproductTests.scala +++ b/tests/src/test/scala/cats/tests/CoproductTests.scala @@ -14,7 +14,7 @@ class CoproductTests extends CatsSuite { checkAll("Traverse[Coproduct[Option, Option, ?]]", SerializableTests.serializable(Traverse[Coproduct[Option, Option, ?]])) { - implicit val foldable = Coproduct.coproductFoldable[Option, Option] + implicit val foldable = Coproduct.catsDataFoldableForCoproduct[Option, Option] checkAll("Coproduct[Option, Option, ?]", FoldableTests[Coproduct[Option, Option, ?]].foldable[Int, Int]) checkAll("Foldable[Coproduct[Option, Option, ?]]", SerializableTests.serializable(Foldable[Coproduct[Option, Option, ?]])) } @@ -23,7 +23,7 @@ class CoproductTests extends CatsSuite { checkAll("Comonad[Coproduct[Eval, Eval, ?]]", SerializableTests.serializable(Comonad[Coproduct[Eval, Eval, ?]])) { - implicit val coflatMap = Coproduct.coproductCoflatMap[Eval, Eval] + implicit val coflatMap = Coproduct.catsDataCoflatMapForCoproduct[Eval, Eval] checkAll("Coproduct[Eval, Eval, ?]", CoflatMapTests[Coproduct[Eval, Eval, ?]].coflatMap[Int, Int, Int]) checkAll("CoflatMap[Coproduct[Eval, Eval, ?]]", SerializableTests.serializable(CoflatMap[Coproduct[Eval, Eval, ?]])) } diff --git a/tests/src/test/scala/cats/tests/FuncTests.scala b/tests/src/test/scala/cats/tests/FuncTests.scala index 0a2083bf7c..fe1216e03a 100644 --- a/tests/src/test/scala/cats/tests/FuncTests.scala +++ b/tests/src/test/scala/cats/tests/FuncTests.scala @@ -20,19 +20,19 @@ class FuncTests extends CatsSuite { checkAll("Cartesian[Func[Option, Int, ?]]", SerializableTests.serializable(Cartesian[Func[Option, Int, ?]])) { - implicit val funcApp = Func.funcApplicative[Option, Int] + implicit val catsDataApplicativeForFunc = Func.catsDataApplicativeForFunc[Option, Int] checkAll("Func[Option, Int, Int]", ApplicativeTests[Func[Option, Int, ?]].applicative[Int, Int, Int]) checkAll("Applicative[Func[Option, Int, ?]]", SerializableTests.serializable(Applicative[Func[Option, Int, ?]])) } { - implicit val funcApply = Func.funcApply[Option, Int] + implicit val catsDataApplyForFunc = Func.catsDataApplyForFunc[Option, Int] checkAll("Func[Option, Int, Int]", ApplyTests[Func[Option, Int, ?]].apply[Int, Int, Int]) checkAll("Apply[Func[Option, Int, ?]]", SerializableTests.serializable(Apply[Func[Option, Int, ?]])) } { - implicit val funcFunctor = Func.funcFunctor[Option, Int] + implicit val catsDataFunctorForFunc = Func.catsDataFunctorForFunc[Option, Int] checkAll("Func[Option, Int, Int]", FunctorTests[Func[Option, Int, ?]].functor[Int, Int, Int]) checkAll("Functor[Func[Option, Int, ?]]", SerializableTests.serializable(Functor[Func[Option, Int, ?]])) } diff --git a/tests/src/test/scala/cats/tests/KleisliTests.scala b/tests/src/test/scala/cats/tests/KleisliTests.scala index a081346975..bcfd7f1ba5 100644 --- a/tests/src/test/scala/cats/tests/KleisliTests.scala +++ b/tests/src/test/scala/cats/tests/KleisliTests.scala @@ -15,7 +15,7 @@ class KleisliTests extends CatsSuite { implicit def kleisliEq[F[_], A, B](implicit A: Arbitrary[A], FB: Eq[F[B]]): Eq[Kleisli[F, A, B]] = Eq.by[Kleisli[F, A, B], A => F[B]](_.run) - implicit val xorTEq = XorT.xorTEq[Kleisli[Option, Int, ?], Unit, Int] + implicit val xorTEq = XorT.catsDataEqForXorT[Kleisli[Option, Int, ?], Unit, Int] implicit val iso = CartesianTests.Isomorphisms.invariant[Kleisli[Option, Int, ?]] @@ -26,81 +26,81 @@ class KleisliTests extends CatsSuite { checkAll("Cartesian[Kleisli[Option, Int, ?]]", SerializableTests.serializable(Cartesian[Kleisli[Option, Int, ?]])) { - implicit val kleisliArrow = Kleisli.kleisliArrow[Option] + implicit val catsDataArrowForKleisli = Kleisli.catsDataArrowForKleisli[Option] checkAll("Kleisli[Option, Int, Int]", ArrowTests[Kleisli[Option, ?, ?]].arrow[Int, Int, Int, Int, Int, Int]) checkAll("Arrow[Kleisli[Option, ?, ?]]", SerializableTests.serializable(Arrow[Kleisli[Option, ?, ?]])) } { - implicit val kleisliChoice = Kleisli.kleisliChoice[Option] + implicit val catsDataChoiceForKleisli = Kleisli.catsDataChoiceForKleisli[Option] checkAll("Kleisli[Option, Int, Int]", ChoiceTests[Kleisli[Option, ?, ?]].choice[Int, Int, Int, Int]) checkAll("Choice[Kleisli[Option, ?, ?]]", SerializableTests.serializable(Choice[Kleisli[Option, ?, ?]])) } { - implicit val kleisliMonadReader = Kleisli.kleisliMonadReader[Option, Int] + implicit val catsDataMonadReaderForKleisli = Kleisli.catsDataMonadReaderForKleisli[Option, Int] checkAll("Kleisli[Option, Int, Int]", MonadReaderTests[Kleisli[Option, Int, ?], Int].monadReader[Int, Int, Int]) checkAll("MonadReader[Kleisli[Option, ?, ?], Int]", SerializableTests.serializable(MonadReader[Kleisli[Option, Int, ?], Int])) } { - implicit val kleisliSplit = Kleisli.kleisliSplit[Option] + implicit val kleisliSplit = Kleisli.catsDataSplitForKleisli[Option] checkAll("Kleisli[Option, Int, Int]", SplitTests[Kleisli[Option, ?, ?]].split[Int, Int, Int, Int, Int, Int]) checkAll("Split[Kleisli[Option, Int, ?]]", SerializableTests.serializable(Split[Kleisli[Option, ?, ?]])) } { - implicit val kleisliStrong = Kleisli.kleisliStrong[Option] + implicit val catsDataStrongForKleisli = Kleisli.catsDataStrongForKleisli[Option] checkAll("Kleisli[Option, Int, Int]", StrongTests[Kleisli[Option, ?, ?]].strong[Int, Int, Int, Int, Int, Int]) checkAll("Strong[Kleisli[Option, ?, ?]]", SerializableTests.serializable(Strong[Kleisli[Option, ?, ?]])) } { - implicit val kleisliFlatMap = Kleisli.kleisliFlatMap[Option, Int] + implicit val catsDataFlatMapForKleisli = Kleisli.catsDataFlatMapForKleisli[Option, Int] checkAll("Kleisli[Option, Int, Int]", FlatMapTests[Kleisli[Option, Int, ?]].flatMap[Int, Int, Int]) checkAll("FlatMap[Kleisli[Option, Int, ?]]", SerializableTests.serializable(FlatMap[Kleisli[Option, Int, ?]])) } { - implicit val kleisliApplicative = Kleisli.kleisliApplicative[Option, Int] + implicit val catsDataApplicativeForKleisli = Kleisli.catsDataApplicativeForKleisli[Option, Int] checkAll("Kleisli[Option, Int, Int]", ApplicativeTests[Kleisli[Option, Int, ?]].applicative[Int, Int, Int]) checkAll("Applicative[Kleisli[Option, Int, ?]]", SerializableTests.serializable(Applicative[Kleisli[Option, Int, ?]])) } { - implicit val kleisliApply = Kleisli.kleisliApply[Option, Int] + implicit val catsDataApplyForKleisli = Kleisli.catsDataApplyForKleisli[Option, Int] checkAll("Kleisli[Option, Int, Int]", ApplyTests[Kleisli[Option, Int, ?]].apply[Int, Int, Int]) checkAll("Apply[Kleisli[Option, Int, ?]]", SerializableTests.serializable(Apply[Kleisli[Option, Int, ?]])) } { - implicit val kleisliFunctor = Kleisli.kleisliFunctor[Option, Int] + implicit val catsDataFunctorForKleisli = Kleisli.catsDataFunctorForKleisli[Option, Int] checkAll("Kleisli[Option, Int, Int]", FunctorTests[Kleisli[Option, Int, ?]].functor[Int, Int, Int]) checkAll("Functor[Kleisli[Option, Int, ?]]", SerializableTests.serializable(Functor[Kleisli[Option, Int, ?]])) } { - implicit val kleisliMonoid = Kleisli.kleisliMonoid[Option, Int, String] + implicit val catsDataMonoidForKleisli = Kleisli.catsDataMonoidForKleisli[Option, Int, String] checkAll("Kleisli[Option, Int, String]", GroupLaws[Kleisli[Option, Int, String]].monoid) - checkAll("Monoid[Kleisli[Option, Int, String]]", SerializableTests.serializable(kleisliMonoid)) + checkAll("Monoid[Kleisli[Option, Int, String]]", SerializableTests.serializable(catsDataMonoidForKleisli)) } { - implicit val kleisliSemigroup = Kleisli.kleisliSemigroup[Option, Int, String] + implicit val catsDataSemigroupForKleisli = Kleisli.catsDataSemigroupForKleisli[Option, Int, String] checkAll("Kleisli[Option, Int, String]", GroupLaws[Kleisli[Option, Int, String]].semigroup) - checkAll("Semigroup[Kleisli[Option, Int, String]]", SerializableTests.serializable(kleisliSemigroup)) + checkAll("Semigroup[Kleisli[Option, Int, String]]", SerializableTests.serializable(catsDataSemigroupForKleisli)) } { - implicit val kleisliMonoidK = Kleisli.kleisliMonoidK[Option] + implicit val catsDataMonoidKForKleisli = Kleisli.catsDataMonoidKForKleisli[Option] checkAll("Kleisli[Option, Int, Int]", MonoidKTests[Lambda[A => Kleisli[Option, A, A]]].monoidK[Int]) - checkAll("MonoidK[Lambda[A => Kleisli[Option, A, A]]]", SerializableTests.serializable(kleisliMonoidK)) + checkAll("MonoidK[Lambda[A => Kleisli[Option, A, A]]]", SerializableTests.serializable(catsDataMonoidKForKleisli)) } { - implicit val kleisliSemigroupK = Kleisli.kleisliSemigroupK[Option] + implicit val catsDataSemigroupKForKleisli = Kleisli.catsDataSemigroupKForKleisli[Option] checkAll("Kleisli[Option, Int, Int]", SemigroupKTests[Lambda[A => Kleisli[Option, A, A]]].semigroupK[Int]) - checkAll("SemigroupK[Lambda[A => Kleisli[Option, A, A]]]", SerializableTests.serializable(kleisliSemigroupK)) + checkAll("SemigroupK[Lambda[A => Kleisli[Option, A, A]]]", SerializableTests.serializable(catsDataSemigroupKForKleisli)) } checkAll("Kleisli[Option, ?, Int]", ContravariantTests[Kleisli[Option, ?, Int]].contravariant[Int, Int, Int]) diff --git a/tests/src/test/scala/cats/tests/OneAndTests.scala b/tests/src/test/scala/cats/tests/OneAndTests.scala index 453df0283f..569535205f 100644 --- a/tests/src/test/scala/cats/tests/OneAndTests.scala +++ b/tests/src/test/scala/cats/tests/OneAndTests.scala @@ -20,7 +20,7 @@ class OneAndTests extends CatsSuite { checkAll("OneAnd[List, Int]", ReducibleTests[OneAnd[List, ?]].reducible[Option, Int, Int]) checkAll("Reducible[OneAnd[List, ?]]", SerializableTests.serializable(Reducible[OneAnd[List, ?]])) - implicit val iso = CartesianTests.Isomorphisms.invariant[OneAnd[ListWrapper, ?]](OneAnd.oneAndFunctor(ListWrapper.functor)) + implicit val iso = CartesianTests.Isomorphisms.invariant[OneAnd[ListWrapper, ?]](OneAnd.catsDataFunctorForOneAnd(ListWrapper.functor)) // Test instances that have more general constraints { diff --git a/tests/src/test/scala/cats/tests/ValidatedTests.scala b/tests/src/test/scala/cats/tests/ValidatedTests.scala index ece8418ed6..22cc72fb6f 100644 --- a/tests/src/test/scala/cats/tests/ValidatedTests.scala +++ b/tests/src/test/scala/cats/tests/ValidatedTests.scala @@ -19,7 +19,7 @@ class ValidatedTests extends CatsSuite { checkAll("Validated[?, ?]", BitraverseTests[Validated].bitraverse[Option, Int, Int, Int, String, String, String]) checkAll("Bitraverse[Validated]", SerializableTests.serializable(Bitraverse[Validated])) - implicit val eq0 = XorT.xorTEq[Validated[String, ?], String, Int] + implicit val eq0 = XorT.catsDataEqForXorT[Validated[String, ?], String, Int] checkAll("Validated[String, Int]", ApplicativeErrorTests[Validated[String, ?], String].applicativeError[Int, Int, Int]) checkAll("ApplicativeError[Xor, String]", SerializableTests.serializable(ApplicativeError[Validated[String, ?], String])) diff --git a/tests/src/test/scala/cats/tests/WriterTTests.scala b/tests/src/test/scala/cats/tests/WriterTTests.scala index 55bff93d00..e567248e73 100644 --- a/tests/src/test/scala/cats/tests/WriterTTests.scala +++ b/tests/src/test/scala/cats/tests/WriterTTests.scala @@ -101,7 +101,7 @@ class WriterTTests extends CatsSuite { checkAll("Bifunctor[WriterT[ListWrapper, ?, ?]]", SerializableTests.serializable(Bifunctor[WriterT[ListWrapper, ?, ?]])) } - implicit val iso = CartesianTests.Isomorphisms.invariant[WriterT[ListWrapper, ListWrapper[Int], ?]](WriterT.writerTCoflatMap(ListWrapper.functor)) + implicit val iso = CartesianTests.Isomorphisms.invariant[WriterT[ListWrapper, ListWrapper[Int], ?]](WriterT.catsDataCoflatMapForWriterT(ListWrapper.functor)) // We have varying instances available depending on `F` and `L`. // We also battle some inference issues with `Id`. diff --git a/tests/src/test/scala/cats/tests/XorTTests.scala b/tests/src/test/scala/cats/tests/XorTTests.scala index 13c279a76b..b88e4c2958 100644 --- a/tests/src/test/scala/cats/tests/XorTTests.scala +++ b/tests/src/test/scala/cats/tests/XorTTests.scala @@ -8,8 +8,8 @@ import cats.laws.discipline.arbitrary._ import cats.kernel.laws.OrderLaws class XorTTests extends CatsSuite { - implicit val eq0 = XorT.xorTEq[List, String, String Xor Int] - implicit val eq1 = XorT.xorTEq[XorT[List, String, ?], String, Int](eq0) + implicit val eq0 = XorT.catsDataEqForXorT[List, String, String Xor Int] + implicit val eq1 = XorT.catsDataEqForXorT[XorT[List, String, ?], String, Int](eq0) implicit val iso = CartesianTests.Isomorphisms.invariant[XorT[List, String, ?]] checkAll("XorT[List, String, Int]", MonadErrorTests[XorT[List, String, ?], String].monadError[Int, Int, Int]) checkAll("MonadError[XorT[List, ?, ?]]", SerializableTests.serializable(MonadError[XorT[List, String, ?], String])) diff --git a/tests/src/test/scala/cats/tests/XorTests.scala b/tests/src/test/scala/cats/tests/XorTests.scala index ed123b545d..6afa7308e0 100644 --- a/tests/src/test/scala/cats/tests/XorTests.scala +++ b/tests/src/test/scala/cats/tests/XorTests.scala @@ -22,7 +22,7 @@ class XorTests extends CatsSuite { checkAll("Xor[String, NonEmptyList[Int]]", GroupLaws[Xor[String, NonEmptyList[Int]]].semigroup) - implicit val eq0 = XorT.xorTEq[Xor[String, ?], String, Int] + implicit val eq0 = XorT.catsDataEqForXorT[Xor[String, ?], String, Int] checkAll("Xor[String, Int]", MonadErrorTests[Xor[String, ?], String].monadError[Int, Int, Int]) checkAll("MonadError[Xor, String]", SerializableTests.serializable(MonadError[Xor[String, ?], String])) From 9459d6246a78a127dacaeeabd755655c82f60e9e Mon Sep 17 00:00:00 2001 From: Kailuo Wang Date: Fri, 27 May 2016 15:17:21 -0400 Subject: [PATCH 33/40] renamed implicit val defs in kernel --- .../src/main/scala/cats/kernel/std/bigInt.scala | 4 ++-- .../src/main/scala/cats/kernel/std/boolean.scala | 2 +- kernel/src/main/scala/cats/kernel/std/byte.scala | 4 ++-- kernel/src/main/scala/cats/kernel/std/char.scala | 2 +- .../src/main/scala/cats/kernel/std/double.scala | 4 ++-- .../src/main/scala/cats/kernel/std/float.scala | 4 ++-- kernel/src/main/scala/cats/kernel/std/int.scala | 4 ++-- kernel/src/main/scala/cats/kernel/std/list.scala | 8 ++++---- kernel/src/main/scala/cats/kernel/std/long.scala | 4 ++-- kernel/src/main/scala/cats/kernel/std/map.scala | 4 ++-- .../src/main/scala/cats/kernel/std/option.scala | 8 ++++---- kernel/src/main/scala/cats/kernel/std/set.scala | 4 ++-- .../src/main/scala/cats/kernel/std/short.scala | 4 ++-- .../src/main/scala/cats/kernel/std/stream.scala | 8 ++++---- .../src/main/scala/cats/kernel/std/string.scala | 4 ++-- kernel/src/main/scala/cats/kernel/std/unit.scala | 4 ++-- .../src/main/scala/cats/kernel/std/vector.scala | 8 ++++---- project/KernelBoiler.scala | 16 ++++++++-------- 18 files changed, 48 insertions(+), 48 deletions(-) diff --git a/kernel/src/main/scala/cats/kernel/std/bigInt.scala b/kernel/src/main/scala/cats/kernel/std/bigInt.scala index 36094a3512..a03b1c2ad1 100644 --- a/kernel/src/main/scala/cats/kernel/std/bigInt.scala +++ b/kernel/src/main/scala/cats/kernel/std/bigInt.scala @@ -4,9 +4,9 @@ package std package object bigInt extends BigIntInstances trait BigIntInstances { - implicit val bigIntOrder: Order[BigInt] = + implicit val catsKernelStdOrderForBigInt: Order[BigInt] = new BigIntOrder - implicit val bigIntGroup: CommutativeGroup[BigInt] = + implicit val catsKernelStdGroupForBigInt: CommutativeGroup[BigInt] = new BigIntGroup } diff --git a/kernel/src/main/scala/cats/kernel/std/boolean.scala b/kernel/src/main/scala/cats/kernel/std/boolean.scala index 6d3214efc5..379021a27d 100644 --- a/kernel/src/main/scala/cats/kernel/std/boolean.scala +++ b/kernel/src/main/scala/cats/kernel/std/boolean.scala @@ -4,7 +4,7 @@ package std package object boolean extends BooleanInstances trait BooleanInstances { - implicit val booleanOrder: Order[Boolean] = + implicit val catsKernelStdOrderForBoolean: Order[Boolean] = new BooleanOrder } diff --git a/kernel/src/main/scala/cats/kernel/std/byte.scala b/kernel/src/main/scala/cats/kernel/std/byte.scala index d635597c1f..69f444a2d6 100644 --- a/kernel/src/main/scala/cats/kernel/std/byte.scala +++ b/kernel/src/main/scala/cats/kernel/std/byte.scala @@ -4,8 +4,8 @@ package std package object byte extends ByteInstances trait ByteInstances { - implicit val byteOrder: Order[Byte] = new ByteOrder - implicit val byteGroup: CommutativeGroup[Byte] = new ByteGroup + implicit val catsKernelStdOrderForByte: Order[Byte] = new ByteOrder + implicit val catsKernelStdGroupForByte: CommutativeGroup[Byte] = new ByteGroup } class ByteGroup extends CommutativeGroup[Byte] { diff --git a/kernel/src/main/scala/cats/kernel/std/char.scala b/kernel/src/main/scala/cats/kernel/std/char.scala index 7a863a8cab..64946a5107 100644 --- a/kernel/src/main/scala/cats/kernel/std/char.scala +++ b/kernel/src/main/scala/cats/kernel/std/char.scala @@ -4,7 +4,7 @@ package std package object char extends CharInstances trait CharInstances { - implicit val charOrder = new CharOrder + implicit val catsKernelStdOrderForChar = new CharOrder } class CharOrder extends Order[Char] { diff --git a/kernel/src/main/scala/cats/kernel/std/double.scala b/kernel/src/main/scala/cats/kernel/std/double.scala index 215fa96564..b656b220e5 100644 --- a/kernel/src/main/scala/cats/kernel/std/double.scala +++ b/kernel/src/main/scala/cats/kernel/std/double.scala @@ -4,8 +4,8 @@ package std import java.lang.Math trait DoubleInstances { - implicit val doubleOrder: Order[Double] = new DoubleOrder - implicit val doubleGroup: CommutativeGroup[Double] = new DoubleGroup + implicit val catsKernelStdOrderForDouble: Order[Double] = new DoubleOrder + implicit val catsKernelStdGroupForDouble: CommutativeGroup[Double] = new DoubleGroup } class DoubleGroup extends CommutativeGroup[Double] { diff --git a/kernel/src/main/scala/cats/kernel/std/float.scala b/kernel/src/main/scala/cats/kernel/std/float.scala index 81c72ed5d5..c41f7978bf 100644 --- a/kernel/src/main/scala/cats/kernel/std/float.scala +++ b/kernel/src/main/scala/cats/kernel/std/float.scala @@ -2,8 +2,8 @@ package cats.kernel package std trait FloatInstances { - implicit val floatOrder: Order[Float] = new FloatOrder - implicit val floatGroup: CommutativeGroup[Float] = new FloatGroup + implicit val catsKernelStdOrderForFloat: Order[Float] = new FloatOrder + implicit val catsKernelStdGroupForFloat: CommutativeGroup[Float] = new FloatGroup } /** diff --git a/kernel/src/main/scala/cats/kernel/std/int.scala b/kernel/src/main/scala/cats/kernel/std/int.scala index 7224bb059e..048805133d 100644 --- a/kernel/src/main/scala/cats/kernel/std/int.scala +++ b/kernel/src/main/scala/cats/kernel/std/int.scala @@ -4,8 +4,8 @@ package std package object int extends IntInstances trait IntInstances { - implicit val intOrder: Order[Int] = new IntOrder - implicit val intGroup: CommutativeGroup[Int] = new IntGroup + implicit val catsKernelStdOrderForInt: Order[Int] = new IntOrder + implicit val catsKernelStdGroupForInt: CommutativeGroup[Int] = new IntGroup } class IntGroup extends CommutativeGroup[Int] { diff --git a/kernel/src/main/scala/cats/kernel/std/list.scala b/kernel/src/main/scala/cats/kernel/std/list.scala index 056e4f36f2..6de5e369cf 100644 --- a/kernel/src/main/scala/cats/kernel/std/list.scala +++ b/kernel/src/main/scala/cats/kernel/std/list.scala @@ -7,19 +7,19 @@ import scala.collection.mutable package object list extends ListInstances trait ListInstances extends ListInstances1 { - implicit def listOrder[A: Order]: Order[List[A]] = + implicit def catsKernelStdOrderForList[A: Order]: Order[List[A]] = new ListOrder[A] - implicit def listMonoid[A]: Monoid[List[A]] = + implicit def catsKernelStdMonoidForList[A]: Monoid[List[A]] = new ListMonoid[A] } trait ListInstances1 extends ListInstances2 { - implicit def listPartialOrder[A: PartialOrder]: PartialOrder[List[A]] = + implicit def catsKernelStdPartialOrderForList[A: PartialOrder]: PartialOrder[List[A]] = new ListPartialOrder[A] } trait ListInstances2 { - implicit def listEq[A: Eq]: Eq[List[A]] = + implicit def catsKernelStdEqForList[A: Eq]: Eq[List[A]] = new ListEq[A] } diff --git a/kernel/src/main/scala/cats/kernel/std/long.scala b/kernel/src/main/scala/cats/kernel/std/long.scala index 21552b6a6f..dbfec69ff1 100644 --- a/kernel/src/main/scala/cats/kernel/std/long.scala +++ b/kernel/src/main/scala/cats/kernel/std/long.scala @@ -4,8 +4,8 @@ package std package object long extends LongInstances trait LongInstances { - implicit val longOrder: Order[Long] = new LongOrder - implicit val longGroup: CommutativeGroup[Long] = new LongGroup + implicit val catsKernelStdOrderForLong: Order[Long] = new LongOrder + implicit val catsKernelStdGroupForLong: CommutativeGroup[Long] = new LongGroup } class LongGroup extends CommutativeGroup[Long] { diff --git a/kernel/src/main/scala/cats/kernel/std/map.scala b/kernel/src/main/scala/cats/kernel/std/map.scala index 3743be1518..ad4411fed8 100644 --- a/kernel/src/main/scala/cats/kernel/std/map.scala +++ b/kernel/src/main/scala/cats/kernel/std/map.scala @@ -6,9 +6,9 @@ import cats.kernel.std.util.StaticMethods.addMap package object map extends MapInstances trait MapInstances { - implicit def mapEq[K, V: Eq]: Eq[Map[K, V]] = + implicit def catsKernelStdEqForMap[K, V: Eq]: Eq[Map[K, V]] = new MapEq[K, V] - implicit def mapMonoid[K, V: Semigroup]: Monoid[Map[K, V]] = + implicit def catsKernelStdMonoidForMap[K, V: Semigroup]: Monoid[Map[K, V]] = new MapMonoid[K, V] } diff --git a/kernel/src/main/scala/cats/kernel/std/option.scala b/kernel/src/main/scala/cats/kernel/std/option.scala index 4a6fcf36d0..f42a96ec8d 100644 --- a/kernel/src/main/scala/cats/kernel/std/option.scala +++ b/kernel/src/main/scala/cats/kernel/std/option.scala @@ -4,19 +4,19 @@ package std package object option extends OptionInstances trait OptionInstances extends OptionInstances1 { - implicit def optionOrder[A: Order]: Order[Option[A]] = + implicit def catsKernelStdOrderForOptioin[A: Order]: Order[Option[A]] = new OptionOrder[A] - implicit def optionMonoid[A: Semigroup]: Monoid[Option[A]] = + implicit def catsKernelStdMonoidForOptioin[A: Semigroup]: Monoid[Option[A]] = new OptionMonoid[A] } trait OptionInstances1 extends OptionInstances0 { - implicit def optionPartialOrder[A: PartialOrder]: PartialOrder[Option[A]] = + implicit def catsKernelStdPartialOrderForOptioin[A: PartialOrder]: PartialOrder[Option[A]] = new OptionPartialOrder[A] } trait OptionInstances0 { - implicit def optionEq[A: Eq]: Eq[Option[A]] = + implicit def catsKernelStdEqForOptioin[A: Eq]: Eq[Option[A]] = new OptionEq[A] } diff --git a/kernel/src/main/scala/cats/kernel/std/set.scala b/kernel/src/main/scala/cats/kernel/std/set.scala index ae84e1d09d..c7012ccf0d 100644 --- a/kernel/src/main/scala/cats/kernel/std/set.scala +++ b/kernel/src/main/scala/cats/kernel/std/set.scala @@ -4,10 +4,10 @@ package std package object set extends SetInstances trait SetInstances { - implicit def setPartialOrder[A]: PartialOrder[Set[A]] = + implicit def catsKernelStdPartialOrderForSet[A]: PartialOrder[Set[A]] = new SetPartialOrder[A] - implicit def setSemilattice[A]: BoundedSemilattice[Set[A]] = + implicit def catsKernelStdSemilatticeForSet[A]: BoundedSemilattice[Set[A]] = new SetSemilattice[A] } diff --git a/kernel/src/main/scala/cats/kernel/std/short.scala b/kernel/src/main/scala/cats/kernel/std/short.scala index 531dfae07d..50cd1fe145 100644 --- a/kernel/src/main/scala/cats/kernel/std/short.scala +++ b/kernel/src/main/scala/cats/kernel/std/short.scala @@ -4,8 +4,8 @@ package std package object short extends ShortInstances trait ShortInstances { - implicit val shortOrder: Order[Short] = new ShortOrder - implicit val shortGroup: CommutativeGroup[Short] = new ShortGroup + implicit val catsKernelStdOrderForShort: Order[Short] = new ShortOrder + implicit val catsKernelStdGroupForShort: CommutativeGroup[Short] = new ShortGroup } class ShortGroup extends CommutativeGroup[Short] { diff --git a/kernel/src/main/scala/cats/kernel/std/stream.scala b/kernel/src/main/scala/cats/kernel/std/stream.scala index edea35a471..05fba59126 100644 --- a/kernel/src/main/scala/cats/kernel/std/stream.scala +++ b/kernel/src/main/scala/cats/kernel/std/stream.scala @@ -6,19 +6,19 @@ import cats.kernel.std.util.StaticMethods package object stream extends StreamInstances trait StreamInstances extends StreamInstances1 { - implicit def streamOrder[A: Order]: Order[Stream[A]] = + implicit def catsKernelStdOrderForStream[A: Order]: Order[Stream[A]] = new StreamOrder[A] - implicit def streamMonoid[A]: Monoid[Stream[A]] = + implicit def catsKernelStdMonoidForStream[A]: Monoid[Stream[A]] = new StreamMonoid[A] } trait StreamInstances1 extends StreamInstances2 { - implicit def streamPartialOrder[A: PartialOrder]: PartialOrder[Stream[A]] = + implicit def catsKernelStdPartialOrderForStream[A: PartialOrder]: PartialOrder[Stream[A]] = new StreamPartialOrder[A] } trait StreamInstances2 { - implicit def streamEq[A: Eq]: Eq[Stream[A]] = + implicit def catsKernelStdEqForStream[A: Eq]: Eq[Stream[A]] = new StreamEq[A] } diff --git a/kernel/src/main/scala/cats/kernel/std/string.scala b/kernel/src/main/scala/cats/kernel/std/string.scala index 6e46989761..3caad03c93 100644 --- a/kernel/src/main/scala/cats/kernel/std/string.scala +++ b/kernel/src/main/scala/cats/kernel/std/string.scala @@ -4,8 +4,8 @@ package std package object string extends StringInstances trait StringInstances { - implicit val stringOrder: Order[String] = new StringOrder - implicit val stringMonoid: Monoid[String] = new StringMonoid + implicit val catsKernelStdOrderForString: Order[String] = new StringOrder + implicit val catsKernelStdMonoidForString: Monoid[String] = new StringMonoid } class StringOrder extends Order[String] { diff --git a/kernel/src/main/scala/cats/kernel/std/unit.scala b/kernel/src/main/scala/cats/kernel/std/unit.scala index fd0b8b8b1a..bc71510f38 100644 --- a/kernel/src/main/scala/cats/kernel/std/unit.scala +++ b/kernel/src/main/scala/cats/kernel/std/unit.scala @@ -4,10 +4,10 @@ package std package object unit extends UnitInstances trait UnitInstances { - implicit val unitOrder: Order[Unit] = + implicit val catsKernelStdOrderForUnit: Order[Unit] = new UnitOrder - implicit val unitAlgebra: BoundedSemilattice[Unit] with CommutativeGroup[Unit] = + implicit val catsKernelStdAlgebraForUnit: BoundedSemilattice[Unit] with CommutativeGroup[Unit] = new UnitAlgebra } diff --git a/kernel/src/main/scala/cats/kernel/std/vector.scala b/kernel/src/main/scala/cats/kernel/std/vector.scala index 77ed2ae954..f559ffe7ea 100644 --- a/kernel/src/main/scala/cats/kernel/std/vector.scala +++ b/kernel/src/main/scala/cats/kernel/std/vector.scala @@ -6,19 +6,19 @@ import cats.kernel.std.util.StaticMethods package object vector extends VectorInstances trait VectorInstances extends VectorInstances1 { - implicit def vectorOrder[A: Order]: Order[Vector[A]] = + implicit def catsKernelStdOrderForVector[A: Order]: Order[Vector[A]] = new VectorOrder[A] - implicit def vectorMonoid[A]: Monoid[Vector[A]] = + implicit def catsKernelStdMonoidForVector[A]: Monoid[Vector[A]] = new VectorMonoid[A] } trait VectorInstances1 extends VectorInstances2 { - implicit def vectorPartialOrder[A: PartialOrder]: PartialOrder[Vector[A]] = + implicit def catsKernelStdPartialOrderForVector[A: PartialOrder]: PartialOrder[Vector[A]] = new VectorPartialOrder[A] } trait VectorInstances2 { - implicit def vectorEq[A: Eq]: Eq[Vector[A]] = + implicit def catsKernelStdEqForVector[A: Eq]: Eq[Vector[A]] = new VectorEq[A] } diff --git a/project/KernelBoiler.scala b/project/KernelBoiler.scala index 69a46537fe..e86048d115 100644 --- a/project/KernelBoiler.scala +++ b/project/KernelBoiler.scala @@ -121,47 +121,47 @@ object KernelBoiler { |package std | |trait TupleInstances { - - implicit def tuple${arity}Band[${`A..N`}](implicit ${constraints("Band")}): Band[${`(A..N)`}] = + - implicit def catsKernelStdBandForTuple${arity}[${`A..N`}](implicit ${constraints("Band")}): Band[${`(A..N)`}] = - new Band[${`(A..N)`}] { - def combine(x: ${`(A..N)`}, y: ${`(A..N)`}): ${`(A..N)`} = ${binTuple("combine")} - } - - - implicit def tuple${arity}Group[${`A..N`}](implicit ${constraints("Group")}): Group[${`(A..N)`}] = + - implicit def catsKernelStdGroupForTuple${arity}[${`A..N`}](implicit ${constraints("Group")}): Group[${`(A..N)`}] = - new Group[${`(A..N)`}] { - def combine(x: ${`(A..N)`}, y: ${`(A..N)`}): ${`(A..N)`} = ${binTuple("combine")} - def empty: ${`(A..N)`} = ${nullaryTuple("empty")} - def inverse(x: ${`(A..N)`}): ${`(A..N)`} = ${unaryTuple("inverse")} - } - - - implicit def tuple${arity}Eq[${`A..N`}](implicit ${constraints("Eq")}): Eq[${`(A..N)`}] = + - implicit def catsKernelStdEqForTuple${arity}[${`A..N`}](implicit ${constraints("Eq")}): Eq[${`(A..N)`}] = - new Eq[${`(A..N)`}] { - def eqv(x: ${`(A..N)`}, y: ${`(A..N)`}): Boolean = ${binMethod("eqv").mkString(" && ")} - } - - - implicit def tuple${arity}Monoid[${`A..N`}](implicit ${constraints("Monoid")}): Monoid[${`(A..N)`}] = + - implicit def catsKernelStdMonoidForTuple${arity}[${`A..N`}](implicit ${constraints("Monoid")}): Monoid[${`(A..N)`}] = - new Monoid[${`(A..N)`}] { - def combine(x: ${`(A..N)`}, y: ${`(A..N)`}): ${`(A..N)`} = ${binTuple("combine")} - def empty: ${`(A..N)`} = ${nullaryTuple("empty")} - } - - - implicit def tuple${arity}Order[${`A..N`}](implicit ${constraints("Order")}): Order[${`(A..N)`}] = + - implicit def catsKernelStdOrderForTuple${arity}[${`A..N`}](implicit ${constraints("Order")}): Order[${`(A..N)`}] = - new Order[${`(A..N)`}] { - def compare(x: ${`(A..N)`}, y: ${`(A..N)`}): Int = - ${binMethod("compare").find(_ != 0).getOrElse(0)} - } - - - implicit def tuple${arity}PartialOrder[${`A..N`}](implicit ${constraints("PartialOrder")}): PartialOrder[${`(A..N)`}] = + - implicit def catsKernelStdPartialOrderForTuple${arity}[${`A..N`}](implicit ${constraints("PartialOrder")}): PartialOrder[${`(A..N)`}] = - new PartialOrder[${`(A..N)`}] { - def partialCompare(x: ${`(A..N)`}, y: ${`(A..N)`}): Double = - ${binMethod("partialCompare").find(_ != 0.0).getOrElse(0.0)} - } - - - implicit def tuple${arity}Semigroup[${`A..N`}](implicit ${constraints("Semigroup")}): Semigroup[${`(A..N)`}] = + - implicit def catsKernelStdSemigroupForTuple${arity}[${`A..N`}](implicit ${constraints("Semigroup")}): Semigroup[${`(A..N)`}] = - new Semigroup[${`(A..N)`}] { - def combine(x: ${`(A..N)`}, y: ${`(A..N)`}): ${`(A..N)`} = ${binTuple("combine")} - } - - - implicit def tuple${arity}Semilattice[${`A..N`}](implicit ${constraints("Semilattice")}): Semilattice[${`(A..N)`}] = + - implicit def catsKernelStdSemilatticeForTuple${arity}[${`A..N`}](implicit ${constraints("Semilattice")}): Semilattice[${`(A..N)`}] = - new Semilattice[${`(A..N)`}] { - def combine(x: ${`(A..N)`}, y: ${`(A..N)`}): ${`(A..N)`} = ${binTuple("combine")} - } From 0c6997bad5e384aee31d4505cb2db59f4eaa4855 Mon Sep 17 00:00:00 2001 From: Tomas Mikula Date: Mon, 16 May 2016 19:40:12 -0400 Subject: [PATCH 34/40] Add FlatMapRec, MonadRec. --- core/src/main/scala/cats/FlatMapRec.scala | 24 +++++++++++++++++++++++ core/src/main/scala/cats/MonadRec.scala | 5 +++++ 2 files changed, 29 insertions(+) create mode 100644 core/src/main/scala/cats/FlatMapRec.scala create mode 100644 core/src/main/scala/cats/MonadRec.scala diff --git a/core/src/main/scala/cats/FlatMapRec.scala b/core/src/main/scala/cats/FlatMapRec.scala new file mode 100644 index 0000000000..5658b3fe00 --- /dev/null +++ b/core/src/main/scala/cats/FlatMapRec.scala @@ -0,0 +1,24 @@ +package cats + +import simulacrum.typeclass + +import cats.data.Xor + +/** + * Version of [[cats.FlatMap]] capable of stack-safe recursive `flatMap`s. + * + * Based on Phil Freeman's + * [[http://functorial.com/stack-safety-for-free/index.pdf Stack Safety for Free]]. + */ +@typeclass trait FlatMapRec[F[_]] extends FlatMap[F] { + + /** + * Keeps calling `f` until a `[[cats.data.Xor.Right Right]][B]` is returned. + * + * Implementations of this method must use constant stack space. + * + * `f` must use constant stack space. (It is OK to use a constant number of + * `map`s and `flatMap`s inside `f`.) + */ + def tailRecM[A, B](a: A)(f: A => F[A Xor B]): F[B] +} diff --git a/core/src/main/scala/cats/MonadRec.scala b/core/src/main/scala/cats/MonadRec.scala new file mode 100644 index 0000000000..e61588c8da --- /dev/null +++ b/core/src/main/scala/cats/MonadRec.scala @@ -0,0 +1,5 @@ +package cats + +import simulacrum.typeclass + +@typeclass trait MonadRec[F[_]] extends Monad[F] with FlatMapRec[F] From 5a38209b2a13ded2652528a8767b1683e74d339d Mon Sep 17 00:00:00 2001 From: Tomas Mikula Date: Mon, 16 May 2016 21:49:43 -0400 Subject: [PATCH 35/40] MonadRec instances for Id, Option, OptionT, Either, Xor, XorT, Free, List. --- core/src/main/scala/cats/data/OptionT.scala | 42 ++++++++++++++----- core/src/main/scala/cats/data/Xor.scala | 11 ++++- core/src/main/scala/cats/data/XorT.scala | 22 +++++++++- core/src/main/scala/cats/package.scala | 11 ++++- core/src/main/scala/cats/std/either.scala | 15 ++++++- core/src/main/scala/cats/std/list.scala | 20 ++++++++- core/src/main/scala/cats/std/option.scala | 15 ++++++- free/src/main/scala/cats/free/Free.scala | 9 +++- free/src/test/scala/cats/free/FreeTests.scala | 14 +++++-- .../main/scala/cats/laws/FlatMapRecLaws.scala | 26 ++++++++++++ .../main/scala/cats/laws/MonadRecLaws.scala | 14 +++++++ .../laws/discipline/FlatMapRecTests.scala | 35 ++++++++++++++++ .../cats/laws/discipline/MonadRecTests.scala | 38 +++++++++++++++++ .../test/scala/cats/tests/EitherTests.scala | 6 +-- tests/src/test/scala/cats/tests/IdTests.scala | 3 ++ .../cats/tests/MonadRecInstancesTests.scala | 41 ++++++++++++++++++ .../test/scala/cats/tests/OptionTTests.scala | 8 ++-- .../test/scala/cats/tests/OptionTests.scala | 3 ++ .../src/test/scala/cats/tests/XorTTests.scala | 2 + .../src/test/scala/cats/tests/XorTests.scala | 5 ++- 20 files changed, 304 insertions(+), 36 deletions(-) create mode 100644 laws/src/main/scala/cats/laws/FlatMapRecLaws.scala create mode 100644 laws/src/main/scala/cats/laws/MonadRecLaws.scala create mode 100644 laws/src/main/scala/cats/laws/discipline/FlatMapRecTests.scala create mode 100644 laws/src/main/scala/cats/laws/discipline/MonadRecTests.scala create mode 100644 tests/src/test/scala/cats/tests/MonadRecInstancesTests.scala diff --git a/core/src/main/scala/cats/data/OptionT.scala b/core/src/main/scala/cats/data/OptionT.scala index 91575a4510..2754604656 100644 --- a/core/src/main/scala/cats/data/OptionT.scala +++ b/core/src/main/scala/cats/data/OptionT.scala @@ -132,7 +132,7 @@ object OptionT extends OptionTInstances { def liftF[F[_], A](fa: F[A])(implicit F: Functor[F]): OptionT[F, A] = OptionT(F.map(fa)(Some(_))) } -private[data] sealed trait OptionTInstances1 { +private[data] sealed trait OptionTInstances2 { implicit def catsDataFunctorForOptionT[F[_]:Functor]: Functor[OptionT[F, ?]] = new Functor[OptionT[F, ?]] { override def map[A, B](fa: OptionT[F, A])(f: A => B): OptionT[F, B] = @@ -148,18 +148,15 @@ private[data] sealed trait OptionTInstances1 { } } -private[data] sealed trait OptionTInstances extends OptionTInstances1 { - - implicit def catsDataMonadForOptionT[F[_]](implicit F: Monad[F]): Monad[OptionT[F, ?]] = - new Monad[OptionT[F, ?]] { - def pure[A](a: A): OptionT[F, A] = OptionT.pure(a) +private[data] sealed trait OptionTInstances1 extends OptionTInstances2 { - def flatMap[A, B](fa: OptionT[F, A])(f: A => OptionT[F, B]): OptionT[F, B] = - fa.flatMap(f) + implicit def catsDataMonadForOptionT[F[_]](implicit F0: Monad[F]): Monad[OptionT[F, ?]] = + new OptionTMonad[F] { implicit val F = F0 } +} - override def map[A, B](fa: OptionT[F, A])(f: A => B): OptionT[F, B] = - fa.map(f) - } +private[data] sealed trait OptionTInstances extends OptionTInstances1 { + implicit def catsDataMonadRecForOptionT[F[_]](implicit F0: MonadRec[F]): MonadRec[OptionT[F, ?]] = + new OptionTMonadRec[F] { implicit val F = F0 } implicit def catsDataEqForOptionT[F[_], A](implicit FA: Eq[F[Option[A]]]): Eq[OptionT[F, A]] = FA.on(_.value) @@ -167,3 +164,26 @@ private[data] sealed trait OptionTInstances extends OptionTInstances1 { implicit def catsDataShowForOptionT[F[_], A](implicit F: Show[F[Option[A]]]): Show[OptionT[F, A]] = functor.Contravariant[Show].contramap(F)(_.value) } + +private[data] trait OptionTMonad[F[_]] extends Monad[OptionT[F, ?]] { + implicit val F: Monad[F] + + def pure[A](a: A): OptionT[F, A] = OptionT.pure(a) + + def flatMap[A, B](fa: OptionT[F, A])(f: A => OptionT[F, B]): OptionT[F, B] = + fa.flatMap(f) + + override def map[A, B](fa: OptionT[F, A])(f: A => B): OptionT[F, B] = + fa.map(f) +} + +private[data] trait OptionTMonadRec[F[_]] extends MonadRec[OptionT[F, ?]] with OptionTMonad[F] { + implicit val F: MonadRec[F] + + def tailRecM[A, B](a: A)(f: A => OptionT[F, A Xor B]): OptionT[F, B] = + OptionT(F.tailRecM(a)(a0 => F.map(f(a0).value){ + case None => Xor.Right(None) + case Some(Xor.Left(a1)) => Xor.Left(a1) + case Some(Xor.Right(b)) => Xor.Right(Some(b)) + })) +} diff --git a/core/src/main/scala/cats/data/Xor.scala b/core/src/main/scala/cats/data/Xor.scala index d8a6a4a2b3..08136b4eb0 100644 --- a/core/src/main/scala/cats/data/Xor.scala +++ b/core/src/main/scala/cats/data/Xor.scala @@ -1,6 +1,7 @@ package cats package data +import scala.annotation.tailrec import scala.reflect.ClassTag import scala.util.{Failure, Success, Try} @@ -233,13 +234,19 @@ private[data] sealed abstract class XorInstances extends XorInstances1 { } } - implicit def catsDataInstancesForXor[A]: Traverse[A Xor ?] with MonadError[Xor[A, ?], A] = - new Traverse[A Xor ?] with MonadError[Xor[A, ?], A] { + implicit def catsDataInstancesForXor[A]: Traverse[A Xor ?] with MonadRec[A Xor ?] with MonadError[Xor[A, ?], A] = + new Traverse[A Xor ?] with MonadRec[A Xor ?] with MonadError[Xor[A, ?], A] { def traverse[F[_]: Applicative, B, C](fa: A Xor B)(f: B => F[C]): F[A Xor C] = fa.traverse(f) def foldLeft[B, C](fa: A Xor B, c: C)(f: (C, B) => C): C = fa.foldLeft(c)(f) def foldRight[B, C](fa: A Xor B, lc: Eval[C])(f: (B, Eval[C]) => Eval[C]): Eval[C] = fa.foldRight(lc)(f) def flatMap[B, C](fa: A Xor B)(f: B => A Xor C): A Xor C = fa.flatMap(f) def pure[B](b: B): A Xor B = Xor.right(b) + @tailrec def tailRecM[B, C](b: B)(f: B => A Xor (B Xor C)): A Xor C = + f(b) match { + case Xor.Left(a) => Xor.Left(a) + case Xor.Right(Xor.Left(b1)) => tailRecM(b1)(f) + case Xor.Right(Xor.Right(c)) => Xor.Right(c) + } def handleErrorWith[B](fea: Xor[A, B])(f: A => Xor[A, B]): Xor[A, B] = fea match { case Xor.Left(e) => f(e) diff --git a/core/src/main/scala/cats/data/XorT.scala b/core/src/main/scala/cats/data/XorT.scala index 555f9c1b39..91feb688c4 100644 --- a/core/src/main/scala/cats/data/XorT.scala +++ b/core/src/main/scala/cats/data/XorT.scala @@ -279,6 +279,11 @@ private[data] abstract class XorTInstances1 extends XorTInstances2 { } private[data] abstract class XorTInstances2 extends XorTInstances3 { + implicit def catsDataMonadRecForXorT[F[_], L](implicit F0: MonadRec[F]): MonadRec[XorT[F, L, ?]] = + new XorTMonadRec[F, L] { implicit val F = F0 } +} + +private[data] abstract class XorTInstances3 extends XorTInstances4 { implicit def catsDataMonadErrorForXorT[F[_], L](implicit F: Monad[F]): MonadError[XorT[F, L, ?], L] = { implicit val F0 = F new XorTMonadError[F, L] { implicit val F = F0 } @@ -299,7 +304,7 @@ private[data] abstract class XorTInstances2 extends XorTInstances3 { } } -private[data] abstract class XorTInstances3 { +private[data] abstract class XorTInstances4 { implicit def catsDataFunctorForXorT[F[_], L](implicit F: Functor[F]): Functor[XorT[F, L, ?]] = { implicit val F0 = F new XorTFunctor[F, L] { implicit val F = F0 } @@ -311,10 +316,13 @@ private[data] trait XorTFunctor[F[_], L] extends Functor[XorT[F, L, ?]] { override def map[A, B](fa: XorT[F, L, A])(f: A => B): XorT[F, L, B] = fa map f } -private[data] trait XorTMonadError[F[_], L] extends MonadError[XorT[F, L, ?], L] with XorTFunctor[F, L] { +private[data] trait XorTMonad[F[_], L] extends Monad[XorT[F, L, ?]] with XorTFunctor[F, L] { implicit val F: Monad[F] def pure[A](a: A): XorT[F, L, A] = XorT.pure[F, L, A](a) def flatMap[A, B](fa: XorT[F, L, A])(f: A => XorT[F, L, B]): XorT[F, L, B] = fa flatMap f +} + +private[data] trait XorTMonadError[F[_], L] extends MonadError[XorT[F, L, ?], L] with XorTMonad[F, L] { def handleErrorWith[A](fea: XorT[F, L, A])(f: L => XorT[F, L, A]): XorT[F, L, A] = XorT(F.flatMap(fea.value) { case Xor.Left(e) => f(e).value @@ -333,6 +341,16 @@ private[data] trait XorTMonadError[F[_], L] extends MonadError[XorT[F, L, ?], L] fla.recoverWith(pf) } +private[data] trait XorTMonadRec[F[_], L] extends MonadRec[XorT[F, L, ?]] with XorTMonad[F, L] { + implicit val F: MonadRec[F] + def tailRecM[A, B](a: A)(f: A => XorT[F, L, A Xor B]): XorT[F, L, B] = + XorT(F.tailRecM(a)(a0 => F.map(f(a0).value){ + case Xor.Left(l) => Xor.Right(Xor.Left(l)) + case Xor.Right(Xor.Left(a1)) => Xor.Left(a1) + case Xor.Right(Xor.Right(b)) => Xor.Right(Xor.Right(b)) + })) +} + private[data] trait XorTMonadFilter[F[_], L] extends MonadFilter[XorT[F, L, ?]] with XorTMonadError[F, L] { implicit val F: Monad[F] implicit val L: Monoid[L] diff --git a/core/src/main/scala/cats/package.scala b/core/src/main/scala/cats/package.scala index d1e7ad5730..cc90780828 100644 --- a/core/src/main/scala/cats/package.scala +++ b/core/src/main/scala/cats/package.scala @@ -1,3 +1,6 @@ +import scala.annotation.tailrec +import cats.data.Xor + /** * Symbolic aliases for various types are defined here. */ @@ -26,12 +29,16 @@ package object cats { * encodes pure unary function application. */ type Id[A] = A - implicit val idInstances: Bimonad[Id] with Traverse[Id] = - new Bimonad[Id] with Traverse[Id] { + implicit val idInstances: Bimonad[Id] with MonadRec[Id] with Traverse[Id] = + new Bimonad[Id] with MonadRec[Id] with Traverse[Id] { def pure[A](a: A): A = a def extract[A](a: A): A = a def flatMap[A, B](a: A)(f: A => B): B = f(a) def coflatMap[A, B](a: A)(f: A => B): B = f(a) + @tailrec def tailRecM[A, B](a: A)(f: A => A Xor B): B = f(a) match { + case Xor.Left(a1) => tailRecM(a1)(f) + case Xor.Right(b) => b + } override def map[A, B](fa: A)(f: A => B): B = f(fa) override def ap[A, B](ff: A => B)(fa: A): B = ff(fa) override def flatten[A](ffa: A): A = ffa diff --git a/core/src/main/scala/cats/std/either.scala b/core/src/main/scala/cats/std/either.scala index 43962597bf..019a4dc29f 100644 --- a/core/src/main/scala/cats/std/either.scala +++ b/core/src/main/scala/cats/std/either.scala @@ -1,6 +1,9 @@ package cats package std +import scala.annotation.tailrec +import cats.data.Xor + trait EitherInstances extends EitherInstances1 { implicit val catsStdBitraverseForEither: Bitraverse[Either] = new Bitraverse[Either] { @@ -23,8 +26,8 @@ trait EitherInstances extends EitherInstances1 { } } - implicit def catsStdInstancesForEither[A]: Monad[Either[A, ?]] with Traverse[Either[A, ?]] = - new Monad[Either[A, ?]] with Traverse[Either[A, ?]] { + implicit def catsStdInstancesForEither[A]: MonadRec[Either[A, ?]] with Traverse[Either[A, ?]] = + new MonadRec[Either[A, ?]] with Traverse[Either[A, ?]] { def pure[B](b: B): Either[A, B] = Right(b) def flatMap[B, C](fa: Either[A, B])(f: B => Either[A, C]): Either[A, C] = @@ -33,6 +36,14 @@ trait EitherInstances extends EitherInstances1 { override def map[B, C](fa: Either[A, B])(f: B => C): Either[A, C] = fa.right.map(f) + @tailrec + def tailRecM[B, C](b: B)(f: B => Either[A, B Xor C]): Either[A, C] = + f(b) match { + case Left(a) => Left(a) + case Right(Xor.Left(b1)) => tailRecM(b1)(f) + case Right(Xor.Right(c)) => Right(c) + } + override def map2Eval[B, C, Z](fb: Either[A, B], fc: Eval[Either[A, C]])(f: (B, C) => Z): Eval[Either[A, Z]] = fb match { // This should be safe, but we are forced to use `asInstanceOf`, diff --git a/core/src/main/scala/cats/std/list.scala b/core/src/main/scala/cats/std/list.scala index 102ad05e71..6154c7d494 100644 --- a/core/src/main/scala/cats/std/list.scala +++ b/core/src/main/scala/cats/std/list.scala @@ -6,10 +6,12 @@ import cats.syntax.show._ import scala.annotation.tailrec import scala.collection.mutable.ListBuffer +import cats.data.Xor + trait ListInstances extends cats.kernel.std.ListInstances { - implicit val catsStdInstancesForList: Traverse[List] with MonadCombine[List] with CoflatMap[List] = - new Traverse[List] with MonadCombine[List] with CoflatMap[List] { + implicit val catsStdInstancesForList: Traverse[List] with MonadCombine[List] with MonadRec[List] with CoflatMap[List] = + new Traverse[List] with MonadCombine[List] with MonadRec[List] with CoflatMap[List] { def empty[A]: List[A] = Nil @@ -26,6 +28,20 @@ trait ListInstances extends cats.kernel.std.ListInstances { override def map2[A, B, Z](fa: List[A], fb: List[B])(f: (A, B) => Z): List[Z] = fa.flatMap(a => fb.map(b => f(a, b))) + def tailRecM[A, B](a: A)(f: A => List[A Xor B]): List[B] = { + val buf = List.newBuilder[B] + @tailrec def go(lists: List[List[A Xor B]]): Unit = lists match { + case (ab :: abs) :: tail => ab match { + case Xor.Right(b) => buf += b; go(abs :: tail) + case Xor.Left(a) => go(f(a) :: abs :: tail) + } + case Nil :: tail => go(tail) + case Nil => () + } + go(f(a) :: Nil) + buf.result + } + def coflatMap[A, B](fa: List[A])(f: List[A] => B): List[B] = { @tailrec def loop(buf: ListBuffer[B], as: List[A]): List[B] = as match { diff --git a/core/src/main/scala/cats/std/option.scala b/core/src/main/scala/cats/std/option.scala index af943b923b..41204c5326 100644 --- a/core/src/main/scala/cats/std/option.scala +++ b/core/src/main/scala/cats/std/option.scala @@ -1,10 +1,13 @@ package cats package std +import scala.annotation.tailrec +import cats.data.Xor + trait OptionInstances extends cats.kernel.std.OptionInstances { - implicit val catsStdInstancesForOption: Traverse[Option] with MonadError[Option, Unit] with MonadCombine[Option] with CoflatMap[Option] with Alternative[Option] = - new Traverse[Option] with MonadError[Option, Unit] with MonadCombine[Option] with CoflatMap[Option] with Alternative[Option] { + implicit val catsStdInstancesForOption: Traverse[Option] with MonadError[Option, Unit] with MonadCombine[Option] with MonadRec[Option] with CoflatMap[Option] with Alternative[Option] = + new Traverse[Option] with MonadError[Option, Unit] with MonadCombine[Option] with MonadRec[Option] with CoflatMap[Option] with Alternative[Option] { def empty[A]: Option[A] = None @@ -18,6 +21,14 @@ trait OptionInstances extends cats.kernel.std.OptionInstances { def flatMap[A, B](fa: Option[A])(f: A => Option[B]): Option[B] = fa.flatMap(f) + @tailrec + def tailRecM[A, B](a: A)(f: A => Option[A Xor B]): Option[B] = + f(a) match { + case None => None + case Some(Xor.Left(a1)) => tailRecM(a1)(f) + case Some(Xor.Right(b)) => Some(b) + } + override def map2[A, B, Z](fa: Option[A], fb: Option[B])(f: (A, B) => Z): Option[Z] = fa.flatMap(a => fb.map(b => f(a, b))) diff --git a/free/src/main/scala/cats/free/Free.scala b/free/src/main/scala/cats/free/Free.scala index d6a14d3a70..c4e2233b7b 100644 --- a/free/src/main/scala/cats/free/Free.scala +++ b/free/src/main/scala/cats/free/Free.scala @@ -40,11 +40,16 @@ object Free { /** * `Free[S, ?]` has a monad for any type constructor `S[_]`. */ - implicit def freeMonad[S[_]]: Monad[Free[S, ?]] = - new Monad[Free[S, ?]] { + implicit def freeMonad[S[_]]: MonadRec[Free[S, ?]] = + new MonadRec[Free[S, ?]] { def pure[A](a: A): Free[S, A] = Free.pure(a) override def map[A, B](fa: Free[S, A])(f: A => B): Free[S, B] = fa.map(f) def flatMap[A, B](a: Free[S, A])(f: A => Free[S, B]): Free[S, B] = a.flatMap(f) + def tailRecM[A, B](a: A)(f: A => Free[S, A Xor B]): Free[S, B] = + f(a).flatMap(_ match { + case Xor.Left(a1) => tailRecM(a1)(f) // recursion OK here, since Free is lazy + case Xor.Right(b) => pure(b) + }) } } diff --git a/free/src/test/scala/cats/free/FreeTests.scala b/free/src/test/scala/cats/free/FreeTests.scala index 1b9c7d63be..5291c60d5c 100644 --- a/free/src/test/scala/cats/free/FreeTests.scala +++ b/free/src/test/scala/cats/free/FreeTests.scala @@ -3,7 +3,8 @@ package free import cats.tests.CatsSuite import cats.arrow.NaturalTransformation -import cats.laws.discipline.{CartesianTests, MonadTests, SerializableTests} +import cats.data.Xor +import cats.laws.discipline.{CartesianTests, MonadRecTests, SerializableTests} import cats.laws.discipline.arbitrary.function0Arbitrary import org.scalacheck.{Arbitrary, Gen} @@ -14,8 +15,8 @@ class FreeTests extends CatsSuite { implicit val iso = CartesianTests.Isomorphisms.invariant[Free[Option, ?]] - checkAll("Free[Option, ?]", MonadTests[Free[Option, ?]].monad[Int, Int, Int]) - checkAll("Monad[Free[Option, ?]]", SerializableTests.serializable(Monad[Free[Option, ?]])) + checkAll("Free[Option, ?]", MonadRecTests[Free[Option, ?]].monadRec[Int, Int, Int]) + checkAll("MonadRec[Free[Option, ?]]", SerializableTests.serializable(MonadRec[Free[Option, ?]])) test("mapSuspension id"){ forAll { x: Free[List, Int] => @@ -43,6 +44,13 @@ class FreeTests extends CatsSuite { } } + test("tailRecM is stack safe") { + val n = 50000 + val fa = MonadRec[Free[Option, ?]].tailRecM(0)(i => + Free.pure[Option, Int Xor Int](if(i < n) Xor.Left(i+1) else Xor.Right(i))) + fa should === (Free.pure[Option, Int](n)) + } + ignore("foldMap is stack safe") { trait FTestApi[A] case class TB(i: Int) extends FTestApi[Int] diff --git a/laws/src/main/scala/cats/laws/FlatMapRecLaws.scala b/laws/src/main/scala/cats/laws/FlatMapRecLaws.scala new file mode 100644 index 0000000000..8ff0254262 --- /dev/null +++ b/laws/src/main/scala/cats/laws/FlatMapRecLaws.scala @@ -0,0 +1,26 @@ +package cats +package laws + +import cats.data.Xor +import cats.syntax.flatMap._ +import cats.syntax.functor._ + +/** + * Laws that must be obeyed by any `FlatMapRec`. + */ +trait FlatMapRecLaws[F[_]] extends FlatMapLaws[F] { + implicit override def F: FlatMapRec[F] + + def tailRecMConsistentFlatMap[A](a: A, f: A => F[A]): IsEq[F[A]] = { + val bounce = F.tailRecM[(A, Int), A]((a, 1)) { case (a0, i) => + if(i > 0) f(a0).map(a1 => Xor.left((a1, i-1))) + else f(a0).map(Xor.right) + } + bounce <-> f(a).flatMap(f) + } +} + +object FlatMapRecLaws { + def apply[F[_]](implicit ev: FlatMapRec[F]): FlatMapRecLaws[F] = + new FlatMapRecLaws[F] { def F: FlatMapRec[F] = ev } +} diff --git a/laws/src/main/scala/cats/laws/MonadRecLaws.scala b/laws/src/main/scala/cats/laws/MonadRecLaws.scala new file mode 100644 index 0000000000..2b2e2e90a1 --- /dev/null +++ b/laws/src/main/scala/cats/laws/MonadRecLaws.scala @@ -0,0 +1,14 @@ +package cats +package laws + +/** + * Laws that must be obeyed by any `MonadRec`. + */ +trait MonadRecLaws[F[_]] extends MonadLaws[F] with FlatMapRecLaws[F] { + implicit override def F: MonadRec[F] +} + +object MonadRecLaws { + def apply[F[_]](implicit ev: MonadRec[F]): MonadRecLaws[F] = + new MonadRecLaws[F] { def F: MonadRec[F] = ev } +} diff --git a/laws/src/main/scala/cats/laws/discipline/FlatMapRecTests.scala b/laws/src/main/scala/cats/laws/discipline/FlatMapRecTests.scala new file mode 100644 index 0000000000..c4d2c3a2b5 --- /dev/null +++ b/laws/src/main/scala/cats/laws/discipline/FlatMapRecTests.scala @@ -0,0 +1,35 @@ +package cats +package laws +package discipline + +import cats.laws.discipline.CartesianTests.Isomorphisms +import org.scalacheck.Arbitrary +import org.scalacheck.Prop +import Prop._ + +trait FlatMapRecTests[F[_]] extends FlatMapTests[F] { + def laws: FlatMapRecLaws[F] + + def flatMapRec[A: Arbitrary, B: Arbitrary, C: Arbitrary](implicit + ArbFA: Arbitrary[F[A]], + ArbFB: Arbitrary[F[B]], + ArbFC: Arbitrary[F[C]], + ArbFAtoB: Arbitrary[F[A => B]], + ArbFBtoC: Arbitrary[F[B => C]], + EqFA: Eq[F[A]], + EqFB: Eq[F[B]], + EqFC: Eq[F[C]], + EqFABC: Eq[F[(A, B, C)]], + iso: Isomorphisms[F] + ): RuleSet = { + new DefaultRuleSet( + name = "flatMapRec", + parent = Some(flatMap[A, B, C]), + "tailRecM consistent flatMap" -> forAll(laws.tailRecMConsistentFlatMap[A] _)) + } +} + +object FlatMapRecTests { + def apply[F[_]: FlatMapRec]: FlatMapRecTests[F] = + new FlatMapRecTests[F] { def laws: FlatMapRecLaws[F] = FlatMapRecLaws[F] } +} diff --git a/laws/src/main/scala/cats/laws/discipline/MonadRecTests.scala b/laws/src/main/scala/cats/laws/discipline/MonadRecTests.scala new file mode 100644 index 0000000000..f6904ca6e4 --- /dev/null +++ b/laws/src/main/scala/cats/laws/discipline/MonadRecTests.scala @@ -0,0 +1,38 @@ +package cats +package laws +package discipline + +import cats.laws.discipline.CartesianTests.Isomorphisms +import org.scalacheck.Arbitrary +import org.scalacheck.Prop + +trait MonadRecTests[F[_]] extends MonadTests[F] with FlatMapRecTests[F] { + def laws: MonadRecLaws[F] + + def monadRec[A: Arbitrary: Eq, B: Arbitrary: Eq, C: Arbitrary: Eq](implicit + ArbFA: Arbitrary[F[A]], + ArbFB: Arbitrary[F[B]], + ArbFC: Arbitrary[F[C]], + ArbFAtoB: Arbitrary[F[A => B]], + ArbFBtoC: Arbitrary[F[B => C]], + EqFA: Eq[F[A]], + EqFB: Eq[F[B]], + EqFC: Eq[F[C]], + EqFABC: Eq[F[(A, B, C)]], + iso: Isomorphisms[F] + ): RuleSet = { + new RuleSet { + def name: String = "monadRec" + def bases: Seq[(String, RuleSet)] = Nil + def parents: Seq[RuleSet] = Seq(monad[A, B, C], flatMapRec[A, B, C]) + def props: Seq[(String, Prop)] = Nil + } + } +} + +object MonadRecTests { + def apply[F[_]: MonadRec]: MonadRecTests[F] = + new MonadRecTests[F] { + def laws: MonadRecLaws[F] = MonadRecLaws[F] + } +} diff --git a/tests/src/test/scala/cats/tests/EitherTests.scala b/tests/src/test/scala/cats/tests/EitherTests.scala index 97d7d74e08..b39fc91040 100644 --- a/tests/src/test/scala/cats/tests/EitherTests.scala +++ b/tests/src/test/scala/cats/tests/EitherTests.scala @@ -1,7 +1,7 @@ package cats package tests -import cats.laws.discipline.{BitraverseTests, TraverseTests, MonadTests, SerializableTests, CartesianTests} +import cats.laws.discipline.{BitraverseTests, TraverseTests, MonadRecTests, SerializableTests, CartesianTests} import cats.kernel.laws.OrderLaws class EitherTests extends CatsSuite { @@ -11,8 +11,8 @@ class EitherTests extends CatsSuite { checkAll("Either[Int, Int]", CartesianTests[Either[Int, ?]].cartesian[Int, Int, Int]) checkAll("Cartesian[Either[Int, ?]]", SerializableTests.serializable(Cartesian[Either[Int, ?]])) - checkAll("Either[Int, Int]", MonadTests[Either[Int, ?]].monad[Int, Int, Int]) - checkAll("Monad[Either[Int, ?]]", SerializableTests.serializable(Monad[Either[Int, ?]])) + checkAll("Either[Int, Int]", MonadRecTests[Either[Int, ?]].monadRec[Int, Int, Int]) + checkAll("MonadRec[Either[Int, ?]]", SerializableTests.serializable(MonadRec[Either[Int, ?]])) checkAll("Either[Int, Int] with Option", TraverseTests[Either[Int, ?]].traverse[Int, Int, Int, Int, Option, Option]) checkAll("Traverse[Either[Int, ?]", SerializableTests.serializable(Traverse[Either[Int, ?]])) diff --git a/tests/src/test/scala/cats/tests/IdTests.scala b/tests/src/test/scala/cats/tests/IdTests.scala index 115ccc875e..c7421e1369 100644 --- a/tests/src/test/scala/cats/tests/IdTests.scala +++ b/tests/src/test/scala/cats/tests/IdTests.scala @@ -9,6 +9,9 @@ class IdTests extends CatsSuite { checkAll("Id[Int]", BimonadTests[Id].bimonad[Int, Int, Int]) checkAll("Bimonad[Id]", SerializableTests.serializable(Bimonad[Id])) + checkAll("Id[Int]", MonadRecTests[Id].monadRec[Int, Int, Int]) + checkAll("MonadRec[Id]", SerializableTests.serializable(MonadRec[Id])) + checkAll("Id[Int]", TraverseTests[Id].traverse[Int, Int, Int, Int, Option, Option]) checkAll("Traverse[Id]", SerializableTests.serializable(Traverse[Id])) } diff --git a/tests/src/test/scala/cats/tests/MonadRecInstancesTests.scala b/tests/src/test/scala/cats/tests/MonadRecInstancesTests.scala new file mode 100644 index 0000000000..649cd60c01 --- /dev/null +++ b/tests/src/test/scala/cats/tests/MonadRecInstancesTests.scala @@ -0,0 +1,41 @@ +package cats +package tests + +import cats.data.{OptionT, Xor, XorT} + +class MonadRecInstancesTests extends CatsSuite { + def tailRecMStackSafety[M[_]](implicit M: MonadRec[M], Eq: Eq[M[Int]]): Unit = { + val n = 50000 + val res = M.tailRecM(0)(i => M.pure(if(i < n) Xor.Left(i + 1) else Xor.Right(i))) + res should === (M.pure(n)) + } + + test("tailRecM stack-safety for Id") { + tailRecMStackSafety[Id] + } + + test("tailRecM stack-safety for Option") { + tailRecMStackSafety[Option] + } + + test("tailRecM stack-safety for OptionT") { + tailRecMStackSafety[OptionT[Option, ?]] + } + + test("tailRecM stack-safety for Either") { + tailRecMStackSafety[Either[String, ?]] + } + + test("tailRecM stack-safety for Xor") { + tailRecMStackSafety[String Xor ?] + } + + test("tailRecM stack-safety for XorT") { + tailRecMStackSafety[XorT[Option, String, ?]] + } + + test("tailRecM stack-safety for List") { + tailRecMStackSafety[List] + } + +} diff --git a/tests/src/test/scala/cats/tests/OptionTTests.scala b/tests/src/test/scala/cats/tests/OptionTTests.scala index 95cb4fac7d..9d12864e88 100644 --- a/tests/src/test/scala/cats/tests/OptionTTests.scala +++ b/tests/src/test/scala/cats/tests/OptionTTests.scala @@ -1,8 +1,8 @@ package cats.tests -import cats.{Id, Monad, Cartesian, Show} +import cats.{Id, MonadRec, Cartesian, Show} import cats.data.{OptionT, Xor} -import cats.laws.discipline.{FunctorTests, SerializableTests, CartesianTests, MonadTests} +import cats.laws.discipline.{FunctorTests, SerializableTests, CartesianTests, MonadRecTests} import cats.laws.discipline.arbitrary._ class OptionTTests extends CatsSuite { @@ -160,8 +160,8 @@ class OptionTTests extends CatsSuite { } } - checkAll("Monad[OptionT[List, Int]]", MonadTests[OptionT[List, ?]].monad[Int, Int, Int]) - checkAll("Monad[OptionT[List, ?]]", SerializableTests.serializable(Monad[OptionT[List, ?]])) + checkAll("OptionT[List, Int]", MonadRecTests[OptionT[List, ?]].monadRec[Int, Int, Int]) + checkAll("MonadRec[OptionT[List, ?]]", SerializableTests.serializable(MonadRec[OptionT[List, ?]])) { implicit val F = ListWrapper.functor diff --git a/tests/src/test/scala/cats/tests/OptionTests.scala b/tests/src/test/scala/cats/tests/OptionTests.scala index 8c6ef464b9..a7e0d69d94 100644 --- a/tests/src/test/scala/cats/tests/OptionTests.scala +++ b/tests/src/test/scala/cats/tests/OptionTests.scala @@ -14,6 +14,9 @@ class OptionTests extends CatsSuite { checkAll("Option[Int]", MonadCombineTests[Option].monadCombine[Int, Int, Int]) checkAll("MonadCombine[Option]", SerializableTests.serializable(MonadCombine[Option])) + checkAll("Option[Int]", MonadRecTests[Option].monadRec[Int, Int, Int]) + checkAll("MonadRec[Option]", SerializableTests.serializable(MonadRec[Option])) + checkAll("Option[Int] with Option", TraverseTests[Option].traverse[Int, Int, Int, Int, Option, Option]) checkAll("Traverse[Option]", SerializableTests.serializable(Traverse[Option])) diff --git a/tests/src/test/scala/cats/tests/XorTTests.scala b/tests/src/test/scala/cats/tests/XorTTests.scala index b88e4c2958..80c96a6601 100644 --- a/tests/src/test/scala/cats/tests/XorTTests.scala +++ b/tests/src/test/scala/cats/tests/XorTTests.scala @@ -13,6 +13,8 @@ class XorTTests extends CatsSuite { implicit val iso = CartesianTests.Isomorphisms.invariant[XorT[List, String, ?]] checkAll("XorT[List, String, Int]", MonadErrorTests[XorT[List, String, ?], String].monadError[Int, Int, Int]) checkAll("MonadError[XorT[List, ?, ?]]", SerializableTests.serializable(MonadError[XorT[List, String, ?], String])) + checkAll("XorT[List, String, Int]", MonadRecTests[XorT[List, String, ?]].monadRec[Int, Int, Int]) + checkAll("MonadRec[XorT[List, String, ?]]", SerializableTests.serializable(MonadRec[XorT[List, String, ?]])) checkAll("XorT[List, ?, ?]", BifunctorTests[XorT[List, ?, ?]].bifunctor[Int, Int, Int, String, String, String]) checkAll("Bifunctor[XorT[List, ?, ?]]", SerializableTests.serializable(Bifunctor[XorT[List, ?, ?]])) checkAll("XorT[List, ?, ?]", BitraverseTests[XorT[List, ?, ?]].bitraverse[Option, Int, Int, Int, String, String, String]) diff --git a/tests/src/test/scala/cats/tests/XorTests.scala b/tests/src/test/scala/cats/tests/XorTests.scala index 6afa7308e0..ac984230f6 100644 --- a/tests/src/test/scala/cats/tests/XorTests.scala +++ b/tests/src/test/scala/cats/tests/XorTests.scala @@ -5,7 +5,7 @@ import cats.data.{NonEmptyList, Xor, XorT} import cats.data.Xor._ import cats.laws.discipline.{SemigroupKTests} import cats.laws.discipline.arbitrary._ -import cats.laws.discipline.{BitraverseTests, TraverseTests, MonadErrorTests, SerializableTests, CartesianTests} +import cats.laws.discipline.{BitraverseTests, TraverseTests, MonadErrorTests, MonadRecTests, SerializableTests, CartesianTests} import cats.kernel.laws.{GroupLaws, OrderLaws} import org.scalacheck.Arbitrary import org.scalacheck.Arbitrary._ @@ -27,6 +27,9 @@ class XorTests extends CatsSuite { checkAll("Xor[String, Int]", MonadErrorTests[Xor[String, ?], String].monadError[Int, Int, Int]) checkAll("MonadError[Xor, String]", SerializableTests.serializable(MonadError[Xor[String, ?], String])) + checkAll("Xor[String, Int]", MonadRecTests[Xor[String, ?]].monadRec[Int, Int, Int]) + checkAll("MonadRec[Xor[String, ?]]", SerializableTests.serializable(MonadRec[Xor[String, ?]])) + checkAll("Xor[String, Int] with Option", TraverseTests[Xor[String, ?]].traverse[Int, Int, Int, Int, Option, Option]) checkAll("Traverse[Xor[String,?]]", SerializableTests.serializable(Traverse[Xor[String, ?]])) From de5d911e02f2fb70d07da05ce1623b4d8b9b8d3e Mon Sep 17 00:00:00 2001 From: Tomas Mikula Date: Tue, 31 May 2016 01:00:19 -0400 Subject: [PATCH 36/40] MonadRec instances for Eval and StateT. --- core/src/main/scala/cats/Eval.scala | 10 +++- core/src/main/scala/cats/data/StateT.scala | 52 +++++++++++++------ .../src/test/scala/cats/tests/EvalTests.scala | 4 +- .../cats/tests/MonadRecInstancesTests.scala | 11 +++- .../test/scala/cats/tests/StateTTests.scala | 12 ++++- 5 files changed, 67 insertions(+), 22 deletions(-) diff --git a/core/src/main/scala/cats/Eval.scala b/core/src/main/scala/cats/Eval.scala index b0970cc808..a56e6215bf 100644 --- a/core/src/main/scala/cats/Eval.scala +++ b/core/src/main/scala/cats/Eval.scala @@ -1,6 +1,7 @@ package cats import scala.annotation.tailrec +import cats.data.Xor import cats.syntax.all._ /** @@ -294,14 +295,19 @@ object Eval extends EvalInstances { private[cats] trait EvalInstances extends EvalInstances0 { - implicit val evalBimonad: Bimonad[Eval] = - new Bimonad[Eval] { + implicit val evalBimonad: Bimonad[Eval] with MonadRec[Eval] = + new Bimonad[Eval] with MonadRec[Eval] { override def map[A, B](fa: Eval[A])(f: A => B): Eval[B] = fa.map(f) def pure[A](a: A): Eval[A] = Now(a) override def pureEval[A](la: Eval[A]): Eval[A] = la def flatMap[A, B](fa: Eval[A])(f: A => Eval[B]): Eval[B] = fa.flatMap(f) def extract[A](la: Eval[A]): A = la.value def coflatMap[A, B](fa: Eval[A])(f: Eval[A] => B): Eval[B] = Later(f(fa)) + def tailRecM[A, B](a: A)(f: A => Eval[A Xor B]): Eval[B] = + f(a).flatMap(_ match { + case Xor.Left(a1) => tailRecM(a1)(f) // recursion OK here, since flatMap is lazy + case Xor.Right(b) => Eval.now(b) + }) } implicit def evalOrder[A: Order]: Order[Eval[A]] = diff --git a/core/src/main/scala/cats/data/StateT.scala b/core/src/main/scala/cats/data/StateT.scala index e8f1406ac0..169e7832d7 100644 --- a/core/src/main/scala/cats/data/StateT.scala +++ b/core/src/main/scala/cats/data/StateT.scala @@ -135,22 +135,9 @@ object StateT extends StateTInstances { StateT(s => F.pure((s, a))) } -private[data] sealed abstract class StateTInstances { - implicit def catsDataMonadStateForStateT[F[_], S](implicit F: Monad[F]): MonadState[StateT[F, S, ?], S] = - new MonadState[StateT[F, S, ?], S] { - def pure[A](a: A): StateT[F, S, A] = - StateT.pure(a) - - def flatMap[A, B](fa: StateT[F, S, A])(f: A => StateT[F, S, B]): StateT[F, S, B] = - fa.flatMap(f) - - val get: StateT[F, S, S] = StateT(a => F.pure((a, a))) - - def set(s: S): StateT[F, S, Unit] = StateT(_ => F.pure((s, ()))) - - override def map[A, B](fa: StateT[F, S, A])(f: A => B): StateT[F, S, B] = - fa.map(f) - } +private[data] sealed abstract class StateTInstances extends StateTInstances1 { + implicit def catsDataMonadStateForStateT[F[_], S](implicit F0: Monad[F]): MonadState[StateT[F, S, ?], S] = + new StateTMonadState[F, S] { implicit def F = F0 } implicit def catsDataLiftForStateT[S]: TransLift.Aux[StateT[?[_], S, ?], Applicative] = new TransLift[StateT[?[_], S, ?]] { @@ -161,6 +148,11 @@ private[data] sealed abstract class StateTInstances { } +private[data] sealed abstract class StateTInstances1 { + implicit def catsDataMonadRecForStateT[F[_], S](implicit F0: MonadRec[F]): MonadRec[StateT[F, S, ?]] = + new StateTMonadRec[F, S] { implicit def F = F0 } +} + // To workaround SI-7139 `object State` needs to be defined inside the package object // together with the type alias. private[data] abstract class StateFunctions { @@ -193,3 +185,31 @@ private[data] abstract class StateFunctions { */ def set[S](s: S): State[S, Unit] = State(_ => (s, ())) } + +private[data] sealed trait StateTMonad[F[_], S] extends Monad[StateT[F, S, ?]] { + implicit def F: Monad[F] + + def pure[A](a: A): StateT[F, S, A] = + StateT.pure(a) + + def flatMap[A, B](fa: StateT[F, S, A])(f: A => StateT[F, S, B]): StateT[F, S, B] = + fa.flatMap(f) + + override def map[A, B](fa: StateT[F, S, A])(f: A => B): StateT[F, S, B] = + fa.map(f) +} + +private[data] sealed trait StateTMonadState[F[_], S] extends MonadState[StateT[F, S, ?], S] with StateTMonad[F, S] { + val get: StateT[F, S, S] = StateT(s => F.pure((s, s))) + + def set(s: S): StateT[F, S, Unit] = StateT(_ => F.pure((s, ()))) +} + +private[data] sealed trait StateTMonadRec[F[_], S] extends MonadRec[StateT[F, S, ?]] with StateTMonad[F, S] { + override implicit def F: MonadRec[F] + + def tailRecM[A, B](a: A)(f: A => StateT[F, S, A Xor B]): StateT[F, S, B] = + StateT[F, S, B](s => F.tailRecM[(S, A), (S, B)]((s, a)) { + case (s, a) => F.map(f(a).run(s)) { case (s, ab) => ab.bimap((s, _), (s, _)) } + }) +} diff --git a/tests/src/test/scala/cats/tests/EvalTests.scala b/tests/src/test/scala/cats/tests/EvalTests.scala index 76fb4f48d0..6e6ddaa44d 100644 --- a/tests/src/test/scala/cats/tests/EvalTests.scala +++ b/tests/src/test/scala/cats/tests/EvalTests.scala @@ -3,7 +3,7 @@ package tests import scala.math.min import cats.laws.ComonadLaws -import cats.laws.discipline.{CartesianTests, BimonadTests, SerializableTests} +import cats.laws.discipline.{BimonadTests, CartesianTests, MonadRecTests, SerializableTests} import cats.laws.discipline.arbitrary._ import cats.kernel.laws.{GroupLaws, OrderLaws} @@ -93,8 +93,10 @@ class EvalTests extends CatsSuite { { implicit val iso = CartesianTests.Isomorphisms.invariant[Eval] checkAll("Eval[Int]", BimonadTests[Eval].bimonad[Int, Int, Int]) + checkAll("Eval[Int]", MonadRecTests[Eval].monadRec[Int, Int, Int]) } checkAll("Bimonad[Eval]", SerializableTests.serializable(Bimonad[Eval])) + checkAll("MonadRec[Eval]", SerializableTests.serializable(MonadRec[Eval])) checkAll("Eval[Int]", GroupLaws[Eval[Int]].group) diff --git a/tests/src/test/scala/cats/tests/MonadRecInstancesTests.scala b/tests/src/test/scala/cats/tests/MonadRecInstancesTests.scala index 649cd60c01..89ad883e0d 100644 --- a/tests/src/test/scala/cats/tests/MonadRecInstancesTests.scala +++ b/tests/src/test/scala/cats/tests/MonadRecInstancesTests.scala @@ -1,7 +1,7 @@ package cats package tests -import cats.data.{OptionT, Xor, XorT} +import cats.data.{OptionT, StateT, Xor, XorT} class MonadRecInstancesTests extends CatsSuite { def tailRecMStackSafety[M[_]](implicit M: MonadRec[M], Eq: Eq[M[Int]]): Unit = { @@ -38,4 +38,13 @@ class MonadRecInstancesTests extends CatsSuite { tailRecMStackSafety[List] } + test("tailRecM stack-safety for Eval") { + tailRecMStackSafety[Eval] + } + + test("tailRecM stack-safety for StateT") { + import StateTTests._ // import implicit Eq[StateT[...]] + tailRecMStackSafety[StateT[Option, Int, ?]] + } + } diff --git a/tests/src/test/scala/cats/tests/StateTTests.scala b/tests/src/test/scala/cats/tests/StateTTests.scala index 677af2ea02..1f7b3aee75 100644 --- a/tests/src/test/scala/cats/tests/StateTTests.scala +++ b/tests/src/test/scala/cats/tests/StateTTests.scala @@ -2,7 +2,7 @@ package cats package tests import cats.kernel.std.tuple._ -import cats.laws.discipline.{CartesianTests, MonadStateTests, SerializableTests} +import cats.laws.discipline.{CartesianTests, MonadRecTests, MonadStateTests, SerializableTests} import cats.data.{State, StateT} import cats.laws.discipline.eq._ import cats.laws.discipline.arbitrary._ @@ -116,14 +116,22 @@ class StateTTests extends CatsSuite { { implicit val iso = CartesianTests.Isomorphisms.invariant[StateT[Option, Int, ?]] + checkAll("StateT[Option, Int, Int]", MonadStateTests[StateT[Option, Int, ?], Int].monadState[Int, Int, Int]) - checkAll("MonadState[StateT[Option, ?, ?], Int]", SerializableTests.serializable(MonadState[StateT[Option, Int, ?], Int])) + checkAll("MonadState[StateT[Option, Int, ?], Int]", SerializableTests.serializable(MonadState[StateT[Option, Int, ?], Int])) + + checkAll("StateT[Option, Int, Int]", MonadRecTests[StateT[Option, Int, ?]].monadRec[Int, Int, Int]) + checkAll("MonadRec[StateT[Option, Int, ?]]", SerializableTests.serializable(MonadRec[StateT[Option, Int, ?]])) } { implicit val iso = CartesianTests.Isomorphisms.invariant[State[Long, ?]] + checkAll("State[Long, ?]", MonadStateTests[State[Long, ?], Long].monadState[Int, Int, Int]) checkAll("MonadState[State[Long, ?], Long]", SerializableTests.serializable(MonadState[State[Long, ?], Long])) + + checkAll("State[Long, ?]", MonadRecTests[State[Long, ?]].monadRec[Int, Int, Int]) + checkAll("MonadRec[State[Long, ?]]", SerializableTests.serializable(MonadRec[State[Long, ?]])) } } From 8509cd41765ef82dc01184d9a20af203c814c935 Mon Sep 17 00:00:00 2001 From: peterneyens Date: Mon, 30 May 2016 19:23:18 +0200 Subject: [PATCH 37/40] Rename NaturalTransformation to FunctionK. --- .../src/main/scala/cats/arrow/FunctionK.scala | 31 +++++++++++++++++++ .../cats/arrow/NaturalTransformation.scala | 31 ------------------- core/src/main/scala/cats/data/Coproduct.scala | 10 +++--- core/src/main/scala/cats/data/Kleisli.scala | 4 +-- core/src/main/scala/cats/package.scala | 3 +- docs/src/main/tut/freeapplicative.md | 10 +++--- docs/src/main/tut/freemonad.md | 8 ++--- free/src/main/scala/cats/free/Coyoneda.scala | 4 +-- free/src/main/scala/cats/free/Free.scala | 10 +++--- .../scala/cats/free/FreeApplicative.scala | 16 +++++----- .../test/scala/cats/free/CoyonedaTests.scala | 4 +-- .../cats/free/FreeApplicativeTests.scala | 14 ++++----- free/src/test/scala/cats/free/FreeTests.scala | 10 +++--- .../test/scala/cats/free/InjectTests.scala | 8 ++--- ...mationTests.scala => FunctionKTests.scala} | 14 ++++----- .../test/scala/cats/tests/KleisliTests.scala | 4 +-- 16 files changed, 90 insertions(+), 91 deletions(-) create mode 100644 core/src/main/scala/cats/arrow/FunctionK.scala delete mode 100644 core/src/main/scala/cats/arrow/NaturalTransformation.scala rename tests/src/test/scala/cats/tests/{NaturalTransformationTests.scala => FunctionKTests.scala} (77%) diff --git a/core/src/main/scala/cats/arrow/FunctionK.scala b/core/src/main/scala/cats/arrow/FunctionK.scala new file mode 100644 index 0000000000..5e1cf69a8a --- /dev/null +++ b/core/src/main/scala/cats/arrow/FunctionK.scala @@ -0,0 +1,31 @@ +package cats +package arrow + +import cats.data.{Xor, Coproduct} + +trait FunctionK[F[_], G[_]] extends Serializable { self => + def apply[A](fa: F[A]): G[A] + + def compose[E[_]](f: FunctionK[E, F]): FunctionK[E, G] = + new FunctionK[E, G] { + def apply[A](fa: E[A]): G[A] = self.apply(f(fa)) + } + + def andThen[H[_]](f: FunctionK[G, H]): FunctionK[F, H] = + f.compose(self) + + def or[H[_]](h: FunctionK[H,G]): FunctionK[Coproduct[F, H, ?], G] = + new FunctionK[Coproduct[F, H, ?], G] { + def apply[A](fa: Coproduct[F, H, A]): G[A] = fa.run match { + case Xor.Left(ff) => self(ff) + case Xor.Right(gg) => h(gg) + } + } +} + +object FunctionK { + def id[F[_]]: FunctionK[F, F] = + new FunctionK[F, F] { + def apply[A](fa: F[A]): F[A] = fa + } +} diff --git a/core/src/main/scala/cats/arrow/NaturalTransformation.scala b/core/src/main/scala/cats/arrow/NaturalTransformation.scala deleted file mode 100644 index 0b792bc9cf..0000000000 --- a/core/src/main/scala/cats/arrow/NaturalTransformation.scala +++ /dev/null @@ -1,31 +0,0 @@ -package cats -package arrow - -import cats.data.{Xor, Coproduct} - -trait NaturalTransformation[F[_], G[_]] extends Serializable { self => - def apply[A](fa: F[A]): G[A] - - def compose[E[_]](f: NaturalTransformation[E, F]): NaturalTransformation[E, G] = - new NaturalTransformation[E, G] { - def apply[A](fa: E[A]): G[A] = self.apply(f(fa)) - } - - def andThen[H[_]](f: NaturalTransformation[G, H]): NaturalTransformation[F, H] = - f.compose(self) - - def or[H[_]](h: NaturalTransformation[H,G]): NaturalTransformation[Coproduct[F, H, ?],G] = - new (NaturalTransformation[Coproduct[F, H, ?],G]) { - def apply[A](fa: Coproduct[F, H, A]): G[A] = fa.run match { - case Xor.Left(ff) => self(ff) - case Xor.Right(gg) => h(gg) - } - } -} - -object NaturalTransformation { - def id[F[_]]: NaturalTransformation[F, F] = - new NaturalTransformation[F, F] { - def apply[A](fa: F[A]): F[A] = fa - } -} diff --git a/core/src/main/scala/cats/data/Coproduct.scala b/core/src/main/scala/cats/data/Coproduct.scala index 1428abd123..09a16e8f9a 100644 --- a/core/src/main/scala/cats/data/Coproduct.scala +++ b/core/src/main/scala/cats/data/Coproduct.scala @@ -1,7 +1,7 @@ package cats package data -import cats.arrow.NaturalTransformation +import cats.arrow.FunctionK import cats.functor.Contravariant /** `F` on the left and `G` on the right of [[Xor]]. @@ -63,13 +63,13 @@ final case class Coproduct[F[_], G[_], A](run: F[A] Xor G[A]) { * * Example: * {{{ - * scala> import cats.arrow.NaturalTransformation + * scala> import cats.arrow.FunctionK * scala> import cats.data.Coproduct * scala> val listToOption = - * | new NaturalTransformation[List, Option] { + * | new FunctionK[List, Option] { * | def apply[A](fa: List[A]): Option[A] = fa.headOption * | } - * scala> val optionToOption = NaturalTransformation.id[Option] + * scala> val optionToOption = FunctionK.id[Option] * scala> val cp1: Coproduct[List, Option, Int] = Coproduct.leftc(List(1,2,3)) * scala> val cp2: Coproduct[List, Option, Int] = Coproduct.rightc(Some(4)) * scala> cp1.fold(listToOption, optionToOption) @@ -78,7 +78,7 @@ final case class Coproduct[F[_], G[_], A](run: F[A] Xor G[A]) { * res1: Option[Int] = Some(4) * }}} */ - def fold[H[_]](f: NaturalTransformation[F, H], g: NaturalTransformation[G, H]): H[A] = + def fold[H[_]](f: FunctionK[F, H], g: FunctionK[G, H]): H[A] = run.fold(f.apply, g.apply) } diff --git a/core/src/main/scala/cats/data/Kleisli.scala b/core/src/main/scala/cats/data/Kleisli.scala index ea4b58c33c..6f06bb1e17 100644 --- a/core/src/main/scala/cats/data/Kleisli.scala +++ b/core/src/main/scala/cats/data/Kleisli.scala @@ -1,7 +1,7 @@ package cats package data -import cats.arrow.{Arrow, Choice, Split, NaturalTransformation} +import cats.arrow.{Arrow, Choice, Split, FunctionK} import cats.functor.{Contravariant, Strong} /** @@ -48,7 +48,7 @@ final case class Kleisli[F[_], A, B](run: A => F[B]) { self => def local[AA](f: AA => A): Kleisli[F, AA, B] = Kleisli(f.andThen(run)) - def transform[G[_]](f: NaturalTransformation[F,G]): Kleisli[G, A, B] = + def transform[G[_]](f: FunctionK[F,G]): Kleisli[G, A, B] = Kleisli(a => f(run(a))) def lower(implicit F: Applicative[F]): Kleisli[F, A, F[B]] = diff --git a/core/src/main/scala/cats/package.scala b/core/src/main/scala/cats/package.scala index cc90780828..3bd885db4e 100644 --- a/core/src/main/scala/cats/package.scala +++ b/core/src/main/scala/cats/package.scala @@ -6,8 +6,7 @@ import cats.data.Xor */ package object cats { - type ~>[F[_], G[_]] = arrow.NaturalTransformation[F, G] - type <~[F[_], G[_]] = arrow.NaturalTransformation[G, F] + type ~>[F[_], G[_]] = arrow.FunctionK[F, G] type ⊥ = Nothing type ⊤ = Any diff --git a/docs/src/main/tut/freeapplicative.md b/docs/src/main/tut/freeapplicative.md index 238d44ded1..f9534a8e77 100644 --- a/docs/src/main/tut/freeapplicative.md +++ b/docs/src/main/tut/freeapplicative.md @@ -54,14 +54,14 @@ at this point. To make our program useful we need to interpret it. ```tut:silent import cats.Id -import cats.arrow.NaturalTransformation +import cats.arrow.FunctionK import cats.std.function._ // a function that takes a string as input type FromString[A] = String => A val compiler = - new NaturalTransformation[ValidationOp, FromString] { + new FunctionK[ValidationOp, FromString] { def apply[A](fa: ValidationOp[A]): String => A = str => fa match { @@ -103,7 +103,7 @@ import scala.concurrent.ExecutionContext.Implicits.global type ParValidator[A] = Kleisli[Future, String, A] val parCompiler = - new NaturalTransformation[ValidationOp, ParValidator] { + new FunctionK[ValidationOp, ParValidator] { def apply[A](fa: ValidationOp[A]): ParValidator[A] = Kleisli { str => fa match { @@ -130,7 +130,7 @@ import cats.std.list._ type Log[A] = Const[List[String], A] val logCompiler = - new NaturalTransformation[ValidationOp, Log] { + new FunctionK[ValidationOp, Log] { def apply[A](fa: ValidationOp[A]): Log[A] = fa match { case Size(size) => Const(List(s"size >= $size")) @@ -166,7 +166,7 @@ import cats.data.Prod type ValidateAndLog[A] = Prod[ParValidator, Log, A] val prodCompiler = - new NaturalTransformation[ValidationOp, ValidateAndLog] { + new FunctionK[ValidationOp, ValidateAndLog] { def apply[A](fa: ValidationOp[A]): ValidateAndLog[A] = { fa match { case Size(size) => diff --git a/docs/src/main/tut/freemonad.md b/docs/src/main/tut/freemonad.md index d8cf2a2848..2563623091 100644 --- a/docs/src/main/tut/freemonad.md +++ b/docs/src/main/tut/freemonad.md @@ -166,14 +166,14 @@ DSL. By itself, this DSL only represents a sequence of operations To do this, we will use a *natural transformation* between type containers. Natural transformations go between types like `F[_]` and `G[_]` (this particular transformation would be written as -`NaturalTransformation[F,G]` or as done here using the symbolic +`FunctionK[F,G]` or as done here using the symbolic alternative as `F ~> G`). In our case, we will use a simple mutable map to represent our key value store: ```tut:silent -import cats.arrow.NaturalTransformation +import cats.arrow.FunctionK import cats.{Id, ~>} import scala.collection.mutable @@ -244,7 +244,7 @@ recursive structure by: This operation is called `Free.foldMap`: ```scala -final def foldMap[M[_]](f: NaturalTransformation[S,M])(M: Monad[M]): M[A] = ... +final def foldMap[M[_]](f: FunctionK[S,M])(M: Monad[M]): M[A] = ... ``` `M` must be a `Monad` to be flattenable (the famous monoid aspect @@ -366,7 +366,7 @@ def program(implicit I : Interacts[CatsApp], D : DataSource[CatsApp]): Free[Cats } ``` -Finally we write one interpreter per ADT and combine them with a `NaturalTransformation` to `Coproduct` so they can be +Finally we write one interpreter per ADT and combine them with a `FunctionK` to `Coproduct` so they can be compiled and applied to our `Free` program. ```tut:invisible diff --git a/free/src/main/scala/cats/free/Coyoneda.scala b/free/src/main/scala/cats/free/Coyoneda.scala index 9afa427ca3..2bf8ec5774 100644 --- a/free/src/main/scala/cats/free/Coyoneda.scala +++ b/free/src/main/scala/cats/free/Coyoneda.scala @@ -1,7 +1,7 @@ package cats package free -import cats.arrow.NaturalTransformation +import cats.arrow.FunctionK /** * The dual view of the Yoneda lemma. Also a free functor on `F`. @@ -38,7 +38,7 @@ sealed abstract class Coyoneda[F[_], A] extends Serializable { self => final def map[B](f: A => B): Aux[F, B, Pivot] = apply(fi)(f compose k) - final def transform[G[_]](f: NaturalTransformation[F,G]): Aux[G, A, Pivot] = + final def transform[G[_]](f: FunctionK[F,G]): Aux[G, A, Pivot] = apply(f(fi))(k) } diff --git a/free/src/main/scala/cats/free/Free.scala b/free/src/main/scala/cats/free/Free.scala index c4e2233b7b..f34934daa8 100644 --- a/free/src/main/scala/cats/free/Free.scala +++ b/free/src/main/scala/cats/free/Free.scala @@ -4,7 +4,7 @@ package free import scala.annotation.tailrec import cats.data.Xor, Xor.{Left, Right} -import cats.arrow.NaturalTransformation +import cats.arrow.FunctionK object Free { /** @@ -135,7 +135,7 @@ sealed abstract class Free[S[_], A] extends Product with Serializable { * Run to completion, mapping the suspension with the given transformation at each step and * accumulating into the monad `M`. */ - final def foldMap[M[_]](f: NaturalTransformation[S,M])(implicit M: Monad[M]): M[A] = + final def foldMap[M[_]](f: FunctionK[S,M])(implicit M: Monad[M]): M[A] = step match { case Pure(a) => M.pure(a) case Suspend(s) => f(s) @@ -147,13 +147,13 @@ sealed abstract class Free[S[_], A] extends Product with Serializable { * using the given natural transformation. * Be careful if your natural transformation is effectful, effects are applied by mapSuspension. */ - final def mapSuspension[T[_]](f: NaturalTransformation[S,T]): Free[T, A] = + final def mapSuspension[T[_]](f: FunctionK[S,T]): Free[T, A] = foldMap[Free[T, ?]] { - new NaturalTransformation[S, Free[T, ?]] { + new FunctionK[S, Free[T, ?]] { def apply[B](fa: S[B]): Free[T, B] = Suspend(f(fa)) } }(Free.freeMonad) - final def compile[T[_]](f: NaturalTransformation[S,T]): Free[T, A] = mapSuspension(f) + final def compile[T[_]](f: FunctionK[S,T]): Free[T, A] = mapSuspension(f) } diff --git a/free/src/main/scala/cats/free/FreeApplicative.scala b/free/src/main/scala/cats/free/FreeApplicative.scala index e5a9268ac8..b581ca5a4d 100644 --- a/free/src/main/scala/cats/free/FreeApplicative.scala +++ b/free/src/main/scala/cats/free/FreeApplicative.scala @@ -1,7 +1,7 @@ package cats package free -import cats.arrow.NaturalTransformation +import cats.arrow.FunctionK import cats.data.Const /** Applicative Functor for Free */ @@ -27,7 +27,7 @@ sealed abstract class FreeApplicative[F[_], A] extends Product with Serializable /** Interprets/Runs the sequence of operations using the semantics of Applicative G * Tail recursive only if G provides tail recursive interpretation (ie G is FreeMonad) */ - final def foldMap[G[_]](f: NaturalTransformation[F,G])(implicit G: Applicative[G]): G[A] = + final def foldMap[G[_]](f: FunctionK[F,G])(implicit G: Applicative[G]): G[A] = this match { case Pure(a) => G.pure(a) case Ap(pivot, fn) => G.map2(f(pivot), fn.foldMap(f))((a, g) => g(a)) @@ -37,26 +37,26 @@ sealed abstract class FreeApplicative[F[_], A] extends Product with Serializable * Tail recursive only if `F` provides tail recursive interpretation. */ final def fold(implicit F: Applicative[F]): F[A] = - foldMap(NaturalTransformation.id[F]) + foldMap(FunctionK.id[F]) /** Interpret this algebra into another FreeApplicative */ - final def compile[G[_]](f: NaturalTransformation[F,G]): FA[G, A] = + final def compile[G[_]](f: FunctionK[F,G]): FA[G, A] = foldMap[FA[G, ?]] { - new NaturalTransformation[F, FA[G, ?]] { + new FunctionK[F, FA[G, ?]] { def apply[B](fa: F[B]): FA[G, B] = lift(f(fa)) } } /** Interpret this algebra into a Monoid */ - final def analyze[M:Monoid](f: NaturalTransformation[F,λ[α => M]]): M = - foldMap[Const[M, ?]](new (NaturalTransformation[F,Const[M, ?]]) { + final def analyze[M:Monoid](f: FunctionK[F,λ[α => M]]): M = + foldMap[Const[M, ?]](new (FunctionK[F,Const[M, ?]]) { def apply[X](x: F[X]): Const[M,X] = Const(f(x)) }).getConst /** Compile this FreeApplicative algebra into a Free algebra. */ final def monad: Free[F, A] = foldMap[Free[F, ?]] { - new NaturalTransformation[F, Free[F, ?]] { + new FunctionK[F, Free[F, ?]] { def apply[B](fa: F[B]): Free[F, B] = Free.liftF(fa) } } diff --git a/free/src/test/scala/cats/free/CoyonedaTests.scala b/free/src/test/scala/cats/free/CoyonedaTests.scala index 26cbe38193..45e708acfa 100644 --- a/free/src/test/scala/cats/free/CoyonedaTests.scala +++ b/free/src/test/scala/cats/free/CoyonedaTests.scala @@ -2,7 +2,7 @@ package cats package free import cats.tests.CatsSuite -import cats.arrow.NaturalTransformation +import cats.arrow.FunctionK import cats.laws.discipline.{FunctorTests, SerializableTests} import org.scalacheck.Arbitrary @@ -27,7 +27,7 @@ class CoyonedaTests extends CatsSuite { test("transform and run is same as applying natural trans") { val nt = - new NaturalTransformation[Option, List] { + new FunctionK[Option, List] { def apply[A](fa: Option[A]): List[A] = fa.toList } val o = Option("hello") diff --git a/free/src/test/scala/cats/free/FreeApplicativeTests.scala b/free/src/test/scala/cats/free/FreeApplicativeTests.scala index de60d901ec..91096c92df 100644 --- a/free/src/test/scala/cats/free/FreeApplicativeTests.scala +++ b/free/src/test/scala/cats/free/FreeApplicativeTests.scala @@ -2,7 +2,7 @@ package cats package free import cats.tests.CatsSuite -import cats.arrow.NaturalTransformation +import cats.arrow.FunctionK import cats.laws.discipline.{CartesianTests, ApplicativeTests, SerializableTests} import cats.data.State @@ -18,7 +18,7 @@ class FreeApplicativeTests extends CatsSuite { implicit def freeApplicativeEq[S[_]: Applicative, A](implicit SA: Eq[S[A]]): Eq[FreeApplicative[S, A]] = new Eq[FreeApplicative[S, A]] { def eqv(a: FreeApplicative[S, A], b: FreeApplicative[S, A]): Boolean = { - val nt = NaturalTransformation.id[S] + val nt = FunctionK.id[S] SA.eqv(a.foldMap(nt), b.foldMap(nt)) } } @@ -44,7 +44,7 @@ class FreeApplicativeTests extends CatsSuite { val x = FreeApplicative.lift[Id, Int](1) val y = FreeApplicative.pure[Id, Int](2) val f = x.map(i => (j: Int) => i + j) - val nt = NaturalTransformation.id[Id] + val nt = FunctionK.id[Id] val r1 = y.ap(f) val r2 = r1.compile(nt) r1.foldMap(nt) should === (r2.foldMap(nt)) @@ -57,7 +57,7 @@ class FreeApplicativeTests extends CatsSuite { val r1 = y.ap(f) val r2 = r1.monad val nt = - new NaturalTransformation[Id, Id] { + new FunctionK[Id, Id] { def apply[A](fa: Id[A]): Id[A] = fa } r1.foldMap(nt) should === (r2.foldMap(nt)) @@ -75,7 +75,7 @@ class FreeApplicativeTests extends CatsSuite { test("FreeApplicative#analyze") { type G[A] = List[Int] - val countingNT = new NaturalTransformation[List, G] { + val countingNT = new FunctionK[List, G] { def apply[A](la: List[A]): G[A] = List(la.length) } @@ -97,7 +97,7 @@ class FreeApplicativeTests extends CatsSuite { type Tracked[A] = State[String, A] - val f: NaturalTransformation[Foo,Tracked] = new NaturalTransformation[Foo,Tracked] { + val f: FunctionK[Foo,Tracked] = new FunctionK[Foo,Tracked] { def apply[A](fa: Foo[A]): Tracked[A] = State[String, A]{ s0 => (s0 + fa.toString + ";", fa.getA) } @@ -120,7 +120,7 @@ class FreeApplicativeTests extends CatsSuite { val z = Apply[Dsl].map2(x, y)((_, _) => ()) - val asString: NaturalTransformation[Id,λ[α => String]] = new NaturalTransformation[Id,λ[α => String]] { + val asString: FunctionK[Id,λ[α => String]] = new FunctionK[Id,λ[α => String]] { def apply[A](a: A): String = a.toString } diff --git a/free/src/test/scala/cats/free/FreeTests.scala b/free/src/test/scala/cats/free/FreeTests.scala index 5291c60d5c..bf2574ae52 100644 --- a/free/src/test/scala/cats/free/FreeTests.scala +++ b/free/src/test/scala/cats/free/FreeTests.scala @@ -2,7 +2,7 @@ package cats package free import cats.tests.CatsSuite -import cats.arrow.NaturalTransformation +import cats.arrow.FunctionK import cats.data.Xor import cats.laws.discipline.{CartesianTests, MonadRecTests, SerializableTests} import cats.laws.discipline.arbitrary.function0Arbitrary @@ -20,7 +20,7 @@ class FreeTests extends CatsSuite { test("mapSuspension id"){ forAll { x: Free[List, Int] => - x.mapSuspension(NaturalTransformation.id[List]) should === (x) + x.mapSuspension(FunctionK.id[List]) should === (x) } } @@ -39,7 +39,7 @@ class FreeTests extends CatsSuite { test("mapSuspension consistent with foldMap"){ forAll { x: Free[List, Int] => val mapped = x.mapSuspension(headOptionU) - val folded = mapped.foldMap(NaturalTransformation.id[Option]) + val folded = mapped.foldMap(FunctionK.id[Option]) folded should === (x.foldMap(headOptionU)) } } @@ -64,7 +64,7 @@ class FreeTests extends CatsSuite { z <- if (j<10000) a(j) else Free.pure[FTestApi, Int](j) } yield z - def runner: NaturalTransformation[FTestApi,Id] = new NaturalTransformation[FTestApi,Id] { + def runner: FunctionK[FTestApi,Id] = new FunctionK[FTestApi,Id] { def apply[A](fa: FTestApi[A]): Id[A] = fa match { case TB(i) => i+1 } @@ -85,7 +85,7 @@ object FreeTests extends FreeTestsInstances { } sealed trait FreeTestsInstances { - val headOptionU: NaturalTransformation[List,Option] = new NaturalTransformation[List,Option] { + val headOptionU: FunctionK[List,Option] = new FunctionK[List,Option] { def apply[A](fa: List[A]): Option[A] = fa.headOption } diff --git a/free/src/test/scala/cats/free/InjectTests.scala b/free/src/test/scala/cats/free/InjectTests.scala index e957da6f00..ae922e63ba 100644 --- a/free/src/test/scala/cats/free/InjectTests.scala +++ b/free/src/test/scala/cats/free/InjectTests.scala @@ -1,7 +1,7 @@ package cats package free -import cats.arrow.NaturalTransformation +import cats.arrow.FunctionK import cats.tests.CatsSuite import cats.data.{Xor, Coproduct} import org.scalacheck._ @@ -40,19 +40,19 @@ class InjectTests extends CatsSuite { implicit def test2Arbitrary[A](implicit seqArb: Arbitrary[Int], intAArb : Arbitrary[Int => A]): Arbitrary[Test2[A]] = Arbitrary(for {s <- seqArb.arbitrary; f <- intAArb.arbitrary} yield Test2(s, f)) - object Test1Interpreter extends NaturalTransformation[Test1Algebra,Id] { + object Test1Interpreter extends FunctionK[Test1Algebra,Id] { override def apply[A](fa: Test1Algebra[A]): Id[A] = fa match { case Test1(k, h) => h(k) } } - object Test2Interpreter extends NaturalTransformation[Test2Algebra,Id] { + object Test2Interpreter extends FunctionK[Test2Algebra,Id] { override def apply[A](fa: Test2Algebra[A]): Id[A] = fa match { case Test2(k, h) => h(k) } } - val coProductInterpreter: NaturalTransformation[T,Id] = Test1Interpreter or Test2Interpreter + val coProductInterpreter: FunctionK[T,Id] = Test1Interpreter or Test2Interpreter val x: Free[T, Int] = Free.inject[Test1Algebra, T](Test1(1, identity)) diff --git a/tests/src/test/scala/cats/tests/NaturalTransformationTests.scala b/tests/src/test/scala/cats/tests/FunctionKTests.scala similarity index 77% rename from tests/src/test/scala/cats/tests/NaturalTransformationTests.scala rename to tests/src/test/scala/cats/tests/FunctionKTests.scala index 3c69bc8a57..15682de62a 100644 --- a/tests/src/test/scala/cats/tests/NaturalTransformationTests.scala +++ b/tests/src/test/scala/cats/tests/FunctionKTests.scala @@ -1,18 +1,18 @@ package cats package tests -import cats.arrow.NaturalTransformation +import cats.arrow.FunctionK import cats.data.Coproduct -class NaturalTransformationTests extends CatsSuite { +class FunctionKTests extends CatsSuite { val listToOption = - new NaturalTransformation[List, Option] { + new FunctionK[List, Option] { def apply[A](fa: List[A]): Option[A] = fa.headOption } val optionToList = - new NaturalTransformation[Option, List] { + new FunctionK[Option, List] { def apply[A](fa: Option[A]): List[A] = fa.toList } @@ -28,11 +28,11 @@ class NaturalTransformationTests extends CatsSuite { case class Test2[A](v : A) extends Test2Algebra[A] - object Test1NT extends NaturalTransformation[Test1Algebra,Id] { + object Test1NT extends FunctionK[Test1Algebra,Id] { override def apply[A](fa: Test1Algebra[A]): Id[A] = fa.v } - object Test2NT extends NaturalTransformation[Test2Algebra,Id] { + object Test2NT extends FunctionK[Test2Algebra,Id] { override def apply[A](fa: Test2Algebra[A]): Id[A] = fa.v } @@ -54,7 +54,7 @@ class NaturalTransformationTests extends CatsSuite { test("id is identity") { forAll { (list: List[Int]) => - NaturalTransformation.id[List].apply(list) should === (list) + FunctionK.id[List].apply(list) should === (list) } } diff --git a/tests/src/test/scala/cats/tests/KleisliTests.scala b/tests/src/test/scala/cats/tests/KleisliTests.scala index bcfd7f1ba5..1b831986b5 100644 --- a/tests/src/test/scala/cats/tests/KleisliTests.scala +++ b/tests/src/test/scala/cats/tests/KleisliTests.scala @@ -1,7 +1,7 @@ package cats package tests -import cats.arrow.{Arrow, Choice, Split, NaturalTransformation} +import cats.arrow.{Arrow, Choice, Split, FunctionK} import cats.data.{XorT, Kleisli, Reader} import cats.functor.{Contravariant, Strong} import cats.laws.discipline._ @@ -126,7 +126,7 @@ class KleisliTests extends CatsSuite { test("transform") { val opt = Kleisli { (x: Int) => Option(x.toDouble) } - val optToList = new NaturalTransformation[Option,List] { def apply[A](fa: Option[A]): List[A] = fa.toList } + val optToList = new FunctionK[Option,List] { def apply[A](fa: Option[A]): List[A] = fa.toList } val list = opt.transform(optToList) val is = 0.to(10).toList From 07de29206f92a0107fbf23f7f6f04e2eff543297 Mon Sep 17 00:00:00 2001 From: Tomas Mikula Date: Mon, 30 May 2016 20:32:04 -0400 Subject: [PATCH 38/40] Make Free.foldMap stack-safe. Fixes #721. The fix is possible by strengthening constraints on the target monad from Monad to MonadRec. --- free/src/main/scala/cats/free/Free.scala | 12 ++++++------ free/src/test/scala/cats/free/FreeTests.scala | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/free/src/main/scala/cats/free/Free.scala b/free/src/main/scala/cats/free/Free.scala index f34934daa8..93159b07b9 100644 --- a/free/src/main/scala/cats/free/Free.scala +++ b/free/src/main/scala/cats/free/Free.scala @@ -135,12 +135,12 @@ sealed abstract class Free[S[_], A] extends Product with Serializable { * Run to completion, mapping the suspension with the given transformation at each step and * accumulating into the monad `M`. */ - final def foldMap[M[_]](f: FunctionK[S,M])(implicit M: Monad[M]): M[A] = - step match { - case Pure(a) => M.pure(a) - case Suspend(s) => f(s) - case Gosub(c, g) => M.flatMap(c.foldMap(f))(cc => g(cc).foldMap(f)) - } + final def foldMap[M[_]](f: FunctionK[S,M])(implicit M: MonadRec[M]): M[A] = + M.tailRecM(this)(_.step match { + case Pure(a) => M.pure(Xor.right(a)) + case Suspend(sa) => M.map(f(sa))(Xor.right) + case Gosub(c, g) => M.map(c.foldMap(f))(cc => Xor.left(g(cc))) + }) /** * Compile your Free into another language by changing the suspension functor diff --git a/free/src/test/scala/cats/free/FreeTests.scala b/free/src/test/scala/cats/free/FreeTests.scala index bf2574ae52..09288b275c 100644 --- a/free/src/test/scala/cats/free/FreeTests.scala +++ b/free/src/test/scala/cats/free/FreeTests.scala @@ -51,7 +51,7 @@ class FreeTests extends CatsSuite { fa should === (Free.pure[Option, Int](n)) } - ignore("foldMap is stack safe") { + test("foldMap is stack safe") { trait FTestApi[A] case class TB(i: Int) extends FTestApi[Int] From b1b5985aeaec8071ad139444f66ad18f781c75eb Mon Sep 17 00:00:00 2001 From: Madder Date: Mon, 23 May 2016 15:34:51 +0100 Subject: [PATCH 39/40] Small fix for the forgetful functor/free monad analogy. --- docs/src/main/tut/freemonad.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/src/main/tut/freemonad.md b/docs/src/main/tut/freemonad.md index e84d130f86..3ba0948515 100644 --- a/docs/src/main/tut/freemonad.md +++ b/docs/src/main/tut/freemonad.md @@ -420,14 +420,14 @@ _very simple_ Monad from any _functor_**. The above forgetful functor takes a `Monad` and: - forgets its *monadic* part (e.g. the `flatMap` function) - - forgets its *applicative* part (e.g. the `pure` function) + - forgets its *pointed* part (e.g. the `pure` function) - finally keeps the *functor* part (e.g. the `map` function) By reversing all arrows to build the left-adjoint, we deduce that the -forgetful functor is basically a construction that: +free monad is basically a construction that: - takes a *functor* - - adds the *applicative* part (e.g. `pure`) + - adds the *pointed* part (e.g. `pure`) - adds the *monadic* behavior (e.g. `flatMap`) In terms of implementation, to build a *monad* from a *functor* we use From cad0970c9be7901b49e0316dbe5e34352968bb48 Mon Sep 17 00:00:00 2001 From: Adelbert Chang Date: Wed, 1 Jun 2016 12:37:58 -0700 Subject: [PATCH 40/40] Fix removed tuple instance in tests after merge --- tests/src/test/scala/cats/tests/BifunctorTests.scala | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/src/test/scala/cats/tests/BifunctorTests.scala b/tests/src/test/scala/cats/tests/BifunctorTests.scala index bb5de39ff0..b371e72e31 100644 --- a/tests/src/test/scala/cats/tests/BifunctorTests.scala +++ b/tests/src/test/scala/cats/tests/BifunctorTests.scala @@ -3,7 +3,6 @@ package tests import cats.functor.Bifunctor import cats.laws.discipline.{SerializableTests, BifunctorTests} -import cats.laws.discipline.eq.tuple2Eq class BifunctorTest extends CatsSuite { type Tuple2Either[A, B] = (Either[A, B], Either[A, B])