diff --git a/.scalafmt.conf b/.scalafmt.conf new file mode 100644 index 00000000000..b31b2248d0a --- /dev/null +++ b/.scalafmt.conf @@ -0,0 +1,5 @@ +maxColumn = 120 +continuationIndent.defnSite = 2 +assumeStandardLibraryStripMargin = true +danglingParentheses = true +rewrite.rules = [AvoidInfix, SortImports, RedundantBraces, RedundantParens, SortModifiers] diff --git a/alleycats-core/src/main/scala/alleycats/ConsK.scala b/alleycats-core/src/main/scala/alleycats/ConsK.scala index 021fddbb29d..9511065c4b3 100644 --- a/alleycats-core/src/main/scala/alleycats/ConsK.scala +++ b/alleycats-core/src/main/scala/alleycats/ConsK.scala @@ -17,4 +17,3 @@ object ConsK extends ConsK0 { @imports[ConsK] trait ConsK0 - diff --git a/alleycats-core/src/main/scala/alleycats/std/map.scala b/alleycats-core/src/main/scala/alleycats/std/map.scala index 4f120019781..63b9d7839d3 100644 --- a/alleycats-core/src/main/scala/alleycats/std/map.scala +++ b/alleycats-core/src/main/scala/alleycats/std/map.scala @@ -9,13 +9,17 @@ trait MapInstances { // toList is inconsistent. See https://github.com/typelevel/cats/issues/1831 implicit def alleycatsStdInstancesForMap[K]: Traverse[Map[K, ?]] = - new Traverse[Map[K, ?]] { + new Traverse[Map[K, ?]] { def traverse[G[_], A, B](fa: Map[K, A])(f: A => G[B])(implicit G: Applicative[G]): G[Map[K, B]] = { val gba: Eval[G[Map[K, B]]] = Always(G.pure(Map.empty)) - val gbb = Foldable.iterateRight(fa, gba){ (kv, lbuf) => - G.map2Eval(f(kv._2), lbuf)({ (b, buf) => buf + (kv._1 -> b)}) - }.value + val gbb = Foldable + .iterateRight(fa, gba) { (kv, lbuf) => + G.map2Eval(f(kv._2), lbuf)({ (b, buf) => + buf + (kv._1 -> b) + }) + } + .value G.map(gbb)(_.toMap) } @@ -23,7 +27,7 @@ trait MapInstances { fa.map { case (k, a) => (k, f(a)) } def foldLeft[A, B](fa: Map[K, A], b: B)(f: (B, A) => B): B = - fa.foldLeft(b) { case (x, (k, a)) => f(x, a)} + fa.foldLeft(b) { case (x, (k, a)) => f(x, a) } def foldRight[A, B](fa: Map[K, A], lb: Eval[B])(f: (A, Eval[B]) => Eval[B]): Eval[B] = Foldable.iterateRight(fa.values, lb)(f) @@ -45,11 +49,13 @@ trait MapInstances { override def toList[A](fa: Map[K, A]): List[A] = fa.values.toList - override def collectFirst[A, B](fa: Map[K, A])(pf: PartialFunction[A, B]): Option[B] = fa.collectFirst(new PartialFunction[(K, A), B] { - override def isDefinedAt(x: (K, A)) = pf.isDefinedAt(x._2) - override def apply(v1: (K, A)) = pf(v1._2) - }) + override def collectFirst[A, B](fa: Map[K, A])(pf: PartialFunction[A, B]): Option[B] = + fa.collectFirst(new PartialFunction[(K, A), B] { + override def isDefinedAt(x: (K, A)) = pf.isDefinedAt(x._2) + override def apply(v1: (K, A)) = pf(v1._2) + }) - override def collectFirstSome[A, B](fa: Map[K, A])(f: A => Option[B]): Option[B] = collectFirst(fa)(Function.unlift(f)) + override def collectFirstSome[A, B](fa: Map[K, A])(f: A => Option[B]): Option[B] = + collectFirst(fa)(Function.unlift(f)) } } diff --git a/alleycats-core/src/main/scala/alleycats/std/set.scala b/alleycats-core/src/main/scala/alleycats/std/set.scala index 9eaa6a03045..3477d946ed0 100644 --- a/alleycats-core/src/main/scala/alleycats/std/set.scala +++ b/alleycats-core/src/main/scala/alleycats/std/set.scala @@ -80,15 +80,15 @@ object SetInstances { override def get[A](fa: Set[A])(idx: Long): Option[A] = { @tailrec - def go(idx: Int, it: Iterator[A]): Option[A] = { + def go(idx: Int, it: Iterator[A]): Option[A] = if (it.hasNext) { - if (idx == 0) Some(it.next) else { + if (idx == 0) Some(it.next) + else { it.next go(idx - 1, it) } } else None - } - if (idx < Int.MaxValue && idx >= 0L) go(idx.toInt, fa.toIterator) else None + if (idx < Int.MaxValue && idx >= 0L) go(idx.toInt, fa.toIterator) else None } override def size[A](fa: Set[A]): Long = fa.size.toLong diff --git a/alleycats-core/src/main/scala/alleycats/std/try.scala b/alleycats-core/src/main/scala/alleycats/std/try.scala index 1594c5c9cb9..a0b86890229 100644 --- a/alleycats-core/src/main/scala/alleycats/std/try.scala +++ b/alleycats-core/src/main/scala/alleycats/std/try.scala @@ -42,7 +42,8 @@ object TryInstances { def coflatMap[A, B](fa: Try[A])(f: Try[A] => B): Try[B] = Try(f(fa)) def extract[A](p: Try[A]): A = p.get - def tailRecM[A, B](a: A)(f: (A) => Try[Either[A, B]]): Try[B] = cats.instances.try_.catsStdInstancesForTry.tailRecM(a)(f) + def tailRecM[A, B](a: A)(f: (A) => Try[Either[A, B]]): Try[B] = + cats.instances.try_.catsStdInstancesForTry.tailRecM(a)(f) } } diff --git a/alleycats-core/src/main/scala/alleycats/syntax/all.scala b/alleycats-core/src/main/scala/alleycats/syntax/all.scala index cb1e438c684..63476197267 100644 --- a/alleycats-core/src/main/scala/alleycats/syntax/all.scala +++ b/alleycats-core/src/main/scala/alleycats/syntax/all.scala @@ -1,5 +1,3 @@ package alleycats.syntax -object all - extends EmptySyntax - with FoldableSyntax +object all extends EmptySyntax with FoldableSyntax diff --git a/alleycats-core/src/main/scala/alleycats/syntax/foldable.scala b/alleycats-core/src/main/scala/alleycats/syntax/foldable.scala index ddcbce70b27..f4e4c9a1156 100644 --- a/alleycats-core/src/main/scala/alleycats/syntax/foldable.scala +++ b/alleycats-core/src/main/scala/alleycats/syntax/foldable.scala @@ -9,6 +9,8 @@ object foldable extends FoldableSyntax trait FoldableSyntax { implicit class ExtraFoldableOps[F[_]: Foldable, A](fa: F[A]) { def foreach(f: A => Unit): Unit = - fa.foldLeft(()) { (_, a) => f(a) } + fa.foldLeft(()) { (_, a) => + f(a) + } } } diff --git a/alleycats-laws/src/main/scala/alleycats/laws/discipline/FlatMapRecTests.scala b/alleycats-laws/src/main/scala/alleycats/laws/discipline/FlatMapRecTests.scala index 1bfc8333b80..9c4a34ef631 100644 --- a/alleycats-laws/src/main/scala/alleycats/laws/discipline/FlatMapRecTests.scala +++ b/alleycats-laws/src/main/scala/alleycats/laws/discipline/FlatMapRecTests.scala @@ -7,20 +7,18 @@ import org.scalacheck.Arbitrary import org.scalacheck.Prop._ import org.typelevel.discipline.Laws - trait FlatMapRecTests[F[_]] extends Laws { def laws: FlatMapLaws[F] def tailRecM[A: Arbitrary](implicit ArbFA: Arbitrary[F[A]], ArbAFA: Arbitrary[A => F[A]], - EqFA: Eq[F[A]] - ): RuleSet = { + EqFA: Eq[F[A]]): RuleSet = new DefaultRuleSet( name = "flatMapTailRec", parent = None, - "tailRecM consistent flatMap" -> forAll(laws.tailRecMConsistentFlatMap[A] _)) - } + "tailRecM consistent flatMap" -> forAll(laws.tailRecMConsistentFlatMap[A] _) + ) } object FlatMapRecTests { diff --git a/alleycats-tests/src/test/scala/alleycats/tests/AlleycatsSuite.scala b/alleycats-tests/src/test/scala/alleycats/tests/AlleycatsSuite.scala index c0769047115..a76ae9dcb12 100644 --- a/alleycats-tests/src/test/scala/alleycats/tests/AlleycatsSuite.scala +++ b/alleycats-tests/src/test/scala/alleycats/tests/AlleycatsSuite.scala @@ -1,7 +1,6 @@ package alleycats package tests - import alleycats.std.MapInstances import catalysts.Platform import cats._ @@ -25,7 +24,8 @@ trait TestSettings extends Configuration with Matchers { maxDiscardedFactor = if (Platform.isJvm) PosZDouble(5.0) else PosZDouble(50.0), minSize = PosZInt(0), sizeRange = if (Platform.isJvm) PosZInt(10) else PosZInt(5), - workers = PosInt(1)) + workers = PosInt(1) + ) lazy val slowCheckConfiguration: PropertyCheckConfiguration = if (Platform.isJvm) checkConfiguration @@ -33,10 +33,20 @@ trait TestSettings extends Configuration with Matchers { } /** - * An opinionated stack of traits to improve consistency and reduce - * boilerplate in Alleycats tests. Derived from Cats. - */ -trait AlleycatsSuite extends FunSuite with Matchers with GeneratorDrivenPropertyChecks with Discipline with TestSettings with AllInstances with AllSyntax with TestInstances with StrictCatsEquality with MapInstances { + * An opinionated stack of traits to improve consistency and reduce + * boilerplate in Alleycats tests. Derived from Cats. + */ +trait AlleycatsSuite + extends FunSuite + with Matchers + with GeneratorDrivenPropertyChecks + with Discipline + with TestSettings + with AllInstances + with AllSyntax + with TestInstances + with StrictCatsEquality + with MapInstances { implicit override val generatorDrivenConfig: PropertyCheckConfiguration = checkConfiguration @@ -48,7 +58,5 @@ trait AlleycatsSuite extends FunSuite with Matchers with GeneratorDrivenProperty sealed trait TestInstances { // To be replaced by https://github.com/rickynils/scalacheck/pull/170 implicit def arbitraryTry[A: Arbitrary]: Arbitrary[Try[A]] = - Arbitrary(Gen.oneOf( - arbitrary[A].map(Success(_)), - arbitrary[Throwable].map(Failure(_)))) + Arbitrary(Gen.oneOf(arbitrary[A].map(Success(_)), arbitrary[Throwable].map(Failure(_)))) } diff --git a/alleycats-tests/src/test/scala/alleycats/tests/IterableTests.scala b/alleycats-tests/src/test/scala/alleycats/tests/IterableTests.scala index 157e637f142..7ac5f2d6ef7 100644 --- a/alleycats-tests/src/test/scala/alleycats/tests/IterableTests.scala +++ b/alleycats-tests/src/test/scala/alleycats/tests/IterableTests.scala @@ -6,18 +6,20 @@ import alleycats.std.all._ class IterableTests extends AlleycatsSuite { - test("foldLeft sum == sum"){ + test("foldLeft sum == sum") { val it = Iterable(1, 2, 3) - Foldable[Iterable].foldLeft(it, 0){ + Foldable[Iterable].foldLeft(it, 0) { case (b, a) => a + b - } shouldEqual(it.sum) + } shouldEqual (it.sum) } - test("foldRight early termination"){ - Foldable[Iterable].foldRight(Iterable(1, 2, 3), Eval.now("KO")){ + test("foldRight early termination") { + Foldable[Iterable] + .foldRight(Iterable(1, 2, 3), Eval.now("KO")) { case (2, _) => Eval.now("OK") case (a, b) => b - }.value shouldEqual(Eval.now("OK").value) - } + } + .value shouldEqual (Eval.now("OK").value) + } } diff --git a/alleycats-tests/src/test/scala/alleycats/tests/SetSuite.scala b/alleycats-tests/src/test/scala/alleycats/tests/SetSuite.scala index 6f1136d3830..02ae856d557 100644 --- a/alleycats-tests/src/test/scala/alleycats/tests/SetSuite.scala +++ b/alleycats-tests/src/test/scala/alleycats/tests/SetSuite.scala @@ -11,6 +11,3 @@ class SetSuite extends AlleycatsSuite { checkAll("Foldable[Set]", SerializableTests.serializable(Foldable[Set])) } - - - diff --git a/build.sbt b/build.sbt index 3381bbdd59d..5cf33d564bb 100644 --- a/build.sbt +++ b/build.sbt @@ -17,7 +17,7 @@ lazy val commonSettings = Seq( Compile / unmanagedSourceDirectories ++= { val bd = baseDirectory.value def extraDirs(suffix: String) = - CrossType.Pure.sharedSrcDir(bd, "main").toList map (f => file(f.getPath + suffix)) + CrossType.Pure.sharedSrcDir(bd, "main").toList.map(f => file(f.getPath + suffix)) CrossVersion.partialVersion(scalaVersion.value) match { case Some((2, y)) if y <= 12 => extraDirs("-2.12-") @@ -27,21 +27,19 @@ lazy val commonSettings = Seq( } }, coverageEnabled := { - if(priorTo2_13(scalaVersion.value)) + if (priorTo2_13(scalaVersion.value)) coverageEnabled.value else false - } , - resolvers ++= Seq( - Resolver.sonatypeRepo("releases"), - Resolver.sonatypeRepo("snapshots")), + }, + resolvers ++= Seq(Resolver.sonatypeRepo("releases"), Resolver.sonatypeRepo("snapshots")), fork in test := true, parallelExecution in Test := false, scalacOptions in (Compile, doc) := (scalacOptions in (Compile, doc)).value.filter(_ != "-Xfatal-warnings"), //todo: reenable doctests on 2.13 once it's officially released. it's disabled for now due to changes to the `toString` impl of collections doctestGenTests := { val unchanged = doctestGenTests.value - if(priorTo2_13(scalaVersion.value)) unchanged else Nil + if (priorTo2_13(scalaVersion.value)) unchanged else Nil }, //todo: re-enable disable scaladoc on 2.13 due to https://github.com/scala/bug/issues/11045 sources in (Compile, doc) := { @@ -50,45 +48,44 @@ lazy val commonSettings = Seq( } ) ++ warnUnusedImport ++ update2_12 ++ xlint - def macroDependencies(scalaVersion: String) = CrossVersion.partialVersion(scalaVersion) match { - case Some((2, minor)) if minor < 13 => Seq( - compilerPlugin("org.scalamacros" %% "paradise" % "2.1.0" cross CrossVersion.patch) - ) + case Some((2, minor)) if minor < 13 => + Seq( + compilerPlugin(("org.scalamacros" %% "paradise" % "2.1.0").cross(CrossVersion.patch)) + ) case _ => Seq() } - lazy val catsSettings = Seq( incOptions := incOptions.value.withLogRecompileOnMacro(false), resolvers ++= Seq( - "bintray/non" at "http://dl.bintray.com/non/maven" + "bintray/non".at("http://dl.bintray.com/non/maven") ), libraryDependencies ++= Seq( "org.typelevel" %%% "machinist" % "0.6.5", - compilerPlugin("org.spire-math" %% "kind-projector" % "0.9.7")) ++ macroDependencies(scalaVersion.value), - + compilerPlugin("org.spire-math" %% "kind-projector" % "0.9.7") + ) ++ macroDependencies(scalaVersion.value), ) ++ commonSettings ++ publishSettings ++ scoverageSettings ++ simulacrumSettings - lazy val simulacrumSettings = Seq( libraryDependencies += "com.github.mpilquist" %%% "simulacrum" % "0.13.0" % Provided, pomPostProcess := { (node: xml.Node) => new RuleTransformer(new RewriteRule { override def transform(node: xml.Node): Seq[xml.Node] = node match { case e: xml.Elem - if e.label == "dependency" && - e.child.exists(child => child.label == "groupId" && child.text == "com.github.mpilquist") && - e.child.exists(child => child.label == "artifactId" && child.text.startsWith("simulacrum_")) => Nil + if e.label == "dependency" && + e.child.exists(child => child.label == "groupId" && child.text == "com.github.mpilquist") && + e.child.exists(child => child.label == "artifactId" && child.text.startsWith("simulacrum_")) => + Nil case _ => Seq(node) } }).transform(node).head } ) -lazy val tagName = Def.setting{ - s"v${if (releaseUseGlobalVersion.value) (version in ThisBuild).value else version.value}" +lazy val tagName = Def.setting { + s"v${if (releaseUseGlobalVersion.value) (version in ThisBuild).value else version.value}" } lazy val commonJsSettings = Seq( @@ -132,8 +129,6 @@ lazy val includeGeneratedSrc: Setting[_] = { } } - - // 2.13.0-M4 workarounds def catalystsVersion(scalaVersion: String): String = if (priorTo2_13(scalaVersion)) "0.6" else "0.7" @@ -149,14 +144,16 @@ def disciplineVersion(scalaVersion: String): String = lazy val disciplineDependencies = Seq( libraryDependencies += "org.scalacheck" %%% "scalacheck" % scalaCheckVersion(scalaVersion.value), - libraryDependencies += "org.typelevel" %%% "discipline" % disciplineVersion(scalaVersion.value)) + libraryDependencies += "org.typelevel" %%% "discipline" % disciplineVersion(scalaVersion.value) +) lazy val testingDependencies = Seq( libraryDependencies += "org.typelevel" %%% "catalysts-platform" % catalystsVersion(scalaVersion.value), libraryDependencies += "org.typelevel" %%% "catalysts-macros" % catalystsVersion(scalaVersion.value) % "test", // 2.13.0-M3 workaround // libraryDependencies += "org.scalatest" %%% "scalatest" % scalaTestVersion % "test") - libraryDependencies += "org.scalatest" %%% "scalatest" % scalatestVersion(scalaVersion.value) % "test") + libraryDependencies += "org.scalatest" %%% "scalatest" % scalatestVersion(scalaVersion.value) % "test" +) lazy val docsMappingsAPIDir = settingKey[String]("Name of subdirectory in site target directory for api docs") @@ -168,7 +165,8 @@ lazy val docSettings = Seq( """ |

© 2017 The Cats Maintainers

|

Website built with sbt-microsites © 2016 47 Degrees

- |""".stripMargin), + |""".stripMargin + ), micrositeHighlightTheme := "atom-one-light", micrositeHomepage := "http://typelevel.org/cats/", micrositeBaseUrl := "cats", @@ -179,7 +177,7 @@ lazy val docSettings = Seq( file("CONTRIBUTING.md") -> ExtraMdFileConfig( "contributing.md", "home", - Map("title" -> "Contributing", "section" -> "contributing", "position" -> "50") + Map("title" -> "Contributing", "section" -> "contributing", "position" -> "50") ), file("README.md") -> ExtraMdFileConfig( "index.md", @@ -196,7 +194,8 @@ lazy val docSettings = Seq( "gray" -> "#7B7B7E", "gray-light" -> "#E5E5E6", "gray-lighter" -> "#F4F3F4", - "white-color" -> "#FFFFFF"), + "white-color" -> "#FFFFFF" + ), autoAPIMappings := true, unidocProjectFilter in (ScalaUnidoc, unidoc) := inProjects(kernelJVM, coreJVM, freeJVM), docsMappingsAPIDir := "api", @@ -207,14 +206,19 @@ lazy val docSettings = Seq( scalacOptions in (ScalaUnidoc, unidoc) ++= Seq( "-Xfatal-warnings", "-groups", - "-doc-source-url", scmInfo.value.get.browseUrl + "/tree/master€{FILE_PATH}.scala", - "-sourcepath", baseDirectory.in(LocalRootProject).value.getAbsolutePath, + "-doc-source-url", + scmInfo.value.get.browseUrl + "/tree/master€{FILE_PATH}.scala", + "-sourcepath", + baseDirectory.in(LocalRootProject).value.getAbsolutePath, "-diagrams" - ) ++ (if(priorTo2_13(scalaVersion.value)) Seq( - "-Yno-adapted-args", - ) else Seq( - "-Ymacro-annotations" - )), + ) ++ (if (priorTo2_13(scalaVersion.value)) + Seq( + "-Yno-adapted-args", + ) + else + Seq( + "-Ymacro-annotations" + )), scalacOptions in Tut ~= (_.filterNot(Set("-Ywarn-unused-import", "-Ywarn-dead-code"))), git.remoteRepo := "git@github.com:typelevel/cats.git", includeFilter in makeSite := "*.html" | "*.css" | "*.png" | "*.jpg" | "*.gif" | "*.js" | "*.swf" | "*.yml" | "*.md" | "*.svg", @@ -226,7 +230,7 @@ def mimaPrevious(moduleName: String, scalaVer: String, ver: String): List[Module def semverBinCompatVersions(major: Int, minor: Int, patch: Int): List[(Int, Int, Int)] = { val majorVersions: List[Int] = List(major) - val minorVersions : List[Int] = + val minorVersions: List[Int] = if (major >= 1) Range(0, minor).inclusive.toList else List(minor) def patchVersions(currentMinVersion: Int): List[Int] = @@ -246,7 +250,7 @@ def mimaPrevious(moduleName: String, scalaVer: String, ver: String): List[Module Version(ver) match { case Some(Version(major, Seq(minor, patch), _)) => semverBinCompatVersions(major.toInt, minor.toInt, patch.toInt) - .map{case (maj, min, pat) => s"${maj}.${min}.${pat}"} + .map { case (maj, min, pat) => s"${maj}.${min}.${pat}" } case _ => List.empty[String] } @@ -257,8 +261,7 @@ def mimaPrevious(moduleName: String, scalaVer: String, ver: String): List[Module // Safety Net for Inclusions lazy val extraVersions: List[String] = List() - - if(priorTo2_13(scalaVer)) { + if (priorTo2_13(scalaVer)) { (mimaVersions ++ extraVersions) .filterNot(excludedVersions.contains(_)) .map(v => "org.typelevel" %% moduleName % v) @@ -266,11 +269,9 @@ def mimaPrevious(moduleName: String, scalaVer: String, ver: String): List[Module } -def mimaSettings(moduleName: String) = { - +def mimaSettings(moduleName: String) = Seq( mimaPreviousArtifacts := mimaPrevious(moduleName, scalaVersion.value, version.value).toSet, - mimaBinaryIssueFilters ++= { import com.typesafe.tools.mima.core._ import com.typesafe.tools.mima.core.ProblemFilters._ @@ -286,16 +287,14 @@ def mimaSettings(moduleName: String) = { exclude[DirectMissingMethodProblem]("cats.data.IRWSTInstances1.catsDataStrongForIRWST"), exclude[DirectMissingMethodProblem]("cats.data.OptionTInstances1.catsDataMonadErrorMonadForOptionT") ) ++ // Only compile-time abstractions (macros) allowed here - Seq( - exclude[IncompatibleMethTypeProblem]("cats.arrow.FunctionKMacros.lift"), - exclude[MissingTypesProblem]("cats.arrow.FunctionKMacros$"), - exclude[IncompatibleMethTypeProblem]("cats.arrow.FunctionKMacros#Lifter.this"), - exclude[IncompatibleResultTypeProblem]("cats.arrow.FunctionKMacros#Lifter.c") - ) + Seq( + exclude[IncompatibleMethTypeProblem]("cats.arrow.FunctionKMacros.lift"), + exclude[MissingTypesProblem]("cats.arrow.FunctionKMacros$"), + exclude[IncompatibleMethTypeProblem]("cats.arrow.FunctionKMacros#Lifter.this"), + exclude[IncompatibleResultTypeProblem]("cats.arrow.FunctionKMacros#Lifter.c") + ) } ) -} - lazy val docs = project .enablePlugins(MicrositesPlugin) @@ -307,31 +306,82 @@ lazy val docs = project .settings(commonJvmSettings) .dependsOn(coreJVM, freeJVM, kernelLawsJVM, lawsJVM, testkitJVM) -lazy val cats = project.in(file(".")) +lazy val cats = project + .in(file(".")) .settings(moduleName := "root") .settings(catsSettings) .settings(noPublishSettings) .aggregate(catsJVM, catsJS) .dependsOn(catsJVM, catsJS, testsJVM % "test-internal -> test") -lazy val catsJVM = project.in(file(".catsJVM")) +lazy val catsJVM = project + .in(file(".catsJVM")) .settings(moduleName := "cats") .settings(noPublishSettings) .settings(catsSettings) .settings(commonJvmSettings) - .aggregate(macrosJVM, kernelJVM, kernelLawsJVM, coreJVM, lawsJVM, freeJVM, testkitJVM, testsJVM, alleycatsCoreJVM, alleycatsLawsJVM, alleycatsTestsJVM, jvm, docs) - .dependsOn(macrosJVM, kernelJVM, kernelLawsJVM, coreJVM, lawsJVM, freeJVM, testkitJVM, testsJVM % "test-internal -> test", alleycatsCoreJVM, alleycatsLawsJVM, alleycatsTestsJVM % "test-internal -> test", jvm) + .aggregate(macrosJVM, + kernelJVM, + kernelLawsJVM, + coreJVM, + lawsJVM, + freeJVM, + testkitJVM, + testsJVM, + alleycatsCoreJVM, + alleycatsLawsJVM, + alleycatsTestsJVM, + jvm, + docs) + .dependsOn( + macrosJVM, + kernelJVM, + kernelLawsJVM, + coreJVM, + lawsJVM, + freeJVM, + testkitJVM, + testsJVM % "test-internal -> test", + alleycatsCoreJVM, + alleycatsLawsJVM, + alleycatsTestsJVM % "test-internal -> test", + jvm + ) -lazy val catsJS = project.in(file(".catsJS")) +lazy val catsJS = project + .in(file(".catsJS")) .settings(moduleName := "cats") .settings(noPublishSettings) .settings(catsSettings) .settings(commonJsSettings) - .aggregate(macrosJS, kernelJS, kernelLawsJS, coreJS, lawsJS, freeJS, testkitJS, testsJS, alleycatsCoreJS, alleycatsLawsJS, alleycatsTestsJS, js) - .dependsOn(macrosJS, kernelJS, kernelLawsJS, coreJS, lawsJS, freeJS, testkitJS, testsJS % "test-internal -> test", alleycatsCoreJS, alleycatsLawsJS, alleycatsTestsJS % "test-internal -> test", js) + .aggregate(macrosJS, + kernelJS, + kernelLawsJS, + coreJS, + lawsJS, + freeJS, + testkitJS, + testsJS, + alleycatsCoreJS, + alleycatsLawsJS, + alleycatsTestsJS, + js) + .dependsOn( + macrosJS, + kernelJS, + kernelLawsJS, + coreJS, + lawsJS, + freeJS, + testkitJS, + testsJS % "test-internal -> test", + alleycatsCoreJS, + alleycatsLawsJS, + alleycatsTestsJS % "test-internal -> test", + js + ) .enablePlugins(ScalaJSPlugin) - lazy val macros = crossProject(JSPlatform, JVMPlatform) .crossType(CrossType.Pure) .settings(moduleName := "cats-macros", name := "Cats macros") @@ -344,7 +394,6 @@ lazy val macros = crossProject(JSPlatform, JVMPlatform) lazy val macrosJVM = macros.jvm lazy val macrosJS = macros.js - lazy val kernel = crossProject(JSPlatform, JVMPlatform, NativePlatform) .crossType(CrossType.Pure) .in(file("kernel")) @@ -389,7 +438,7 @@ lazy val core = crossProject(JSPlatform, JVMPlatform) .settings(includeGeneratedSrc) .settings(libraryDependencies += "org.scalacheck" %%% "scalacheck" % scalaCheckVersion(scalaVersion.value) % "test") .jsSettings(commonJsSettings) - .jvmSettings(commonJvmSettings ++ mimaSettings("cats-core") ) + .jvmSettings(commonJvmSettings ++ mimaSettings("cats-core")) lazy val coreJVM = core.jvm lazy val coreJS = core.js @@ -431,7 +480,6 @@ lazy val tests = crossProject(JSPlatform, JVMPlatform) lazy val testsJVM = tests.jvm lazy val testsJS = tests.js - lazy val testkit = crossProject(JSPlatform, JVMPlatform) .crossType(CrossType.Pure) .dependsOn(macros, core, laws) @@ -452,17 +500,18 @@ lazy val alleycatsCore = crossProject(JSPlatform, JVMPlatform) .in(file("alleycats-core")) .dependsOn(core) .settings(moduleName := "alleycats-core", name := "Alleycats core") - .settings(libraryDependencies ++= Seq( - "org.typelevel" %% "export-hook" % "1.2.0" - )) + .settings( + libraryDependencies ++= Seq( + "org.typelevel" %% "export-hook" % "1.2.0" + ) + ) .settings(catsSettings) .settings(publishSettings) .settings(scoverageSettings) .settings(includeGeneratedSrc) .jsSettings(commonJsSettings) .jvmSettings(commonJvmSettings) - .settings(scalacOptions ~= {_.filterNot("-Ywarn-unused-import" == _)}) //export-hook triggers unused import - + .settings(scalacOptions ~= { _.filterNot("-Ywarn-unused-import" == _) }) //export-hook triggers unused import lazy val alleycatsCoreJVM = alleycatsCore.jvm lazy val alleycatsCoreJS = alleycatsCore.js @@ -498,23 +547,24 @@ lazy val alleycatsTests = crossProject(JSPlatform, JVMPlatform) lazy val alleycatsTestsJVM = alleycatsTests.jvm lazy val alleycatsTestsJS = alleycatsTests.js - // bench is currently JVM-only -lazy val bench = project.dependsOn(macrosJVM, coreJVM, freeJVM, lawsJVM) +lazy val bench = project + .dependsOn(macrosJVM, coreJVM, freeJVM, lawsJVM) .settings(moduleName := "cats-bench") .settings(catsSettings) .settings(noPublishSettings) .settings(commonJvmSettings) .settings(coverageEnabled := false) - .settings(libraryDependencies ++= Seq( - "org.scalaz" %% "scalaz-core" % "7.2.23", - "org.spire-math" %% "chain" % "0.3.0", - "co.fs2" %% "fs2-core" % "0.10.4" - )) + .settings( + libraryDependencies ++= Seq( + "org.scalaz" %% "scalaz-core" % "7.2.23", + "org.spire-math" %% "chain" % "0.3.0", + "co.fs2" %% "fs2-core" % "0.10.4" + ) + ) .enablePlugins(JmhPlugin) - lazy val binCompatTest = project .disablePlugins(CoursierPlugin) .settings(noPublishSettings) @@ -532,7 +582,6 @@ lazy val binCompatTest = project ) .dependsOn(coreJVM % Test) - // cats-js is JS-only lazy val js = project .dependsOn(macrosJS, coreJS, testsJS % "test-internal -> test") @@ -541,7 +590,6 @@ lazy val js = project .settings(commonJsSettings) .enablePlugins(ScalaJSPlugin) - // cats-jvm is JVM-only lazy val jvm = project .dependsOn(macrosJVM, coreJVM, testsJVM % "test-internal -> test") @@ -636,31 +684,23 @@ lazy val publishSettings = Seq( ) ) ++ credentialSettings ++ sharedPublishSettings ++ sharedReleaseProcess -// These aliases serialise the build for the benefit of Travis-CI. +// Scalafmt +addCommandAlias("fmt", "; compile:scalafmt; test:scalafmt; scalafmtSbt") +addCommandAlias("fmtCheck", "; compile:scalafmtCheck; test:scalafmtCheck; scalafmtSbtCheck") +// These aliases serialise the build for the benefit of Travis-CI. addCommandAlias("buildKernelJVM", ";kernelJVM/test;kernelLawsJVM/test") - addCommandAlias("buildCoreJVM", ";macrosJVM/test;coreJVM/test") - addCommandAlias("buildTestsJVM", ";lawsJVM/test;testkitJVM/test;testsJVM/test;jvm/test") - addCommandAlias("buildFreeJVM", ";freeJVM/test") - addCommandAlias("buildAlleycatsJVM", ";alleycatsCoreJVM/test;alleycatsLawsJVM/test;alleycatsTestsJVM/test") - addCommandAlias("buildJVM", ";buildKernelJVM;buildCoreJVM;buildTestsJVM;buildFreeJVM;buildAlleycatsJVM") - addCommandAlias("validateBC", ";binCompatTest/test;mimaReportBinaryIssues") - -addCommandAlias("validateJVM", ";scalastyle;buildJVM;bench/test;validateBC;makeMicrosite") - +addCommandAlias("validateJVM", ";buildJVM;bench/test;validateBC;makeMicrosite") addCommandAlias("validateJS", ";catsJS/compile;testsJS/test;js/test") - addCommandAlias("validateKernelJS", "kernelLawsJS/test") - addCommandAlias("validateFreeJS", "freeJS/test") //separated due to memory constraint on travis - -addCommandAlias("validate", ";clean;validateJS;validateKernelJS;validateFreeJS;validateJVM") +addCommandAlias("validate", ";clean;scalastyle;fmtCheck;validateJS;validateKernelJS;validateFreeJS;validateJVM") //////////////////////////////////////////////////////////////////////////////////////////////////// // Base Build Settings - Should not need to edit below this line. @@ -679,36 +719,41 @@ lazy val noPublishSettings = Seq( lazy val crossVersionSharedSources: Seq[Setting[_]] = Seq(Compile, Test).map { sc => (unmanagedSourceDirectories in sc) ++= { - (unmanagedSourceDirectories in sc ).value.map { - dir:File => new File(dir.getPath + "_" + scalaBinaryVersion.value) + (unmanagedSourceDirectories in sc).value.map { dir: File => + new File(dir.getPath + "_" + scalaBinaryVersion.value) } } } -def commonScalacOptions(scalaVersion: String) = Seq( - "-encoding", "UTF-8", - "-feature", - "-language:existentials", - "-language:higherKinds", - "-language:implicitConversions", - "-language:experimental.macros", - "-unchecked", - "-Ywarn-dead-code", - "-Ywarn-numeric-widen", - "-Ywarn-value-discard", - "-Xfuture" -) ++ (if(priorTo2_13(scalaVersion)) Seq( - "-Yno-adapted-args", - "-Xfatal-warnings", //todo: add the following two back to 2.13 - "-deprecation" -) else Seq( - "-Ymacro-annotations" -)) +def commonScalacOptions(scalaVersion: String) = + Seq( + "-encoding", + "UTF-8", + "-feature", + "-language:existentials", + "-language:higherKinds", + "-language:implicitConversions", + "-language:experimental.macros", + "-unchecked", + "-Ywarn-dead-code", + "-Ywarn-numeric-widen", + "-Ywarn-value-discard", + "-Xfuture" + ) ++ (if (priorTo2_13(scalaVersion)) + Seq( + "-Yno-adapted-args", + "-Xfatal-warnings", //todo: add the following two back to 2.13 + "-deprecation" + ) + else + Seq( + "-Ymacro-annotations" + )) def priorTo2_13(scalaVersion: String): Boolean = CrossVersion.partialVersion(scalaVersion) match { case Some((2, minor)) if minor < 13 => true - case _ => false + case _ => false } lazy val sharedPublishSettings = Seq( @@ -716,16 +761,16 @@ lazy val sharedPublishSettings = Seq( releaseTagName := tagName.value, releasePublishArtifactsAction := PgpKeys.publishSigned.value, releaseVcsSign := true, - useGpg := true, // bouncycastle has bugs with subkeys, so we use gpg instead + useGpg := true, // bouncycastle has bugs with subkeys, so we use gpg instead publishMavenStyle := true, publishArtifact in Test := false, pomIncludeRepository := Function.const(false), publishTo := { val nexus = "https://oss.sonatype.org/" if (isSnapshot.value) - Some("Snapshots" at nexus + "content/repositories/snapshots") + Some("Snapshots".at(nexus + "content/repositories/snapshots")) else - Some("Releases" at nexus + "service/local/staging/deploy/maven2") + Some("Releases".at(nexus + "service/local/staging/deploy/maven2")) } ) @@ -742,12 +787,13 @@ lazy val sharedReleaseProcess = Seq( setNextVersion, commitNextVersion, releaseStepCommand("sonatypeReleaseAll"), - pushChanges) + pushChanges + ) ) lazy val warnUnusedImport = Seq( scalacOptions ++= Seq("-Ywarn-unused-import"), - scalacOptions in (Compile, console) ~= {_.filterNot("-Ywarn-unused-import" == _)}, + scalacOptions in (Compile, console) ~= { _.filterNot("-Ywarn-unused-import" == _) }, scalacOptions in (Test, console) := (scalacOptions in (Compile, console)).value ) @@ -759,12 +805,11 @@ lazy val credentialSettings = Seq( } yield Credentials("Sonatype Nexus Repository Manager", "oss.sonatype.org", username, password)).toSeq ) - lazy val update2_12 = Seq( scalacOptions -= { CrossVersion.partialVersion(scalaVersion.value) match { case Some((2, scalaMajor)) if scalaMajor >= 12 => "-Yinline-warnings" - case _ => "" + case _ => "" } } ) @@ -773,7 +818,7 @@ lazy val xlint = Seq( scalacOptions += { CrossVersion.partialVersion(scalaVersion.value) match { case Some((2, scalaMajor)) if scalaMajor >= 12 => "-Xlint:-unused,_" - case _ => "-Xlint" + case _ => "-Xlint" } } ) diff --git a/core/src/main/scala-2.12-/cats/compat/SortedSet.scala b/core/src/main/scala-2.12-/cats/compat/SortedSet.scala index f732921b560..6bfe60fd500 100644 --- a/core/src/main/scala-2.12-/cats/compat/SortedSet.scala +++ b/core/src/main/scala-2.12-/cats/compat/SortedSet.scala @@ -3,7 +3,6 @@ package compat import scala.collection.immutable - private[cats] object SortedSet { def zipWithIndex[A](s: immutable.SortedSet[A])(implicit A: Ordering[A]): immutable.SortedSet[(A, Int)] = s.zipWithIndex diff --git a/core/src/main/scala/cats/Alternative.scala b/core/src/main/scala/cats/Alternative.scala index 126436115d9..b12070e4727 100644 --- a/core/src/main/scala/cats/Alternative.scala +++ b/core/src/main/scala/cats/Alternative.scala @@ -3,6 +3,7 @@ package cats import simulacrum.typeclass @typeclass trait Alternative[F[_]] extends Applicative[F] with MonoidK[F] { self => + /** * Fold over the inner structure to combine all of the values with * our combine method inherited from MonoidK. The result is for us @@ -24,16 +25,16 @@ import simulacrum.typeclass } /** - * Separate the inner foldable values into the "lefts" and "rights" - * - * Example: - * {{{ - * scala> import cats.implicits._ - * scala> val l: List[Either[String, Int]] = List(Right(1), Left("error")) - * scala> Alternative[List].separate(l) - * res0: (List[String], List[Int]) = (List(error),List(1)) - * }}} - */ + * Separate the inner foldable values into the "lefts" and "rights" + * + * Example: + * {{{ + * scala> import cats.implicits._ + * scala> val l: List[Either[String, Int]] = List(Right(1), Left("error")) + * scala> Alternative[List].separate(l) + * res0: (List[String], List[Int]) = (List(error),List(1)) + * }}} + */ def separate[G[_, _], A, B](fgab: F[G[A, B]])(implicit FM: Monad[F], G: Bifoldable[G]): (F[A], F[B]) = { val as = FM.flatMap(fgab)(gab => G.bifoldMap(gab)(pure, _ => empty[A])(algebra[A])) val bs = FM.flatMap(fgab)(gab => G.bifoldMap(gab)(_ => empty[B], pure)(algebra[B])) @@ -41,18 +42,18 @@ import simulacrum.typeclass } /** - * Return ().pure[F] if `condition` is true, `empty` otherwise - * - * Example: - * {{{ - * scala> import cats.implicits._ - * scala> def even(i: Int): Option[String] = Alternative[Option].guard(i % 2 == 0).as("even") - * scala> even(2) - * res0: Option[String] = Some(even) - * scala> even(3) - * res1: Option[String] = None - * }}} - */ + * Return ().pure[F] if `condition` is true, `empty` otherwise + * + * Example: + * {{{ + * scala> import cats.implicits._ + * scala> def even(i: Int): Option[String] = Alternative[Option].guard(i % 2 == 0).as("even") + * scala> even(2) + * res0: Option[String] = Some(even) + * scala> even(3) + * res1: Option[String] = None + * }}} + */ def guard(condition: Boolean): F[Unit] = if (condition) unit else empty diff --git a/core/src/main/scala/cats/Applicative.scala b/core/src/main/scala/cats/Applicative.scala index fd9d0c6b0c2..bd9918c0eb4 100644 --- a/core/src/main/scala/cats/Applicative.scala +++ b/core/src/main/scala/cats/Applicative.scala @@ -5,86 +5,84 @@ import cats.instances.list._ import simulacrum.typeclass /** - * Applicative functor. - * - * Allows application of a function in an Applicative context to a value in an Applicative context - * - * See: [[https://www.cs.ox.ac.uk/jeremy.gibbons/publications/iterator.pdf The Essence of the Iterator Pattern]] - * Also: [[http://staff.city.ac.uk/~ross/papers/Applicative.pdf Applicative programming with effects]] - * - * Must obey the laws defined in cats.laws.ApplicativeLaws. - */ + * Applicative functor. + * + * Allows application of a function in an Applicative context to a value in an Applicative context + * + * See: [[https://www.cs.ox.ac.uk/jeremy.gibbons/publications/iterator.pdf The Essence of the Iterator Pattern]] + * Also: [[http://staff.city.ac.uk/~ross/papers/Applicative.pdf Applicative programming with effects]] + * + * Must obey the laws defined in cats.laws.ApplicativeLaws. + */ @typeclass trait Applicative[F[_]] extends Apply[F] with InvariantMonoidal[F] { self => - - /** - * `pure` lifts any value into the Applicative Functor. - * - * Example: - * {{{ - * scala> import cats.implicits._ - * - * scala> Applicative[Option].pure(10) - * res0: Option[Int] = Some(10) - * }}} - */ + * `pure` lifts any value into the Applicative Functor. + * + * Example: + * {{{ + * scala> import cats.implicits._ + * + * scala> Applicative[Option].pure(10) + * res0: Option[Int] = Some(10) + * }}} + */ def pure[A](x: A): F[A] /** - * Returns an `F[Unit]` value, equivalent with `pure(())`. - * - * A useful shorthand, also allowing implementations to optimize the - * returned reference (e.g. it can be a `val`). - * - * Example: - * {{{ - * scala> import cats.implicits._ - * - * scala> Applicative[Option].unit - * res0: Option[Unit] = Some(()) - * }}} - */ + * Returns an `F[Unit]` value, equivalent with `pure(())`. + * + * A useful shorthand, also allowing implementations to optimize the + * returned reference (e.g. it can be a `val`). + * + * Example: + * {{{ + * scala> import cats.implicits._ + * + * scala> Applicative[Option].unit + * res0: Option[Unit] = Some(()) + * }}} + */ def unit: F[Unit] = pure(()) override def map[A, B](fa: F[A])(f: A => B): F[B] = ap(pure(f))(fa) /** - * Given `fa` and `n`, apply `fa` `n` times to construct an `F[List[A]]` value. - * - * Example: - * {{{ - * scala> import cats.data.State - * - * scala> type Counter[A] = State[Int, A] - * scala> val getAndIncrement: Counter[Int] = State { i => (i + 1, i) } - * scala> val getAndIncrement5: Counter[List[Int]] = - * | Applicative[Counter].replicateA(5, getAndIncrement) - * scala> getAndIncrement5.run(0).value - * res0: (Int, List[Int]) = (5,List(0, 1, 2, 3, 4)) - * }}} - */ + * Given `fa` and `n`, apply `fa` `n` times to construct an `F[List[A]]` value. + * + * Example: + * {{{ + * scala> import cats.data.State + * + * scala> type Counter[A] = State[Int, A] + * scala> val getAndIncrement: Counter[Int] = State { i => (i + 1, i) } + * scala> val getAndIncrement5: Counter[List[Int]] = + * | Applicative[Counter].replicateA(5, getAndIncrement) + * scala> getAndIncrement5.run(0).value + * res0: (Int, List[Int]) = (5,List(0, 1, 2, 3, 4)) + * }}} + */ def replicateA[A](n: Int, fa: F[A]): F[List[A]] = Traverse[List].sequence(List.fill(n)(fa))(this) /** - * Compose an `Applicative[F]` and an `Applicative[G]` into an - * `Applicative[λ[α => F[G[α]]]]`. - * - * Example: - * {{{ - * scala> import cats.implicits._ - * - * scala> val alo = Applicative[List].compose[Option] - * - * scala> alo.pure(3) - * res0: List[Option[Int]] = List(Some(3)) - * - * scala> alo.product(List(None, Some(true), Some(false)), List(Some(2), None)) - * res1: List[Option[(Boolean, Int)]] = List(None, None, Some((true,2)), None, Some((false,2)), None) - * }}} - */ + * Compose an `Applicative[F]` and an `Applicative[G]` into an + * `Applicative[λ[α => F[G[α]]]]`. + * + * Example: + * {{{ + * scala> import cats.implicits._ + * + * scala> val alo = Applicative[List].compose[Option] + * + * scala> alo.pure(3) + * res0: List[Option[Int]] = List(Some(3)) + * + * scala> alo.product(List(None, Some(true), Some(false)), List(Some(2), None)) + * res1: List[Option[(Boolean, Int)]] = List(None, None, Some((true,2)), None, Some((false,2)), None) + * }}} + */ def compose[G[_]: Applicative]: Applicative[λ[α => F[G[α]]]] = new ComposedApplicative[F, G] { val F = self @@ -92,47 +90,47 @@ import simulacrum.typeclass } /** - * Compose an `Applicative[F]` and a `ContravariantMonoidal[G]` into a - * `ContravariantMonoidal[λ[α => F[G[α]]]]`. - * - * Example: - * {{{ - * scala> import cats.kernel.Comparison - * scala> import cats.implicits._ - * - * // compares strings by alphabetical order - * scala> val alpha: Order[String] = Order[String] - * - * // compares strings by their length - * scala> val strLength: Order[String] = Order.by[String, Int](_.length) - * - * scala> val stringOrders: List[Order[String]] = List(alpha, strLength) - * - * // first comparison is with alpha order, second is with string length - * scala> stringOrders.map(o => o.comparison("abc", "de")) - * res0: List[Comparison] = List(LessThan, GreaterThan) - * - * scala> val le = Applicative[List].composeContravariantMonoidal[Order] - * - * // create Int orders that convert ints to strings and then use the string orders - * scala> val intOrders: List[Order[Int]] = le.contramap(stringOrders)(_.toString) - * - * // first comparison is with alpha order, second is with string length - * scala> intOrders.map(o => o.comparison(12, 3)) - * res1: List[Comparison] = List(LessThan, GreaterThan) - * - * // create the `product` of the string order list and the int order list - * // `p` contains a list of the following orders: - * // 1. (alpha comparison on strings followed by alpha comparison on ints) - * // 2. (alpha comparison on strings followed by length comparison on ints) - * // 3. (length comparison on strings followed by alpha comparison on ints) - * // 4. (length comparison on strings followed by length comparison on ints) - * scala> val p: List[Order[(String, Int)]] = le.product(stringOrders, intOrders) - * - * scala> p.map(o => o.comparison(("abc", 12), ("def", 3))) - * res2: List[Comparison] = List(LessThan, LessThan, LessThan, GreaterThan) - * }}} - */ + * Compose an `Applicative[F]` and a `ContravariantMonoidal[G]` into a + * `ContravariantMonoidal[λ[α => F[G[α]]]]`. + * + * Example: + * {{{ + * scala> import cats.kernel.Comparison + * scala> import cats.implicits._ + * + * // compares strings by alphabetical order + * scala> val alpha: Order[String] = Order[String] + * + * // compares strings by their length + * scala> val strLength: Order[String] = Order.by[String, Int](_.length) + * + * scala> val stringOrders: List[Order[String]] = List(alpha, strLength) + * + * // first comparison is with alpha order, second is with string length + * scala> stringOrders.map(o => o.comparison("abc", "de")) + * res0: List[Comparison] = List(LessThan, GreaterThan) + * + * scala> val le = Applicative[List].composeContravariantMonoidal[Order] + * + * // create Int orders that convert ints to strings and then use the string orders + * scala> val intOrders: List[Order[Int]] = le.contramap(stringOrders)(_.toString) + * + * // first comparison is with alpha order, second is with string length + * scala> intOrders.map(o => o.comparison(12, 3)) + * res1: List[Comparison] = List(LessThan, GreaterThan) + * + * // create the `product` of the string order list and the int order list + * // `p` contains a list of the following orders: + * // 1. (alpha comparison on strings followed by alpha comparison on ints) + * // 2. (alpha comparison on strings followed by length comparison on ints) + * // 3. (length comparison on strings followed by alpha comparison on ints) + * // 4. (length comparison on strings followed by length comparison on ints) + * scala> val p: List[Order[(String, Int)]] = le.product(stringOrders, intOrders) + * + * scala> p.map(o => o.comparison(("abc", 12), ("def", 3))) + * res2: List[Comparison] = List(LessThan, LessThan, LessThan, GreaterThan) + * }}} + */ def composeContravariantMonoidal[G[_]: ContravariantMonoidal]: ContravariantMonoidal[λ[α => F[G[α]]]] = new ComposedApplicativeContravariantMonoidal[F, G] { val F = self @@ -140,50 +138,50 @@ import simulacrum.typeclass } /** - * Returns the given argument (mapped to Unit) if `cond` is `false`, - * otherwise, unit lifted into F. - * - * Example: - * {{{ - * scala> import cats.implicits._ - * - * scala> Applicative[List].unlessA(true)(List(1, 2, 3)) - * res0: List[Unit] = List(()) - * - * scala> Applicative[List].unlessA(false)(List(1, 2, 3)) - * res1: List[Unit] = List((), (), ()) - * - * scala> Applicative[List].unlessA(true)(List.empty[Int]) - * res2: List[Unit] = List(()) - * - * scala> Applicative[List].unlessA(false)(List.empty[Int]) - * res3: List[Unit] = List() - * }}} - */ + * Returns the given argument (mapped to Unit) if `cond` is `false`, + * otherwise, unit lifted into F. + * + * Example: + * {{{ + * scala> import cats.implicits._ + * + * scala> Applicative[List].unlessA(true)(List(1, 2, 3)) + * res0: List[Unit] = List(()) + * + * scala> Applicative[List].unlessA(false)(List(1, 2, 3)) + * res1: List[Unit] = List((), (), ()) + * + * scala> Applicative[List].unlessA(true)(List.empty[Int]) + * res2: List[Unit] = List(()) + * + * scala> Applicative[List].unlessA(false)(List.empty[Int]) + * res3: List[Unit] = List() + * }}} + */ def unlessA[A](cond: Boolean)(f: => F[A]): F[Unit] = if (cond) unit else void(f) /** - * Returns the given argument (mapped to Unit) if `cond` is `true`, otherwise, - * unit lifted into F. - * - * Example: - * {{{ - * scala> import cats.implicits._ - * - * scala> Applicative[List].whenA(true)(List(1, 2, 3)) - * res0: List[Unit] = List((), (), ()) - * - * scala> Applicative[List].whenA(false)(List(1, 2, 3)) - * res1: List[Unit] = List(()) - * - * scala> Applicative[List].whenA(true)(List.empty[Int]) - * res2: List[Unit] = List() - * - * scala> Applicative[List].whenA(false)(List.empty[Int]) - * res3: List[Unit] = List(()) - * }}} - */ + * Returns the given argument (mapped to Unit) if `cond` is `true`, otherwise, + * unit lifted into F. + * + * Example: + * {{{ + * scala> import cats.implicits._ + * + * scala> Applicative[List].whenA(true)(List(1, 2, 3)) + * res0: List[Unit] = List((), (), ()) + * + * scala> Applicative[List].whenA(false)(List(1, 2, 3)) + * res1: List[Unit] = List(()) + * + * scala> Applicative[List].whenA(true)(List.empty[Int]) + * res2: List[Unit] = List() + * + * scala> Applicative[List].whenA(false)(List.empty[Int]) + * res3: List[Unit] = List(()) + * }}} + */ def whenA[A](cond: Boolean)(f: => F[A]): F[Unit] = if (cond) void(f) else unit @@ -194,38 +192,37 @@ object Applicative { new ApplicativeMonoid[F, A](f, monoid) /** - * Creates an applicative functor for `F`, holding domain fixed and combining - * over the codomain. - * - * Example: - * {{{ - * scala> import cats.implicits._ - * scala> import cats.Applicative.catsApplicativeForArrow - * scala> val toLong: Int => Long = _.toLong - * scala> val double: Int => Int = 2*_ - * scala> val f: Int => (Long, Int) = catsApplicativeForArrow.product(toLong, double) - * scala> f(3) - * res0: (Long, Int) = (3,6) - * }}} - */ + * Creates an applicative functor for `F`, holding domain fixed and combining + * over the codomain. + * + * Example: + * {{{ + * scala> import cats.implicits._ + * scala> import cats.Applicative.catsApplicativeForArrow + * scala> val toLong: Int => Long = _.toLong + * scala> val double: Int => Int = 2*_ + * scala> val f: Int => (Long, Int) = catsApplicativeForArrow.product(toLong, double) + * scala> f(3) + * res0: (Long, Int) = (3,6) + * }}} + */ implicit def catsApplicativeForArrow[F[_, _], A](implicit F: Arrow[F]): Applicative[F[A, ?]] = new ArrowApplicative[F, A](F) - /** - * Creates a CoflatMap for an Applicative `F`. - * Cannot be implicit in 1.0 for Binary Compatibility Reasons - * - * Example: - * {{{ - * scala> import cats._ - * scala> import cats.implicits._ - * scala> val fa = Some(3) - * fa: Option[Int] = Some(3) - * scala> Applicative.coflatMap[Option].coflatten(fa) - * res0: Option[Option[Int]] = Some(Some(3)) - * }}} - */ + * Creates a CoflatMap for an Applicative `F`. + * Cannot be implicit in 1.0 for Binary Compatibility Reasons + * + * Example: + * {{{ + * scala> import cats._ + * scala> import cats.implicits._ + * scala> val fa = Some(3) + * fa: Option[Int] = Some(3) + * scala> Applicative.coflatMap[Option].coflatten(fa) + * res0: Option[Option[Int]] = Some(Some(3)) + * }}} + */ def coflatMap[F[_]](implicit F: Applicative[F]): CoflatMap[F] = new CoflatMap[F] { def coflatMap[A, B](fa: F[A])(f: F[A] => B): F[B] = F.pure(f(fa)) @@ -234,7 +231,9 @@ object Applicative { } -private[cats] class ApplicativeMonoid[F[_], A](f: Applicative[F], monoid: Monoid[A]) extends ApplySemigroup(f, monoid) with Monoid[F[A]] { +private[cats] class ApplicativeMonoid[F[_], A](f: Applicative[F], monoid: Monoid[A]) + extends ApplySemigroup(f, monoid) + with Monoid[F[A]] { def empty: F[A] = f.pure(monoid.empty) } diff --git a/core/src/main/scala/cats/ApplicativeError.scala b/core/src/main/scala/cats/ApplicativeError.scala index 5b0dc72b082..0393e8739a3 100644 --- a/core/src/main/scala/cats/ApplicativeError.scala +++ b/core/src/main/scala/cats/ApplicativeError.scala @@ -1,139 +1,137 @@ package cats import cats.data.EitherT -import scala.util.{ Failure, Success, Try } +import scala.util.{Failure, Success, Try} import scala.util.control.NonFatal /** - * An applicative that also allows you to raise and or handle an error value. - * - * This type class allows one to abstract over error-handling applicatives. - */ + * An applicative that also allows you to raise and or handle an error value. + * + * This type class allows one to abstract over error-handling applicatives. + */ trait ApplicativeError[F[_], E] extends Applicative[F] { /** - * Lift an error into the `F` context. - * - * Example: - * {{{ - * scala> import cats.implicits._ - * - * // integer-rounded division - * scala> def divide[F[_]](dividend: Int, divisor: Int)(implicit F: ApplicativeError[F, String]): F[Int] = - * | if (divisor === 0) F.raiseError("division by zero") - * | else F.pure(dividend / divisor) - * - * scala> type ErrorOr[A] = Either[String, A] - * - * scala> divide[ErrorOr](6, 3) - * res0: ErrorOr[Int] = Right(2) - * - * scala> divide[ErrorOr](6, 0) - * res1: ErrorOr[Int] = Left(division by zero) - * }}} - */ + * Lift an error into the `F` context. + * + * Example: + * {{{ + * scala> import cats.implicits._ + * + * // integer-rounded division + * scala> def divide[F[_]](dividend: Int, divisor: Int)(implicit F: ApplicativeError[F, String]): F[Int] = + * | if (divisor === 0) F.raiseError("division by zero") + * | else F.pure(dividend / divisor) + * + * scala> type ErrorOr[A] = Either[String, A] + * + * scala> divide[ErrorOr](6, 3) + * res0: ErrorOr[Int] = Right(2) + * + * scala> divide[ErrorOr](6, 0) + * res1: ErrorOr[Int] = Left(division by zero) + * }}} + */ def raiseError[A](e: E): F[A] /** - * Handle any error, potentially recovering from it, by mapping it to an - * `F[A]` value. - * - * @see [[handleError]] to handle any error by simply mapping it to an `A` - * value instead of an `F[A]`. - * - * @see [[recoverWith]] to recover from only certain errors. - */ + * Handle any error, potentially recovering from it, by mapping it to an + * `F[A]` value. + * + * @see [[handleError]] to handle any error by simply mapping it to an `A` + * value instead of an `F[A]`. + * + * @see [[recoverWith]] to recover from only certain errors. + */ def handleErrorWith[A](fa: F[A])(f: E => F[A]): F[A] /** - * Handle any error, by mapping it to an `A` value. - * - * @see [[handleErrorWith]] to map to an `F[A]` value instead of simply an - * `A` value. - * - * @see [[recover]] to only recover from certain errors. - */ - def handleError[A](fa: F[A])(f: E => A): F[A] = handleErrorWith(fa)(f andThen pure) + * Handle any error, by mapping it to an `A` value. + * + * @see [[handleErrorWith]] to map to an `F[A]` value instead of simply an + * `A` value. + * + * @see [[recover]] to only recover from certain errors. + */ + def handleError[A](fa: F[A])(f: E => A): F[A] = handleErrorWith(fa)(f.andThen(pure)) /** - * Handle errors by turning them into [[scala.util.Either]] values. - * - * If there is no error, then an `scala.util.Right` value will be returned instead. - * - * All non-fatal errors should be handled by this method. - */ - def attempt[A](fa: F[A]): F[Either[E, A]] = handleErrorWith( - map(fa)(Right(_): Either[E, A]) - )(e => pure(Left(e))) + * Handle errors by turning them into [[scala.util.Either]] values. + * + * If there is no error, then an `scala.util.Right` value will be returned instead. + * + * All non-fatal errors should be handled by this method. + */ + def attempt[A](fa: F[A]): F[Either[E, A]] = + handleErrorWith( + map(fa)(Right(_): Either[E, A]) + )(e => pure(Left(e))) /** - * Similar to [[attempt]], but wraps the result in a [[cats.data.EitherT]] for - * convenience. - */ + * Similar to [[attempt]], but wraps the result in a [[cats.data.EitherT]] for + * convenience. + */ def attemptT[A](fa: F[A]): EitherT[F, E, A] = EitherT(attempt(fa)) /** - * Recover from certain errors by mapping them to an `A` value. - * - * @see [[handleError]] to handle any/all errors. - * - * @see [[recoverWith]] to recover from certain errors by mapping them to - * `F[A]` values. - */ + * Recover from certain errors by mapping them to an `A` value. + * + * @see [[handleError]] to handle any/all errors. + * + * @see [[recoverWith]] to recover from certain errors by mapping them to + * `F[A]` values. + */ def recover[A](fa: F[A])(pf: PartialFunction[E, A]): F[A] = - handleErrorWith(fa)(e => - (pf andThen pure) applyOrElse(e, raiseError)) + handleErrorWith(fa)(e => (pf.andThen(pure)).applyOrElse(e, raiseError)) /** - * Recover from certain errors by mapping them to an `F[A]` value. - * - * @see [[handleErrorWith]] to handle any/all errors. - * - * @see [[recover]] to recover from certain errors by mapping them to `A` - * values. - */ + * Recover from certain errors by mapping them to an `F[A]` value. + * + * @see [[handleErrorWith]] to handle any/all errors. + * + * @see [[recover]] to recover from certain errors by mapping them to `A` + * values. + */ def recoverWith[A](fa: F[A])(pf: PartialFunction[E, F[A]]): F[A] = - handleErrorWith(fa)(e => - pf applyOrElse(e, raiseError)) + handleErrorWith(fa)(e => pf.applyOrElse(e, raiseError)) /** - * Execute a callback on certain errors, then rethrow them. - * Any non matching error is rethrown as well. - * - * In the following example, only one of the errors is logged, - * but they are both rethrown, to be possibly handled by another - * layer of the program: - * - * {{{ - * scala> import cats._, data._, implicits._ - * - * scala> case class Err(msg: String) - * - * scala> type F[A] = EitherT[State[String, ?], Err, A] - * - * scala> val action: PartialFunction[Err, F[Unit]] = { - * | case Err("one") => EitherT.liftF(State.set("one")) - * | } - * - * scala> val prog1: F[Int] = (Err("one")).raiseError[F, Int] - * scala> val prog2: F[Int] = (Err("two")).raiseError[F, Int] - * - * scala> prog1.onError(action).value.run("").value - - * res0: (String, Either[Err,Int]) = (one,Left(Err(one))) - * - * scala> prog2.onError(action).value.run("").value - * res1: (String, Either[Err,Int]) = ("",Left(Err(two))) - * }}} - */ + * Execute a callback on certain errors, then rethrow them. + * Any non matching error is rethrown as well. + * + * In the following example, only one of the errors is logged, + * but they are both rethrown, to be possibly handled by another + * layer of the program: + * + * {{{ + * scala> import cats._, data._, implicits._ + * + * scala> case class Err(msg: String) + * + * scala> type F[A] = EitherT[State[String, ?], Err, A] + * + * scala> val action: PartialFunction[Err, F[Unit]] = { + * | case Err("one") => EitherT.liftF(State.set("one")) + * | } + * + * scala> val prog1: F[Int] = (Err("one")).raiseError[F, Int] + * scala> val prog2: F[Int] = (Err("two")).raiseError[F, Int] + * + * scala> prog1.onError(action).value.run("").value + + * res0: (String, Either[Err,Int]) = (one,Left(Err(one))) + * + * scala> prog2.onError(action).value.run("").value + * res1: (String, Either[Err,Int]) = ("",Left(Err(two))) + * }}} + */ def onError[A](fa: F[A])(pf: PartialFunction[E, F[Unit]]): F[A] = - handleErrorWith(fa)(e => - (pf andThen (map2(_, raiseError[A](e))((_, b) => b))) applyOrElse(e, raiseError)) + handleErrorWith(fa)(e => (pf.andThen(map2(_, raiseError[A](e))((_, b) => b))).applyOrElse(e, raiseError)) /** - * Often E is Throwable. Here we try to call pure or catch - * and raise. - */ + * Often E is Throwable. Here we try to call pure or catch + * and raise. + */ def catchNonFatal[A](a: => A)(implicit ev: Throwable <:< E): F[A] = try pure(a) catch { @@ -141,9 +139,9 @@ trait ApplicativeError[F[_], E] extends Applicative[F] { } /** - * Often E is Throwable. Here we try to call pure or catch - * and raise - */ + * Often E is Throwable. Here we try to call pure or catch + * and raise + */ def catchNonFatalEval[A](a: Eval[A])(implicit ev: Throwable <:< E): F[A] = try pure(a.value) catch { @@ -151,8 +149,8 @@ trait ApplicativeError[F[_], E] extends Applicative[F] { } /** - * If the error type is Throwable, we can convert from a scala.util.Try - */ + * If the error type is Throwable, we can convert from a scala.util.Try + */ def fromTry[A](t: Try[A])(implicit ev: Throwable <:< E): F[A] = t match { case Success(a) => pure(a) @@ -160,41 +158,39 @@ trait ApplicativeError[F[_], E] extends Applicative[F] { } /** - * Convert from scala.Either - * - * Example: - * {{{ - * scala> import cats.ApplicativeError - * scala> import cats.instances.option._ - * - * scala> ApplicativeError[Option, Unit].fromEither(Right(1)) - * res0: scala.Option[Int] = Some(1) - * - * scala> ApplicativeError[Option, Unit].fromEither(Left(())) - * res1: scala.Option[Nothing] = None - * }}} - */ + * Convert from scala.Either + * + * Example: + * {{{ + * scala> import cats.ApplicativeError + * scala> import cats.instances.option._ + * + * scala> ApplicativeError[Option, Unit].fromEither(Right(1)) + * res0: scala.Option[Int] = Some(1) + * + * scala> ApplicativeError[Option, Unit].fromEither(Left(())) + * res1: scala.Option[Nothing] = None + * }}} + */ def fromEither[A](x: E Either A): F[A] = x match { case Right(a) => pure(a) case Left(e) => raiseError(e) } - } object ApplicativeError { def apply[F[_], E](implicit F: ApplicativeError[F, E]): ApplicativeError[F, E] = F - private[cats] final class LiftFromOptionPartially[F[_]](val dummy: Boolean = true) extends AnyVal { + final private[cats] class LiftFromOptionPartially[F[_]](val dummy: Boolean = true) extends AnyVal { def apply[E, A](oa: Option[A], ifEmpty: => E)(implicit F: ApplicativeError[F, _ >: E]): F[A] = oa match { case Some(a) => F.pure(a) - case None => F.raiseError(ifEmpty) + case None => F.raiseError(ifEmpty) } } - /** * lift from scala.Option[A] to a F[A] * diff --git a/core/src/main/scala/cats/Apply.scala b/core/src/main/scala/cats/Apply.scala index 20780da9a20..2e24d339152 100644 --- a/core/src/main/scala/cats/Apply.scala +++ b/core/src/main/scala/cats/Apply.scala @@ -4,107 +4,107 @@ import simulacrum.typeclass import simulacrum.noop /** - * Weaker version of Applicative[F]; has apply but not pure. - * - * Must obey the laws defined in cats.laws.ApplyLaws. - */ + * Weaker version of Applicative[F]; has apply but not pure. + * + * Must obey the laws defined in cats.laws.ApplyLaws. + */ @typeclass(excludeParents = List("ApplyArityFunctions")) trait Apply[F[_]] extends Functor[F] with InvariantSemigroupal[F] with ApplyArityFunctions[F] { self => /** - * Given a value and a function in the Apply context, applies the - * function to the value. - * - * Example: - * {{{ - * scala> import cats.implicits._ - * - * scala> val someF: Option[Int => Long] = Some(_.toLong + 1L) - * scala> val noneF: Option[Int => Long] = None - * scala> val someInt: Option[Int] = Some(3) - * scala> val noneInt: Option[Int] = None - * - * scala> Apply[Option].ap(someF)(someInt) - * res0: Option[Long] = Some(4) - * - * scala> Apply[Option].ap(noneF)(someInt) - * res1: Option[Long] = None - * - * scala> Apply[Option].ap(someF)(noneInt) - * res2: Option[Long] = None - * - * scala> Apply[Option].ap(noneF)(noneInt) - * res3: Option[Long] = None - * }}} - */ + * Given a value and a function in the Apply context, applies the + * function to the value. + * + * Example: + * {{{ + * scala> import cats.implicits._ + * + * scala> val someF: Option[Int => Long] = Some(_.toLong + 1L) + * scala> val noneF: Option[Int => Long] = None + * scala> val someInt: Option[Int] = Some(3) + * scala> val noneInt: Option[Int] = None + * + * scala> Apply[Option].ap(someF)(someInt) + * res0: Option[Long] = Some(4) + * + * scala> Apply[Option].ap(noneF)(someInt) + * res1: Option[Long] = None + * + * scala> Apply[Option].ap(someF)(noneInt) + * res2: Option[Long] = None + * + * scala> Apply[Option].ap(noneF)(noneInt) + * res3: Option[Long] = None + * }}} + */ def ap[A, B](ff: F[A => B])(fa: F[A]): F[B] /** - * Compose two actions, discarding any value produced by the first. - * - * @see [[productL]] to discard the value of the second instead. - * - * Example: - * {{{ - * scala> import cats.implicits._ - * scala> import cats.data.Validated - * scala> import Validated.{Valid, Invalid} - * - * scala> type ErrOr[A] = Validated[String, A] - * - * scala> val validInt: ErrOr[Int] = Valid(3) - * scala> val validBool: ErrOr[Boolean] = Valid(true) - * scala> val invalidInt: ErrOr[Int] = Invalid("Invalid int.") - * scala> val invalidBool: ErrOr[Boolean] = Invalid("Invalid boolean.") - * - * scala> Apply[ErrOr].productR(validInt)(validBool) - * res0: ErrOr[Boolean] = Valid(true) - * - * scala> Apply[ErrOr].productR(invalidInt)(validBool) - * res1: ErrOr[Boolean] = Invalid(Invalid int.) - * - * scala> Apply[ErrOr].productR(validInt)(invalidBool) - * res2: ErrOr[Boolean] = Invalid(Invalid boolean.) - * - * scala> Apply[ErrOr].productR(invalidInt)(invalidBool) - * res3: ErrOr[Boolean] = Invalid(Invalid int.Invalid boolean.) - * }}} - * - */ + * Compose two actions, discarding any value produced by the first. + * + * @see [[productL]] to discard the value of the second instead. + * + * Example: + * {{{ + * scala> import cats.implicits._ + * scala> import cats.data.Validated + * scala> import Validated.{Valid, Invalid} + * + * scala> type ErrOr[A] = Validated[String, A] + * + * scala> val validInt: ErrOr[Int] = Valid(3) + * scala> val validBool: ErrOr[Boolean] = Valid(true) + * scala> val invalidInt: ErrOr[Int] = Invalid("Invalid int.") + * scala> val invalidBool: ErrOr[Boolean] = Invalid("Invalid boolean.") + * + * scala> Apply[ErrOr].productR(validInt)(validBool) + * res0: ErrOr[Boolean] = Valid(true) + * + * scala> Apply[ErrOr].productR(invalidInt)(validBool) + * res1: ErrOr[Boolean] = Invalid(Invalid int.) + * + * scala> Apply[ErrOr].productR(validInt)(invalidBool) + * res2: ErrOr[Boolean] = Invalid(Invalid boolean.) + * + * scala> Apply[ErrOr].productR(invalidInt)(invalidBool) + * res3: ErrOr[Boolean] = Invalid(Invalid int.Invalid boolean.) + * }}} + * + */ def productR[A, B](fa: F[A])(fb: F[B]): F[B] = map2(fa, fb)((_, b) => b) /** - * Compose two actions, discarding any value produced by the second. - * - * @see [[productR]] to discard the value of the first instead. - * - * Example: - * {{{ - * scala> import cats.implicits._ - * scala> import cats.data.Validated - * scala> import Validated.{Valid, Invalid} - * - * scala> type ErrOr[A] = Validated[String, A] - * - * scala> val validInt: ErrOr[Int] = Valid(3) - * scala> val validBool: ErrOr[Boolean] = Valid(true) - * scala> val invalidInt: ErrOr[Int] = Invalid("Invalid int.") - * scala> val invalidBool: ErrOr[Boolean] = Invalid("Invalid boolean.") - * - * scala> Apply[ErrOr].productL(validInt)(validBool) - * res0: ErrOr[Int] = Valid(3) - * - * scala> Apply[ErrOr].productL(invalidInt)(validBool) - * res1: ErrOr[Int] = Invalid(Invalid int.) - * - * scala> Apply[ErrOr].productL(validInt)(invalidBool) - * res2: ErrOr[Int] = Invalid(Invalid boolean.) - * - * scala> Apply[ErrOr].productL(invalidInt)(invalidBool) - * res3: ErrOr[Int] = Invalid(Invalid int.Invalid boolean.) - * }}} - */ + * Compose two actions, discarding any value produced by the second. + * + * @see [[productR]] to discard the value of the first instead. + * + * Example: + * {{{ + * scala> import cats.implicits._ + * scala> import cats.data.Validated + * scala> import Validated.{Valid, Invalid} + * + * scala> type ErrOr[A] = Validated[String, A] + * + * scala> val validInt: ErrOr[Int] = Valid(3) + * scala> val validBool: ErrOr[Boolean] = Valid(true) + * scala> val invalidInt: ErrOr[Int] = Invalid("Invalid int.") + * scala> val invalidBool: ErrOr[Boolean] = Invalid("Invalid boolean.") + * + * scala> Apply[ErrOr].productL(validInt)(validBool) + * res0: ErrOr[Int] = Valid(3) + * + * scala> Apply[ErrOr].productL(invalidInt)(validBool) + * res1: ErrOr[Int] = Invalid(Invalid int.) + * + * scala> Apply[ErrOr].productL(validInt)(invalidBool) + * res2: ErrOr[Int] = Invalid(Invalid boolean.) + * + * scala> Apply[ErrOr].productL(invalidInt)(invalidBool) + * res3: ErrOr[Int] = Invalid(Invalid int.Invalid boolean.) + * }}} + */ def productL[A, B](fa: F[A])(fb: F[B]): F[A] = map2(fa, fb)((a, _) => a) @@ -134,79 +134,79 @@ trait Apply[F[_]] extends Functor[F] with InvariantSemigroupal[F] with ApplyArit productL(fa)(fb) /** - * ap2 is a binary version of ap, defined in terms of ap. - */ + * ap2 is a binary version of ap, defined in terms of ap. + */ def ap2[A, B, Z](ff: F[(A, B) => Z])(fa: F[A], fb: F[B]): F[Z] = map(product(fa, product(fb, ff))) { case (a, (b, f)) => f(a, b) } /** - * Applies the pure (binary) function f to the effectful values fa and fb. - * - * map2 can be seen as a binary version of [[cats.Functor]]#map. - * - * Example: - * {{{ - * scala> import cats.implicits._ - * - * scala> val someInt: Option[Int] = Some(3) - * scala> val noneInt: Option[Int] = None - * scala> val someLong: Option[Long] = Some(4L) - * scala> val noneLong: Option[Long] = None - * - * scala> Apply[Option].map2(someInt, someLong)((i, l) => i.toString + l.toString) - * res0: Option[String] = Some(34) - * - * scala> Apply[Option].map2(someInt, noneLong)((i, l) => i.toString + l.toString) - * res0: Option[String] = None - * - * scala> Apply[Option].map2(noneInt, noneLong)((i, l) => i.toString + l.toString) - * res0: Option[String] = None - * - * scala> Apply[Option].map2(noneInt, someLong)((i, l) => i.toString + l.toString) - * res0: Option[String] = None - * }}} - */ + * Applies the pure (binary) function f to the effectful values fa and fb. + * + * map2 can be seen as a binary version of [[cats.Functor]]#map. + * + * Example: + * {{{ + * scala> import cats.implicits._ + * + * scala> val someInt: Option[Int] = Some(3) + * scala> val noneInt: Option[Int] = None + * scala> val someLong: Option[Long] = Some(4L) + * scala> val noneLong: Option[Long] = None + * + * scala> Apply[Option].map2(someInt, someLong)((i, l) => i.toString + l.toString) + * res0: Option[String] = Some(34) + * + * scala> Apply[Option].map2(someInt, noneLong)((i, l) => i.toString + l.toString) + * res0: Option[String] = None + * + * scala> Apply[Option].map2(noneInt, noneLong)((i, l) => i.toString + l.toString) + * res0: Option[String] = None + * + * scala> Apply[Option].map2(noneInt, someLong)((i, l) => i.toString + l.toString) + * res0: Option[String] = None + * }}} + */ def map2[A, B, Z](fa: F[A], fb: F[B])(f: (A, B) => Z): F[Z] = map(product(fa, fb))(f.tupled) /** - * Similar to [[map2]] but uses [[Eval]] to allow for laziness in the `F[B]` - * argument. This can allow for "short-circuiting" of computations. - * - * NOTE: the default implementation of `map2Eval` does not short-circuit - * computations. For data structures that can benefit from laziness, [[Apply]] - * instances should override this method. - * - * In the following example, `x.map2(bomb)(_ + _)` would result in an error, - * but `map2Eval` "short-circuits" the computation. `x` is `None` and thus the - * result of `bomb` doesn't even need to be evaluated in order to determine - * that the result of `map2Eval` should be `None`. - * - * {{{ - * scala> import cats.{Eval, Later} - * scala> import cats.implicits._ - * scala> val bomb: Eval[Option[Int]] = Later(sys.error("boom")) - * scala> val x: Option[Int] = None - * scala> x.map2Eval(bomb)(_ + _).value - * res0: Option[Int] = None - * }}} - */ + * Similar to [[map2]] but uses [[Eval]] to allow for laziness in the `F[B]` + * argument. This can allow for "short-circuiting" of computations. + * + * NOTE: the default implementation of `map2Eval` does not short-circuit + * computations. For data structures that can benefit from laziness, [[Apply]] + * instances should override this method. + * + * In the following example, `x.map2(bomb)(_ + _)` would result in an error, + * but `map2Eval` "short-circuits" the computation. `x` is `None` and thus the + * result of `bomb` doesn't even need to be evaluated in order to determine + * that the result of `map2Eval` should be `None`. + * + * {{{ + * scala> import cats.{Eval, Later} + * scala> import cats.implicits._ + * scala> val bomb: Eval[Option[Int]] = Later(sys.error("boom")) + * scala> val x: Option[Int] = None + * scala> x.map2Eval(bomb)(_ + _).value + * res0: Option[Int] = None + * }}} + */ def map2Eval[A, B, Z](fa: F[A], fb: Eval[F[B]])(f: (A, B) => Z): Eval[F[Z]] = fb.map(fb => map2(fa, fb)(f)) /** - * Compose an `Apply[F]` and an `Apply[G]` into an `Apply[λ[α => F[G[α]]]]`. - * - * Example: - * {{{ - * scala> import cats.implicits._ - * - * scala> val alo = Apply[List].compose[Option] - * - * scala> alo.product(List(None, Some(true), Some(false)), List(Some(2), None)) - * res1: List[Option[(Boolean, Int)]] = List(None, None, Some((true,2)), None, Some((false,2)), None) - * }}} - */ + * Compose an `Apply[F]` and an `Apply[G]` into an `Apply[λ[α => F[G[α]]]]`. + * + * Example: + * {{{ + * scala> import cats.implicits._ + * + * scala> val alo = Apply[List].compose[Option] + * + * scala> alo.product(List(None, Some(true), Some(false)), List(Some(2), None)) + * res1: List[Option[(Boolean, Int)]] = List(None, None, Some((true,2)), None, Some((false,2)), None) + * }}} + */ def compose[G[_]: Apply]: Apply[λ[α => F[G[α]]]] = new ComposedApply[F, G] { val F = self diff --git a/core/src/main/scala/cats/Bifoldable.scala b/core/src/main/scala/cats/Bifoldable.scala index d02cb34fcd7..20f3da43642 100644 --- a/core/src/main/scala/cats/Bifoldable.scala +++ b/core/src/main/scala/cats/Bifoldable.scala @@ -3,9 +3,10 @@ package cats import simulacrum.typeclass /** - * A type class abstracting over types that give rise to two independent [[cats.Foldable]]s. - */ + * A type class abstracting over types that give rise to two independent [[cats.Foldable]]s. + */ @typeclass trait Bifoldable[F[_, _]] { self => + /** Collapse the structure with a left-associative function */ def bifoldLeft[A, B, C](fab: F[A, B], c: C)(f: (C, A) => C, g: (C, B) => C): C @@ -36,7 +37,8 @@ private[cats] trait ComposedBifoldable[F[_, _], G[_, _]] extends Bifoldable[λ[( (c: C, gab: G[A, B]) => G.bifoldLeft(gab, c)(f, g) ) - override def bifoldRight[A, B, C](fab: F[G[A, B], G[A, B]], c: Eval[C])(f: (A, Eval[C]) => Eval[C], g: (B, Eval[C]) => Eval[C]): Eval[C] = + override def bifoldRight[A, B, C](fab: F[G[A, B], G[A, B]], c: Eval[C])(f: (A, Eval[C]) => Eval[C], + g: (B, Eval[C]) => Eval[C]): Eval[C] = F.bifoldRight(fab, c)( (gab: G[A, B], c: Eval[C]) => G.bifoldRight(gab, c)(f, g), (gab: G[A, B], c: Eval[C]) => G.bifoldRight(gab, c)(f, g) diff --git a/core/src/main/scala/cats/Bifunctor.scala b/core/src/main/scala/cats/Bifunctor.scala index d77176c6363..3d9620d8b6e 100644 --- a/core/src/main/scala/cats/Bifunctor.scala +++ b/core/src/main/scala/cats/Bifunctor.scala @@ -1,36 +1,37 @@ package cats import simulacrum.typeclass + /** - * A type class of types which give rise to two independent, covariant - * functors. - */ + * A type class of types which give rise to two independent, covariant + * functors. + */ @typeclass trait Bifunctor[F[_, _]] { self => /** - * The quintessential method of the Bifunctor trait, it applies a - * function to each "side" of the bifunctor. - * - * Example: - * {{{ - * scala> import cats.implicits._ - * - * scala> val x: (List[String], Int) = (List("foo", "bar"), 3) - * scala> x.bimap(_.headOption, _.toLong + 1) - * res0: (Option[String], Long) = (Some(foo),4) - * }}} - */ + * The quintessential method of the Bifunctor trait, it applies a + * function to each "side" of the bifunctor. + * + * Example: + * {{{ + * scala> import cats.implicits._ + * + * scala> val x: (List[String], Int) = (List("foo", "bar"), 3) + * scala> x.bimap(_.headOption, _.toLong + 1) + * res0: (Option[String], Long) = (Some(foo),4) + * }}} + */ def bimap[A, B, C, D](fab: F[A, B])(f: A => C, g: B => D): F[C, D] def rightFunctor[X]: Functor[F[X, ?]] = - new RightFunctor[F, X] {val F = self} + new RightFunctor[F, X] { val F = self } def leftFunctor[X]: Functor[F[?, X]] = - new LeftFunctor[F, X] {val F = self} + new LeftFunctor[F, X] { val F = self } // derived methods /** - * apply a function to the "left" functor - */ + * apply a function to the "left" functor + */ def leftMap[A, B, C](fab: F[A, B])(f: A => C): F[C, B] = bimap(fab)(f, identity) /** The composition of two Bifunctors is itself a Bifunctor */ @@ -41,21 +42,20 @@ import simulacrum.typeclass } /** - * Widens A into a supertype AA. - * Example: - * {{{ - * scala> import cats.implicits._ - * scala> sealed trait Foo - * scala> case object Bar extends Foo - * scala> val x1: Either[Bar.type, Int] = Either.left(Bar) - * scala> val x2: Either[Foo, Int] = x1.leftWiden - * }}} - */ + * Widens A into a supertype AA. + * Example: + * {{{ + * scala> import cats.implicits._ + * scala> sealed trait Foo + * scala> case object Bar extends Foo + * scala> val x1: Either[Bar.type, Int] = Either.left(Bar) + * scala> val x2: Either[Foo, Int] = x1.leftWiden + * }}} + */ def leftWiden[A, B, AA >: A](fab: F[A, B]): F[AA, B] = fab.asInstanceOf[F[AA, B]] } -private[cats] trait ComposedBifunctor[F[_, _], G[_, _]] - extends Bifunctor[λ[(A, B) => F[G[A, B], G[A, B]]]] { +private[cats] trait ComposedBifunctor[F[_, _], G[_, _]] extends Bifunctor[λ[(A, B) => F[G[A, B], G[A, B]]]] { def F: Bifunctor[F] def G: Bifunctor[G] @@ -65,14 +65,14 @@ private[cats] trait ComposedBifunctor[F[_, _], G[_, _]] } } -private abstract class LeftFunctor[F[_, _], X] extends Functor[F[?, X]] { +abstract private class LeftFunctor[F[_, _], X] extends Functor[F[?, X]] { implicit val F: Bifunctor[F] override def map[A, C](fax: F[A, X])(f: A => C): F[C, X] = F.bimap(fax)(f, identity) } -private abstract class RightFunctor[F[_, _], X] extends Functor[F[X, ?]] { +abstract private class RightFunctor[F[_, _], X] extends Functor[F[X, ?]] { implicit val F: Bifunctor[F] override def map[A, C](fxa: F[X, A])(f: A => C): F[X, C] = diff --git a/core/src/main/scala/cats/Bitraverse.scala b/core/src/main/scala/cats/Bitraverse.scala index 0d75d160f7a..ddbe8859ed8 100644 --- a/core/src/main/scala/cats/Bitraverse.scala +++ b/core/src/main/scala/cats/Bitraverse.scala @@ -1,56 +1,54 @@ package cats - - import simulacrum.typeclass /** - * A type class abstracting over types that give rise to two independent [[cats.Traverse]]s. - */ + * A type class abstracting over types that give rise to two independent [[cats.Traverse]]s. + */ @typeclass trait Bitraverse[F[_, _]] extends Bifoldable[F] with Bifunctor[F] { self => /** - * Traverse each side of the structure with the given functions. - * - * Example: - * {{{ - * scala> import cats.implicits._ - * - * scala> def parseInt(s: String): Option[Int] = Either.catchOnly[NumberFormatException](s.toInt).toOption - * - * scala> ("1", "2").bitraverse(parseInt, parseInt) - * res0: Option[(Int, Int)] = Some((1,2)) - * - * scala> ("1", "two").bitraverse(parseInt, parseInt) - * res1: Option[(Int, Int)] = None - * }}} - */ + * Traverse each side of the structure with the given functions. + * + * Example: + * {{{ + * scala> import cats.implicits._ + * + * scala> def parseInt(s: String): Option[Int] = Either.catchOnly[NumberFormatException](s.toInt).toOption + * + * scala> ("1", "2").bitraverse(parseInt, parseInt) + * res0: Option[(Int, Int)] = Some((1,2)) + * + * scala> ("1", "two").bitraverse(parseInt, parseInt) + * res1: Option[(Int, Int)] = None + * }}} + */ def bitraverse[G[_]: Applicative, A, B, C, D](fab: F[A, B])(f: A => G[C], g: B => G[D]): G[F[C, D]] /** - * Invert the structure from F[G[A], G[B]] to G[F[A, B]]. - * - * Example: - * {{{ - * scala> import cats.implicits._ - * - * scala> val rightSome: Either[Option[String], Option[Int]] = Either.right(Some(3)) - * scala> rightSome.bisequence - * res0: Option[Either[String, Int]] = Some(Right(3)) - * - * scala> val rightNone: Either[Option[String], Option[Int]] = Either.right(None) - * scala> rightNone.bisequence - * res1: Option[Either[String, Int]] = None - * - * scala> val leftSome: Either[Option[String], Option[Int]] = Either.left(Some("foo")) - * scala> leftSome.bisequence - * res2: Option[Either[String, Int]] = Some(Left(foo)) - * - * scala> val leftNone: Either[Option[String], Option[Int]] = Either.left(None) - * scala> leftNone.bisequence - * res3: Option[Either[String, Int]] = None - * }}} - */ + * Invert the structure from F[G[A], G[B]] to G[F[A, B]]. + * + * Example: + * {{{ + * scala> import cats.implicits._ + * + * scala> val rightSome: Either[Option[String], Option[Int]] = Either.right(Some(3)) + * scala> rightSome.bisequence + * res0: Option[Either[String, Int]] = Some(Right(3)) + * + * scala> val rightNone: Either[Option[String], Option[Int]] = Either.right(None) + * scala> rightNone.bisequence + * res1: Option[Either[String, Int]] = None + * + * scala> val leftSome: Either[Option[String], Option[Int]] = Either.left(Some("foo")) + * scala> leftSome.bisequence + * res2: Option[Either[String, Int]] = Some(Left(foo)) + * + * scala> val leftNone: Either[Option[String], Option[Int]] = Either.left(None) + * scala> leftNone.bisequence + * res3: Option[Either[String, Int]] = None + * }}} + */ def bisequence[G[_]: Applicative, A, B](fab: F[G[A], G[B]]): G[F[A, B]] = bitraverse(fab)(identity, identity) @@ -67,14 +65,14 @@ import simulacrum.typeclass private[cats] trait ComposedBitraverse[F[_, _], G[_, _]] extends Bitraverse[λ[(α, β) => F[G[α, β], G[α, β]]]] - with ComposedBifoldable[F, G] - with ComposedBifunctor[F, G] { + with ComposedBifoldable[F, G] + with ComposedBifunctor[F, G] { def F: Bitraverse[F] def G: Bitraverse[G] - override def bitraverse[H[_]: Applicative, A, B, C, D]( - fab: F[G[A, B], G[A, B]])( - f: A => H[C], g: B => H[D] + override def bitraverse[H[_]: Applicative, A, B, C, D](fab: F[G[A, B], G[A, B]])( + f: A => H[C], + g: B => H[D] ): H[F[G[C, D], G[C, D]]] = F.bitraverse(fab)( gab => G.bitraverse(gab)(f, g), diff --git a/core/src/main/scala/cats/CoflatMap.scala b/core/src/main/scala/cats/CoflatMap.scala index 7df1e6266bb..c762169a99f 100644 --- a/core/src/main/scala/cats/CoflatMap.scala +++ b/core/src/main/scala/cats/CoflatMap.scala @@ -3,45 +3,45 @@ package cats import simulacrum.typeclass /** - * `CoflatMap` is the dual of `FlatMap`. - * - * Must obey the laws 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 context to a function that takes a value - * in a context and returns a normal value. - * - * Example: - * {{{ - * scala> import cats.implicits._ - * scala> import cats.CoflatMap - * scala> val fa = Some(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) - * }}} - */ + * `coflatMap` is the dual of `flatMap` on `FlatMap`. It applies + * a value in a context to a function that takes a value + * in a context and returns a normal value. + * + * Example: + * {{{ + * scala> import cats.implicits._ + * scala> import cats.CoflatMap + * scala> val fa = Some(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.implicits._ - * scala> import cats.CoflatMap - * scala> val fa = Some(3) - * fa: Option[Int] = Some(3) - * scala> CoflatMap[Option].coflatten(fa) - * res0: Option[Option[Int]] = Some(Some(3)) - * }}} - */ + * `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.implicits._ + * scala> import cats.CoflatMap + * scala> val fa = Some(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/CommutativeFlatMap.scala b/core/src/main/scala/cats/CommutativeFlatMap.scala index 22998bb3db9..270548b04df 100644 --- a/core/src/main/scala/cats/CommutativeFlatMap.scala +++ b/core/src/main/scala/cats/CommutativeFlatMap.scala @@ -3,12 +3,12 @@ package cats import simulacrum.typeclass /** - * Commutative FlatMap. - * - * Further than a FlatMap, which just allows composition of dependent effectful functions, - * in a Commutative FlatMap those functions can be composed in any order, which guarantees - * that their effects do not interfere. - * - * Must obey the laws defined in cats.laws.CommutativeFlatMapLaws. - */ + * Commutative FlatMap. + * + * Further than a FlatMap, which just allows composition of dependent effectful functions, + * in a Commutative FlatMap those functions can be composed in any order, which guarantees + * that their effects do not interfere. + * + * Must obey the laws defined in cats.laws.CommutativeFlatMapLaws. + */ @typeclass trait CommutativeFlatMap[F[_]] extends FlatMap[F] with CommutativeApply[F] diff --git a/core/src/main/scala/cats/CommutativeMonad.scala b/core/src/main/scala/cats/CommutativeMonad.scala index 9c7b07792d7..bc75bec81bc 100644 --- a/core/src/main/scala/cats/CommutativeMonad.scala +++ b/core/src/main/scala/cats/CommutativeMonad.scala @@ -3,12 +3,12 @@ package cats import simulacrum.typeclass /** - * Commutative Monad. - * - * Further than a Monad, which just allows composition of dependent effectful functions, - * in a Commutative Monad those functions can be composed in any order, which guarantees - * that their effects do not interfere. - * - * Must obey the laws defined in cats.laws.CommutativeMonadLaws. - */ + * Commutative Monad. + * + * Further than a Monad, which just allows composition of dependent effectful functions, + * in a Commutative Monad those functions can be composed in any order, which guarantees + * that their effects do not interfere. + * + * Must obey the laws defined in cats.laws.CommutativeMonadLaws. + */ @typeclass trait CommutativeMonad[F[_]] extends Monad[F] with CommutativeFlatMap[F] with CommutativeApplicative[F] diff --git a/core/src/main/scala/cats/Comonad.scala b/core/src/main/scala/cats/Comonad.scala index 2a931db9b21..bc21851b4b3 100644 --- a/core/src/main/scala/cats/Comonad.scala +++ b/core/src/main/scala/cats/Comonad.scala @@ -2,29 +2,28 @@ package cats import simulacrum.typeclass - /** - * 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. - */ + * 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[Int] = 3 - * scala> Comonad[Id].extract(id) - * res0: cats.Id[Int] = 3 - * }}} - */ + * `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[Int] = 3 + * scala> Comonad[Id].extract(id) + * res0: cats.Id[Int] = 3 + * }}} + */ def extract[A](x: F[A]): A } diff --git a/core/src/main/scala/cats/Composed.scala b/core/src/main/scala/cats/Composed.scala index 8c21b76771c..5cf97bbcd55 100644 --- a/core/src/main/scala/cats/Composed.scala +++ b/core/src/main/scala/cats/Composed.scala @@ -1,7 +1,7 @@ package cats - -private[cats] trait ComposedDistributive[F[_], G[_]] extends Distributive[λ[α => F[G[α]]]] with ComposedFunctor[F, G] { outer => +private[cats] trait ComposedDistributive[F[_], G[_]] extends Distributive[λ[α => F[G[α]]]] with ComposedFunctor[F, G] { + outer => def F: Distributive[F] def G: Distributive[G] @@ -36,7 +36,8 @@ private[cats] trait ComposedApply[F[_], G[_]] extends Apply[λ[α => F[G[α]]]] F.map2(fga, fgb)(G.product) } -private[cats] trait ComposedApplicative[F[_], G[_]] extends Applicative[λ[α => F[G[α]]]] with ComposedApply[F, G] { outer => +private[cats] trait ComposedApplicative[F[_], G[_]] extends Applicative[λ[α => F[G[α]]]] with ComposedApply[F, G] { + outer => def F: Applicative[F] def G: Applicative[G] @@ -55,7 +56,10 @@ private[cats] trait ComposedMonoidK[F[_], G[_]] extends MonoidK[λ[α => F[G[α] override def empty[A]: F[G[A]] = F.empty } -private[cats] trait ComposedAlternative[F[_], G[_]] extends Alternative[λ[α => F[G[α]]]] with ComposedApplicative[F, G] with ComposedMonoidK[F, G] { outer => +private[cats] trait ComposedAlternative[F[_], G[_]] + extends Alternative[λ[α => F[G[α]]]] + with ComposedApplicative[F, G] + with ComposedMonoidK[F, G] { outer => def F: Alternative[F] } @@ -70,7 +74,10 @@ private[cats] trait ComposedFoldable[F[_], G[_]] extends Foldable[λ[α => F[G[ F.foldRight(fga, lb)((ga, lb) => G.foldRight(ga, lb)(f)) } -private[cats] trait ComposedTraverse[F[_], G[_]] extends Traverse[λ[α => F[G[α]]]] with ComposedFoldable[F, G] with ComposedFunctor[F, G] { +private[cats] trait ComposedTraverse[F[_], G[_]] + extends Traverse[λ[α => F[G[α]]]] + with ComposedFoldable[F, G] + with ComposedFunctor[F, G] { def F: Traverse[F] def G: Traverse[G] @@ -78,7 +85,10 @@ private[cats] trait ComposedTraverse[F[_], G[_]] extends Traverse[λ[α => F[G[ F.traverse(fga)(ga => G.traverse(ga)(f)) } -private[cats] trait ComposedNonEmptyTraverse[F[_], G[_]] extends NonEmptyTraverse[λ[α => F[G[α]]]] with ComposedTraverse[F, G] with ComposedReducible[F, G] { +private[cats] trait ComposedNonEmptyTraverse[F[_], G[_]] + extends NonEmptyTraverse[λ[α => F[G[α]]]] + with ComposedTraverse[F, G] + with ComposedReducible[F, G] { def F: NonEmptyTraverse[F] def G: NonEmptyTraverse[G] @@ -121,7 +131,8 @@ private[cats] trait ComposedContravariantCovariant[F[_], G[_]] extends Contravar F.contramap(fga)(gb => G.map(gb)(f)) } -private[cats] trait ComposedApplicativeContravariantMonoidal[F[_], G[_]] extends ContravariantMonoidal[λ[α => F[G[α]]]] { outer => +private[cats] trait ComposedApplicativeContravariantMonoidal[F[_], G[_]] + extends ContravariantMonoidal[λ[α => F[G[α]]]] { outer => def F: Applicative[F] def G: ContravariantMonoidal[G] @@ -134,7 +145,9 @@ private[cats] trait ComposedApplicativeContravariantMonoidal[F[_], G[_]] extends F.map2(fa, fb)(G.product(_, _)) } -private[cats] trait ComposedSemigroupal[F[_], G[_]] extends ContravariantSemigroupal[λ[α => F[G[α]]]] with ComposedContravariantCovariant[F, G] { outer => +private[cats] trait ComposedSemigroupal[F[_], G[_]] + extends ContravariantSemigroupal[λ[α => F[G[α]]]] + with ComposedContravariantCovariant[F, G] { outer => def F: ContravariantSemigroupal[F] def G: Functor[G] @@ -144,13 +157,16 @@ private[cats] trait ComposedSemigroupal[F[_], G[_]] extends ContravariantSemigro } } -private[cats] trait ComposedInvariantApplySemigroupal[F[_], G[_]] extends InvariantSemigroupal[λ[α => F[G[α]]]] with ComposedInvariantCovariant[F, G] { outer => +private[cats] trait ComposedInvariantApplySemigroupal[F[_], G[_]] + extends InvariantSemigroupal[λ[α => F[G[α]]]] + with ComposedInvariantCovariant[F, G] { outer => def F: InvariantSemigroupal[F] def G: Apply[G] def product[A, B](fa: F[G[A]], fb: F[G[B]]): F[G[(A, B)]] = - F.imap(F.product(fa, fb)) { case (ga, gb) => - G.map2(ga, gb)(_ -> _) + F.imap(F.product(fa, fb)) { + case (ga, gb) => + G.map2(ga, gb)(_ -> _) } { g: G[(A, B)] => (G.map(g)(_._1), G.map(g)(_._2)) } diff --git a/core/src/main/scala/cats/Contravariant.scala b/core/src/main/scala/cats/Contravariant.scala index 1b08fb61f2c..06dd5472c4e 100644 --- a/core/src/main/scala/cats/Contravariant.scala +++ b/core/src/main/scala/cats/Contravariant.scala @@ -1,8 +1,9 @@ package cats import simulacrum.typeclass + /** - * Must obey the laws defined in cats.laws.ContravariantLaws. - */ + * Must obey the laws defined in cats.laws.ContravariantLaws. + */ @typeclass trait Contravariant[F[_]] extends Invariant[F] { self => def contramap[A, B](fa: F[A])(f: B => A): F[B] override def imap[A, B](fa: F[A])(f: A => B)(fi: B => A): F[B] = contramap(fa)(fi) @@ -14,9 +15,9 @@ import simulacrum.typeclass } /** - * Lifts natural subtyping contravariance of contravariant Functors. - * could be implemented as contramap(identity), but the Functor laws say this is equivalent - */ + * Lifts natural subtyping contravariance of contravariant Functors. + * could be implemented as contramap(identity), but the Functor laws say this is equivalent + */ def narrow[A, B <: A](fa: F[A]): F[B] = fa.asInstanceOf[F[B]] def liftContravariant[A, B](f: A => B): F[B] => F[A] = contramap(_: F[B])(f) diff --git a/core/src/main/scala/cats/ContravariantMonoidal.scala b/core/src/main/scala/cats/ContravariantMonoidal.scala index 276a7ce31e4..db35e77d40a 100644 --- a/core/src/main/scala/cats/ContravariantMonoidal.scala +++ b/core/src/main/scala/cats/ContravariantMonoidal.scala @@ -3,20 +3,21 @@ package cats import simulacrum.typeclass /** - * [[ContravariantMonoidal]] functors are functors that supply - * a unit along the diagonal map for the `contramap2` operation. - * - * Must obey the laws defined in cats.laws.ContravariantMonoidalLaws. - * - * Based on ekmett's contravariant library: - * https://hackage.haskell.org/package/contravariant-1.4/docs/Data-Functor-Contravariant-Divisible.html - */ + * [[ContravariantMonoidal]] functors are functors that supply + * a unit along the diagonal map for the `contramap2` operation. + * + * Must obey the laws defined in cats.laws.ContravariantMonoidalLaws. + * + * Based on ekmett's contravariant library: + * https://hackage.haskell.org/package/contravariant-1.4/docs/Data-Functor-Contravariant-Divisible.html + */ @typeclass trait ContravariantMonoidal[F[_]] extends ContravariantSemigroupal[F] with InvariantMonoidal[F] { + /** - * `trivial` produces an instance of `F` for any type `A` - * that is trivial with respect to `contramap2` along - * the diagonal - */ + * `trivial` produces an instance of `F` for any type `A` + * that is trivial with respect to `contramap2` along + * the diagonal + */ def trivial[A]: F[A] = contramap(unit)(_ => ()) } @@ -25,6 +26,8 @@ object ContravariantMonoidal extends SemigroupalArityFunctions { new ContravariantMonoidalMonoid[F, A](f) } -private[cats] class ContravariantMonoidalMonoid[F[_], A](f: ContravariantMonoidal[F]) extends ContravariantSemigroupalSemigroup[F, A](f) with Monoid[F[A]] { +private[cats] class ContravariantMonoidalMonoid[F[_], A](f: ContravariantMonoidal[F]) + extends ContravariantSemigroupalSemigroup[F, A](f) + with Monoid[F[A]] { def empty: F[A] = f.trivial } diff --git a/core/src/main/scala/cats/ContravariantSemigroupal.scala b/core/src/main/scala/cats/ContravariantSemigroupal.scala index 77910a31e0f..3f05477c541 100644 --- a/core/src/main/scala/cats/ContravariantSemigroupal.scala +++ b/core/src/main/scala/cats/ContravariantSemigroupal.scala @@ -3,9 +3,9 @@ package cats import simulacrum.typeclass /** - * [[ContravariantSemigroupal]] is nothing more than something both contravariant - * and Semigroupal. It comes up enough to be useful, and composes well - */ + * [[ContravariantSemigroupal]] is nothing more than something both contravariant + * and Semigroupal. It comes up enough to be useful, and composes well + */ @typeclass trait ContravariantSemigroupal[F[_]] extends InvariantSemigroupal[F] with Contravariant[F] { self => override def composeFunctor[G[_]: Functor]: ContravariantSemigroupal[λ[α => F[G[α]]]] = new ComposedSemigroupal[F, G] { diff --git a/core/src/main/scala/cats/Defer.scala b/core/src/main/scala/cats/Defer.scala index 2ab135c54da..5c99f5a001f 100644 --- a/core/src/main/scala/cats/Defer.scala +++ b/core/src/main/scala/cats/Defer.scala @@ -1,31 +1,31 @@ package cats /** - * Defer is a type class that shows the ability to defer creation - * inside of the type constructor F[_]. - * - * This comes up with F[_] types that are implemented with a trampoline - * or are based on function application. - * - * The law is that defer(fa) is equivalent to fa, but not evaluated immediately, - * so - * {{{ - * scala> import cats._ - * scala> import cats.implicits._ - * - * scala> var evaluated = false - * scala> val dfa = Defer[Eval].defer { - * | evaluated = true - * | Eval.now(21) - * | } - * - * scala> evaluated - * res0: Boolean = false - * - * scala> Eq[Eval[Int]].eqv(dfa, Eval.now(21)) - * res1: Boolean = true - * }}} - */ + * Defer is a type class that shows the ability to defer creation + * inside of the type constructor F[_]. + * + * This comes up with F[_] types that are implemented with a trampoline + * or are based on function application. + * + * The law is that defer(fa) is equivalent to fa, but not evaluated immediately, + * so + * {{{ + * scala> import cats._ + * scala> import cats.implicits._ + * + * scala> var evaluated = false + * scala> val dfa = Defer[Eval].defer { + * | evaluated = true + * | Eval.now(21) + * | } + * + * scala> evaluated + * res0: Boolean = false + * + * scala> Eq[Eval[Int]].eqv(dfa, Eval.now(21)) + * res1: Boolean = true + * }}} + */ trait Defer[F[_]] extends Serializable { def defer[A](fa: => F[A]): F[A] } diff --git a/core/src/main/scala/cats/Distributive.scala b/core/src/main/scala/cats/Distributive.scala index 68df7b67e8a..cdb5acf70f2 100644 --- a/core/src/main/scala/cats/Distributive.scala +++ b/core/src/main/scala/cats/Distributive.scala @@ -4,13 +4,13 @@ import simulacrum.typeclass @typeclass trait Distributive[F[_]] extends Functor[F] { self => /** - * Given a function which returns a distributive `F`, apply that value across the structure G. - */ + * Given a function which returns a distributive `F`, apply that value across the structure G. + */ def distribute[G[_]: Functor, A, B](ga: G[A])(f: A => F[B]): F[G[B]] /** - * Given a Functor G which wraps some distributive F, distribute F across the G. - */ + * Given a Functor G which wraps some distributive F, distribute F across the G. + */ def cosequence[G[_]: Functor, A](ga: G[F[A]]): F[G[A]] = distribute(ga)(identity) // Distributive composes diff --git a/core/src/main/scala/cats/Eval.scala b/core/src/main/scala/cats/Eval.scala index ca4898ae551..44fd798100e 100644 --- a/core/src/main/scala/cats/Eval.scala +++ b/core/src/main/scala/cats/Eval.scala @@ -5,71 +5,71 @@ import scala.annotation.tailrec import cats.syntax.all._ /** - * Eval is a monad which controls evaluation. - * - * This type wraps a value (or a computation that produces a value) - * and can produce it on command via the `.value` method. - * - * There are three basic evaluation strategies: - * - * - Now: evaluated immediately - * - Later: evaluated once when value is needed - * - Always: evaluated every time value is needed - * - * The Later and Always are both lazy strategies while Now is eager. - * Later and Always are distinguished from each other only by - * memoization: once evaluated Later will save the value to be returned - * immediately if it is needed again. Always will run its computation - * every time. - * - * Eval supports stack-safe lazy computation via the .map and .flatMap - * methods, which use an internal trampoline to avoid stack overflows. - * Computation done within .map and .flatMap is always done lazily, - * even when applied to a Now instance. - * - * It is not generally good style to pattern-match on Eval instances. - * Rather, use .map and .flatMap to chain computation, and use .value - * to get the result when needed. It is also not good style to create - * Eval instances whose computation involves calling .value on another - * Eval instance -- this can defeat the trampolining and lead to stack - * overflows. - */ + * Eval is a monad which controls evaluation. + * + * This type wraps a value (or a computation that produces a value) + * and can produce it on command via the `.value` method. + * + * There are three basic evaluation strategies: + * + * - Now: evaluated immediately + * - Later: evaluated once when value is needed + * - Always: evaluated every time value is needed + * + * The Later and Always are both lazy strategies while Now is eager. + * Later and Always are distinguished from each other only by + * memoization: once evaluated Later will save the value to be returned + * immediately if it is needed again. Always will run its computation + * every time. + * + * Eval supports stack-safe lazy computation via the .map and .flatMap + * methods, which use an internal trampoline to avoid stack overflows. + * Computation done within .map and .flatMap is always done lazily, + * even when applied to a Now instance. + * + * It is not generally good style to pattern-match on Eval instances. + * Rather, use .map and .flatMap to chain computation, and use .value + * to get the result when needed. It is also not good style to create + * Eval instances whose computation involves calling .value on another + * Eval instance -- this can defeat the trampolining and lead to stack + * overflows. + */ sealed abstract class Eval[+A] extends Serializable { self => /** - * Evaluate the computation and return an A value. - * - * For lazy instances (Later, Always), any necessary computation - * will be performed at this point. For eager instances (Now), a - * value will be immediately returned. - */ + * Evaluate the computation and return an A value. + * + * For lazy instances (Later, Always), any necessary computation + * will be performed at this point. For eager instances (Now), a + * value will be immediately returned. + */ def value: A /** - * Transform an Eval[A] into an Eval[B] given the transformation - * function `f`. - * - * This call is stack-safe -- many .map calls may be chained without - * consumed additional stack during evaluation. - * - * Computation performed in f is always lazy, even when called on an - * eager (Now) instance. - */ + * Transform an Eval[A] into an Eval[B] given the transformation + * function `f`. + * + * This call is stack-safe -- many .map calls may be chained without + * consumed additional stack during evaluation. + * + * Computation performed in f is always lazy, even when called on an + * eager (Now) instance. + */ def map[B](f: A => B): Eval[B] = flatMap(a => Now(f(a))) /** - * Lazily perform a computation based on an Eval[A], using the - * function `f` to produce an Eval[B] given an A. - * - * This call is stack-safe -- many .flatMap calls may be chained - * without consumed additional stack during evaluation. It is also - * written to avoid left-association problems, so that repeated - * calls to .flatMap will be efficiently applied. - * - * Computation performed in f is always lazy, even when called on an - * eager (Now) instance. - */ + * Lazily perform a computation based on an Eval[A], using the + * function `f` to produce an Eval[B] given an A. + * + * This call is stack-safe -- many .flatMap calls may be chained + * without consumed additional stack during evaluation. It is also + * written to avoid left-association problems, so that repeated + * calls to .flatMap will be efficiently applied. + * + * Computation performed in f is always lazy, even when called on an + * eager (Now) instance. + */ def flatMap[B](f: A => Eval[B]): Eval[B] = this match { case c: Eval.FlatMap[A] => @@ -84,7 +84,7 @@ sealed abstract class Eval[+A] extends Serializable { self => type Start = A val start = () => c.run(s) val run = f - } + } } case c: Eval.Defer[A] => new Eval.FlatMap[B] { @@ -101,42 +101,41 @@ sealed abstract class Eval[+A] extends Serializable { self => } /** - * Ensure that the result of the computation (if any) will be - * memoized. - * - * Practically, this means that when called on an Always[A] a - * Later[A] with an equivalent computation will be returned. - */ + * Ensure that the result of the computation (if any) will be + * memoized. + * + * Practically, this means that when called on an Always[A] a + * Later[A] with an equivalent computation will be returned. + */ def memoize: Eval[A] } /** - * Construct an eager Eval[A] instance. - * - * In some sense it is equivalent to using a val. - * - * This type should be used when an A value is already in hand, or - * when the computation to produce an A value is pure and very fast. - */ + * Construct an eager Eval[A] instance. + * + * In some sense it is equivalent to using a val. + * + * This type should be used when an A value is already in hand, or + * when the computation to produce an A value is pure and very fast. + */ final case class Now[A](value: A) extends Eval[A] { def memoize: Eval[A] = this } - /** - * Construct a lazy Eval[A] instance. - * - * This type should be used for most "lazy" values. In some sense it - * is equivalent to using a lazy val. - * - * When caching is not required or desired (e.g. if the value produced - * may be large) prefer Always. When there is no computation - * necessary, prefer Now. - * - * Once Later has been evaluated, the closure (and any values captured - * by the closure) will not be retained, and will be available for - * garbage collection. - */ + * Construct a lazy Eval[A] instance. + * + * This type should be used for most "lazy" values. In some sense it + * is equivalent to using a lazy val. + * + * When caching is not required or desired (e.g. if the value produced + * may be large) prefer Always. When there is no computation + * necessary, prefer Now. + * + * Once Later has been evaluated, the closure (and any values captured + * by the closure) will not be retained, and will be available for + * garbage collection. + */ final class Later[A](f: () => A) extends Eval[A] { private[this] var thunk: () => A = f @@ -161,15 +160,15 @@ object Later { } /** - * Construct a lazy Eval[A] instance. - * - * This type can be used for "lazy" values. In some sense it is - * equivalent to using a Function0 value. - * - * This type will evaluate the computation every time the value is - * required. It should be avoided except when laziness is required and - * caching must be avoided. Generally, prefer Later. - */ + * Construct a lazy Eval[A] instance. + * + * This type can be used for "lazy" values. In some sense it is + * equivalent to using a Function0 value. + * + * This type will evaluate the computation every time the value is + * required. It should be avoided except when laziness is required and + * caching must be avoided. Generally, prefer Later. + */ final class Always[A](f: () => A) extends Eval[A] { def value: A = f() def memoize: Eval[A] = new Later(f) @@ -182,76 +181,76 @@ object Always { object Eval extends EvalInstances { /** - * Construct an eager Eval[A] value (i.e. Now[A]). - */ + * Construct an eager Eval[A] value (i.e. Now[A]). + */ def now[A](a: A): Eval[A] = Now(a) /** - * Construct a lazy Eval[A] value with caching (i.e. Later[A]). - */ + * Construct a lazy Eval[A] value with caching (i.e. Later[A]). + */ def later[A](a: => A): Eval[A] = new Later(a _) /** - * Construct a lazy Eval[A] value without caching (i.e. Always[A]). - */ + * Construct a lazy Eval[A] value without caching (i.e. Always[A]). + */ def always[A](a: => A): Eval[A] = new Always(a _) /** - * Defer a computation which produces an Eval[A] value. - * - * This is useful when you want to delay execution of an expression - * which produces an Eval[A] value. Like .flatMap, it is stack-safe. - */ + * Defer a computation which produces an Eval[A] value. + * + * This is useful when you want to delay execution of an expression + * which produces an Eval[A] value. Like .flatMap, it is stack-safe. + */ def defer[A](a: => Eval[A]): Eval[A] = new Eval.Defer[A](a _) {} /** - * Static Eval instance for common value `Unit`. - * - * This can be useful in cases where the same value may be needed - * many times. - */ + * Static Eval instance for common value `Unit`. + * + * This can be useful in cases where the same value may be needed + * many times. + */ val Unit: Eval[Unit] = Now(()) /** - * Static Eval instance for common value `true`. - * - * This can be useful in cases where the same value may be needed - * many times. - */ + * Static Eval instance for common value `true`. + * + * This can be useful in cases where the same value may be needed + * many times. + */ val True: Eval[Boolean] = Now(true) /** - * Static Eval instance for common value `false`. - * - * This can be useful in cases where the same value may be needed - * many times. - */ + * Static Eval instance for common value `false`. + * + * This can be useful in cases where the same value may be needed + * many times. + */ val False: Eval[Boolean] = Now(false) /** - * Static Eval instance for common value `0`. - * - * This can be useful in cases where the same value may be needed - * many times. - */ + * Static Eval instance for common value `0`. + * + * This can be useful in cases where the same value may be needed + * many times. + */ val Zero: Eval[Int] = Now(0) /** - * Static Eval instance for common value `1`. - * - * This can be useful in cases where the same value may be needed - * many times. - */ + * Static Eval instance for common value `1`. + * + * This can be useful in cases where the same value may be needed + * many times. + */ val One: Eval[Int] = Now(1) /** - * Defer is a type of Eval[A] that is used to defer computations - * which produce Eval[A]. - * - * Users should not instantiate Defer instances themselves. Instead, - * they will be automatically created when needed. - */ + * Defer is a type of Eval[A] that is used to defer computations + * which produce Eval[A]. + * + * Users should not instantiate Defer instances themselves. Instead, + * they will be automatically created when needed. + */ sealed abstract class Defer[A](val thunk: () => Eval[A]) extends Eval[A] { def memoize: Eval[A] = Memoize(this) @@ -259,13 +258,13 @@ object Eval extends EvalInstances { } /** - * Advance until we find a non-deferred Eval node. - * - * Often we may have deep chains of Defer nodes; the goal here is to - * advance through those to find the underlying "work" (in the case - * of FlatMap nodes) or "value" (in the case of Now, Later, or - * Always nodes). - */ + * Advance until we find a non-deferred Eval node. + * + * Often we may have deep chains of Defer nodes; the goal here is to + * advance through those to find the underlying "work" (in the case + * of FlatMap nodes) or "value" (in the case of Now, Later, or + * Always nodes). + */ @tailrec private def advance[A](fa: Eval[A]): Eval[A] = fa match { case call: Eval.Defer[A] => @@ -280,25 +279,25 @@ object Eval extends EvalInstances { } /** - * Alias for advance that can be called in a non-tail position - * from an otherwise tailrec-optimized advance. - */ + * Alias for advance that can be called in a non-tail position + * from an otherwise tailrec-optimized advance. + */ private def advance1[A](fa: Eval[A]): Eval[A] = advance(fa) /** - * FlatMap is a type of Eval[A] that is used to chain computations - * involving .map and .flatMap. Along with Eval#flatMap it - * implements the trampoline that guarantees stack-safety. - * - * Users should not instantiate FlatMap instances - * themselves. Instead, they will be automatically created when - * needed. - * - * Unlike a traditional trampoline, the internal workings of the - * trampoline are not exposed. This allows a slightly more efficient - * implementation of the .value method. - */ + * FlatMap is a type of Eval[A] that is used to chain computations + * involving .map and .flatMap. Along with Eval#flatMap it + * implements the trampoline that guarantees stack-safety. + * + * Users should not instantiate FlatMap instances + * themselves. Instead, they will be automatically created when + * needed. + * + * Unlike a traditional trampoline, the internal workings of the + * trampoline are not exposed. This allows a slightly more efficient + * implementation of the .value method. + */ sealed abstract class FlatMap[A] extends Eval[A] { self => type Start val start: () => Eval[Start] @@ -321,7 +320,6 @@ object Eval extends EvalInstances { } } - private def evaluate[A](e: Eval[A]): A = { type L = Eval[Any] type M = Memoize[Any] @@ -337,10 +335,8 @@ object Eval extends EvalInstances { case c: FlatMap[_] => c.start() match { case cc: FlatMap[_] => - loop( - cc.start().asInstanceOf[L], - cc.run.asInstanceOf[C] :: c.run.asInstanceOf[C] :: fs) - case mm@Memoize(eval) => + loop(cc.start().asInstanceOf[L], cc.run.asInstanceOf[C] :: c.run.asInstanceOf[C] :: fs) + case mm @ Memoize(eval) => mm.result match { case Some(a) => loop(Now(a), c.run.asInstanceOf[C] :: fs) @@ -352,12 +348,12 @@ object Eval extends EvalInstances { } case call: Defer[_] => loop(advance(call), fs) - case m@Memoize(eval) => + case m @ Memoize(eval) => m.result match { case Some(a) => fs match { case f :: fs => loop(f(a), fs) - case Nil => a + case Nil => a } case None => loop(eval, addToMemo(m) :: fs) @@ -365,7 +361,7 @@ object Eval extends EvalInstances { case x => fs match { case f :: fs => loop(f(x.value), fs) - case Nil => x.value + case Nil => x.value } } @@ -373,7 +369,7 @@ object Eval extends EvalInstances { } } -private[cats] sealed abstract class EvalInstances extends EvalInstances0 { +sealed abstract private[cats] class EvalInstances extends EvalInstances0 { implicit val catsBimonadForEval: Bimonad[Eval] with CommutativeMonad[Eval] = new Bimonad[Eval] with StackSafeMonad[Eval] with CommutativeMonad[Eval] { @@ -410,14 +406,16 @@ private[cats] sealed abstract class EvalInstances extends EvalInstances0 { override def reduceRightOption[A](fa: Eval[A])(f: (A, Eval[A]) => Eval[A]): Eval[Option[A]] = fa.map(Some(_)) override def reduceRightToOption[A, B](fa: Eval[A])(f: A => B)(g: (A, Eval[B]) => Eval[B]): Eval[Option[B]] = - fa.map { a => Some(f(a)) } + fa.map { a => + Some(f(a)) + } override def size[A](f: Eval[A]): Long = 1L } implicit def catsOrderForEval[A: Order]: Order[Eval[A]] = new Order[Eval[A]] { def compare(lx: Eval[A], ly: Eval[A]): Int = - lx.value compare ly.value + lx.value.compare(ly.value) } implicit def catsGroupForEval[A: Group]: Group[Eval[A]] = @@ -429,29 +427,29 @@ private[cats] sealed abstract class EvalInstances extends EvalInstances0 { override val F: Functor[Eval] = Functor[Eval] /** - * Create a function that "indexes" into the `F` structure using `Representation` - */ + * Create a function that "indexes" into the `F` structure using `Representation` + */ override def index[A](f: Eval[A]): Unit => A = (_: Unit) => f.value /** - * Reconstructs the `F` structure using the index function - */ + * Reconstructs the `F` structure using the index function + */ override def tabulate[A](f: Unit => A): Eval[A] = Eval.later(f(())) } } -private[cats] sealed abstract class EvalInstances0 extends EvalInstances1 { +sealed abstract private[cats] class EvalInstances0 extends EvalInstances1 { implicit def catsPartialOrderForEval[A: PartialOrder]: PartialOrder[Eval[A]] = new PartialOrder[Eval[A]] { def partialCompare(lx: Eval[A], ly: Eval[A]): Double = - lx.value partialCompare ly.value + lx.value.partialCompare(ly.value) } implicit def catsMonoidForEval[A: Monoid]: Monoid[Eval[A]] = new EvalMonoid[A] { val algebra = Monoid[A] } } -private[cats] sealed abstract class EvalInstances1 { +sealed abstract private[cats] class EvalInstances1 { implicit def catsEqForEval[A: Eq]: Eq[Eval[A]] = new Eq[Eval[A]] { def eqv(lx: Eval[A], ly: Eval[A]): Boolean = diff --git a/core/src/main/scala/cats/FlatMap.scala b/core/src/main/scala/cats/FlatMap.scala index c7c3cb50249..6620116d5df 100644 --- a/core/src/main/scala/cats/FlatMap.scala +++ b/core/src/main/scala/cats/FlatMap.scala @@ -4,84 +4,80 @@ import simulacrum.typeclass import simulacrum.noop /** - * FlatMap type class gives us flatMap, which allows us to have a value - * in a context (F[A]) and then feed that into a function that takes - * a normal value and returns a value in a context (A => F[B]). - * - * One motivation for separating this out from Monad is that there are - * situations where we can implement flatMap but not pure. For example, - * we can implement map or flatMap that transforms the values of Map[K, ?], - * but we can't implement pure (because we wouldn't know what key to use - * when instantiating the new Map). - * - * @see See [[https://github.com/typelevel/cats/issues/3]] for some discussion. - * - * Must obey the laws defined in cats.laws.FlatMapLaws. - */ + * FlatMap type class gives us flatMap, which allows us to have a value + * in a context (F[A]) and then feed that into a function that takes + * a normal value and returns a value in a context (A => F[B]). + * + * One motivation for separating this out from Monad is that there are + * situations where we can implement flatMap but not pure. For example, + * we can implement map or flatMap that transforms the values of Map[K, ?], + * but we can't implement pure (because we wouldn't know what key to use + * when instantiating the new Map). + * + * @see See [[https://github.com/typelevel/cats/issues/3]] for some discussion. + * + * Must obey the laws defined in cats.laws.FlatMapLaws. + */ @typeclass trait FlatMap[F[_]] extends Apply[F] { def flatMap[A, B](fa: F[A])(f: A => F[B]): F[B] /** - * "flatten" a nested `F` of `F` structure into a single-layer `F` structure. - * - * This is also commonly called `join`. - * - * Example: - * {{{ - * scala> import cats.Eval - * scala> import cats.implicits._ - * - * scala> val nested: Eval[Eval[Int]] = Eval.now(Eval.now(3)) - * scala> val flattened: Eval[Int] = nested.flatten - * scala> flattened.value - * res0: Int = 3 - * }}} - */ + * "flatten" a nested `F` of `F` structure into a single-layer `F` structure. + * + * This is also commonly called `join`. + * + * Example: + * {{{ + * scala> import cats.Eval + * scala> import cats.implicits._ + * + * scala> val nested: Eval[Eval[Int]] = Eval.now(Eval.now(3)) + * scala> val flattened: Eval[Int] = nested.flatten + * scala> flattened.value + * res0: Int = 3 + * }}} + */ def flatten[A](ffa: F[F[A]]): F[A] = flatMap(ffa)(fa => fa) - - /** - * Sequentially compose two actions, discarding any value produced by the first. This variant of - * [[productR]] also lets you define the evaluation strategy of the second action. For instance - * you can evaluate it only ''after'' the first action has finished: - * - * {{{ - * scala> import cats.Eval - * scala> import cats.implicits._ - * scala> val fa: Option[Int] = Some(3) - * scala> def fb: Option[String] = Some("foo") - * scala> fa.productREval(Eval.later(fb)) - * res0: Option[String] = Some(foo) - * }}} - */ + * Sequentially compose two actions, discarding any value produced by the first. This variant of + * [[productR]] also lets you define the evaluation strategy of the second action. For instance + * you can evaluate it only ''after'' the first action has finished: + * + * {{{ + * scala> import cats.Eval + * scala> import cats.implicits._ + * scala> val fa: Option[Int] = Some(3) + * scala> def fb: Option[String] = Some("foo") + * scala> fa.productREval(Eval.later(fb)) + * res0: Option[String] = Some(foo) + * }}} + */ def productREval[A, B](fa: F[A])(fb: Eval[F[B]]): F[B] = flatMap(fa)(_ => fb.value) @deprecated("Use productREval instead.", "1.0.0-RC2") @noop def followedByEval[A, B](fa: F[A])(fb: Eval[F[B]]): F[B] = productREval(fa)(fb) - - /** - * Sequentially compose two actions, discarding any value produced by the second. This variant of - * [[productL]] also lets you define the evaluation strategy of the second action. For instance - * you can evaluate it only ''after'' the first action has finished: - * - * {{{ - * scala> import cats.Eval - * scala> import cats.implicits._ - * scala> var count = 0 - * scala> val fa: Option[Int] = Some(3) - * scala> def fb: Option[Unit] = Some(count += 1) - * scala> fa.productLEval(Eval.later(fb)) - * res0: Option[Int] = Some(3) - * scala> assert(count == 1) - * scala> none[Int].productLEval(Eval.later(fb)) - * res1: Option[Int] = None - * scala> assert(count == 1) - * }}} - */ + * Sequentially compose two actions, discarding any value produced by the second. This variant of + * [[productL]] also lets you define the evaluation strategy of the second action. For instance + * you can evaluate it only ''after'' the first action has finished: + * + * {{{ + * scala> import cats.Eval + * scala> import cats.implicits._ + * scala> var count = 0 + * scala> val fa: Option[Int] = Some(3) + * scala> def fb: Option[Unit] = Some(count += 1) + * scala> fa.productLEval(Eval.later(fb)) + * res0: Option[Int] = Some(3) + * scala> assert(count == 1) + * scala> none[Int].productLEval(Eval.later(fb)) + * res1: Option[Int] = None + * scala> assert(count == 1) + * }}} + */ def productLEval[A, B](fa: F[A])(fb: Eval[F[B]]): F[A] = flatMap(fa)(a => map(fb.value)(_ => a)) @deprecated("Use productLEval instead.", "1.0.0-RC2") @@ -94,32 +90,32 @@ import simulacrum.noop flatMap(fa)(a => map(fb)(b => (a, b))) /** - * Pair `A` with the result of function application. - * - * Example: - * {{{ - * scala> import cats.implicits._ - * scala> List("12", "34", "56").mproduct(_.toList) - * res0: List[(String, Char)] = List((12,1), (12,2), (34,3), (34,4), (56,5), (56,6)) - * }}} - */ + * Pair `A` with the result of function application. + * + * Example: + * {{{ + * scala> import cats.implicits._ + * scala> List("12", "34", "56").mproduct(_.toList) + * res0: List[(String, Char)] = List((12,1), (12,2), (34,3), (34,4), (56,5), (56,6)) + * }}} + */ def mproduct[A, B](fa: F[A])(f: A => F[B]): F[(A, B)] = flatMap(fa)(a => map(f(a))((a, _))) /** - * `if` lifted into monad. - */ + * `if` lifted into monad. + */ def ifM[B](fa: F[Boolean])(ifTrue: => F[B], ifFalse: => F[B]): F[B] = flatMap(fa)(if (_) ifTrue else ifFalse) /** - * Keeps calling `f` until a `scala.util.Right[B]` is returned. - * - * Based on Phil Freeman's - * [[http://functorial.com/stack-safety-for-free/index.pdf Stack Safety for Free]]. - * - * Implementations of this method should use constant stack space relative to `f`. - */ + * Keeps calling `f` until a `scala.util.Right[B]` is returned. + * + * Based on Phil Freeman's + * [[http://functorial.com/stack-safety-for-free/index.pdf Stack Safety for Free]]. + * + * Implementations of this method should use constant stack space relative to `f`. + */ def tailRecM[A, B](a: A)(f: A => F[Either[A, B]]): F[B] /** diff --git a/core/src/main/scala/cats/Foldable.scala b/core/src/main/scala/cats/Foldable.scala index cd0047debf8..24fb6ee8495 100644 --- a/core/src/main/scala/cats/Foldable.scala +++ b/core/src/main/scala/cats/Foldable.scala @@ -7,190 +7,189 @@ import simulacrum.typeclass import Foldable.sentinel /** - * Data structures that can be folded to a summary value. - * - * In the case of a collection (such as `List` or `Vector`), these - * methods will fold together (combine) the values contained in the - * collection to produce a single result. Most collection types have - * `foldLeft` methods, which will usually be used by the associated - * `Foldable[_]` instance. - * - * Instances of Foldable should be ordered collections to allow for consistent folding. - * Use the `UnorderedFoldable` type class if you want to fold over unordered collections. - * - * Foldable[F] is implemented in terms of two basic methods: - * - * - `foldLeft(fa, b)(f)` eagerly folds `fa` from left-to-right. - * - `foldRight(fa, b)(f)` lazily folds `fa` from right-to-left. - * - * Beyond these it provides many other useful methods related to - * folding over F[A] values. - * - * See: [[http://www.cs.nott.ac.uk/~pszgmh/fold.pdf A tutorial on the universality and expressiveness of fold]] - */ + * Data structures that can be folded to a summary value. + * + * In the case of a collection (such as `List` or `Vector`), these + * methods will fold together (combine) the values contained in the + * collection to produce a single result. Most collection types have + * `foldLeft` methods, which will usually be used by the associated + * `Foldable[_]` instance. + * + * Instances of Foldable should be ordered collections to allow for consistent folding. + * Use the `UnorderedFoldable` type class if you want to fold over unordered collections. + * + * Foldable[F] is implemented in terms of two basic methods: + * + * - `foldLeft(fa, b)(f)` eagerly folds `fa` from left-to-right. + * - `foldRight(fa, b)(f)` lazily folds `fa` from right-to-left. + * + * Beyond these it provides many other useful methods related to + * folding over F[A] values. + * + * See: [[http://www.cs.nott.ac.uk/~pszgmh/fold.pdf A tutorial on the universality and expressiveness of fold]] + */ @typeclass trait Foldable[F[_]] extends UnorderedFoldable[F] { self => /** - * Left associative fold on 'F' using the function 'f'. - * - * Example: - * {{{ - * scala> import cats.Foldable, cats.implicits._ - * scala> val fa = Option(1) - * - * Folding by addition to zero: - * scala> Foldable[Option].foldLeft(fa, Option(0))((a, n) => a.map(_ + n)) - * res0: Option[Int] = Some(1) - * }}} - * - * With syntax extensions, `foldLeft` can be used like: - * {{{ - * Folding `Option` with addition from zero: - * scala> fa.foldLeft(Option(0))((a, n) => a.map(_ + n)) - * res1: Option[Int] = Some(1) - * - * There's also an alias `foldl` which is equivalent: - * scala> fa.foldl(Option(0))((a, n) => a.map(_ + n)) - * res2: Option[Int] = Some(1) - * }}} - */ + * Left associative fold on 'F' using the function 'f'. + * + * Example: + * {{{ + * scala> import cats.Foldable, cats.implicits._ + * scala> val fa = Option(1) + * + * Folding by addition to zero: + * scala> Foldable[Option].foldLeft(fa, Option(0))((a, n) => a.map(_ + n)) + * res0: Option[Int] = Some(1) + * }}} + * + * With syntax extensions, `foldLeft` can be used like: + * {{{ + * Folding `Option` with addition from zero: + * scala> fa.foldLeft(Option(0))((a, n) => a.map(_ + n)) + * res1: Option[Int] = Some(1) + * + * There's also an alias `foldl` which is equivalent: + * scala> fa.foldl(Option(0))((a, n) => a.map(_ + n)) + * res2: Option[Int] = Some(1) + * }}} + */ def foldLeft[A, B](fa: F[A], b: B)(f: (B, A) => B): B - /** - * Right associative lazy fold on `F` using the folding function 'f'. - * - * This method evaluates `lb` lazily (in some cases it will not be - * needed), and returns a lazy value. We are using `(A, Eval[B]) => - * Eval[B]` to support laziness in a stack-safe way. Chained - * computation should be performed via .map and .flatMap. - * - * For more detailed information about how this method works see the - * documentation for `Eval[_]`. - * - * Example: - * {{{ - * scala> import cats.Foldable, cats.Eval, cats.implicits._ - * scala> val fa = Option(1) - * - * Folding by addition to zero: - * scala> val folded1 = Foldable[Option].foldRight(fa, Eval.now(0))((n, a) => a.map(_ + n)) - * Since `foldRight` yields a lazy computation, we need to force it to inspect the result: - * scala> folded1.value - * res0: Int = 1 - * - * With syntax extensions, we can write the same thing like this: - * scala> val folded2 = fa.foldRight(Eval.now(0))((n, a) => a.map(_ + n)) - * scala> folded2.value - * res1: Int = 1 - * - * Unfortunately, since `foldRight` is defined on many collections - this - * extension clashes with the operation defined in `Foldable`. - * - * To get past this and make sure you're getting the lazy `foldRight` defined - * in `Foldable`, there's an alias `foldr`: - * scala> val folded3 = fa.foldr(Eval.now(0))((n, a) => a.map(_ + n)) - * scala> folded3.value - * res1: Int = 1 - * }}} - */ + * Right associative lazy fold on `F` using the folding function 'f'. + * + * This method evaluates `lb` lazily (in some cases it will not be + * needed), and returns a lazy value. We are using `(A, Eval[B]) => + * Eval[B]` to support laziness in a stack-safe way. Chained + * computation should be performed via .map and .flatMap. + * + * For more detailed information about how this method works see the + * documentation for `Eval[_]`. + * + * Example: + * {{{ + * scala> import cats.Foldable, cats.Eval, cats.implicits._ + * scala> val fa = Option(1) + * + * Folding by addition to zero: + * scala> val folded1 = Foldable[Option].foldRight(fa, Eval.now(0))((n, a) => a.map(_ + n)) + * Since `foldRight` yields a lazy computation, we need to force it to inspect the result: + * scala> folded1.value + * res0: Int = 1 + * + * With syntax extensions, we can write the same thing like this: + * scala> val folded2 = fa.foldRight(Eval.now(0))((n, a) => a.map(_ + n)) + * scala> folded2.value + * res1: Int = 1 + * + * Unfortunately, since `foldRight` is defined on many collections - this + * extension clashes with the operation defined in `Foldable`. + * + * To get past this and make sure you're getting the lazy `foldRight` defined + * in `Foldable`, there's an alias `foldr`: + * scala> val folded3 = fa.foldr(Eval.now(0))((n, a) => a.map(_ + n)) + * scala> folded3.value + * res1: Int = 1 + * }}} + */ def foldRight[A, B](fa: F[A], lb: Eval[B])(f: (A, Eval[B]) => Eval[B]): Eval[B] def reduceLeftToOption[A, B](fa: F[A])(f: A => B)(g: (B, A) => B): Option[B] = foldLeft(fa, Option.empty[B]) { case (Some(b), a) => Some(g(b, a)) - case (None, a) => Some(f(a)) + case (None, a) => Some(f(a)) } def reduceRightToOption[A, B](fa: F[A])(f: A => B)(g: (A, Eval[B]) => Eval[B]): Eval[Option[B]] = foldRight(fa, Now(Option.empty[B])) { (a, lb) => lb.flatMap { case Some(b) => g(a, Now(b)).map(Some(_)) - case None => Later(Some(f(a))) + case None => Later(Some(f(a))) } } /** - * Reduce the elements of this structure down to a single value by applying - * the provided aggregation function in a left-associative manner. - * - * @return `None` if the structure is empty, otherwise the result of combining - * the cumulative left-associative result of the `f` operation over all of the - * elements. - * - * @see [[reduceRightOption]] for a right-associative alternative. - * - * @see [[Reducible#reduceLeft]] for a version that doesn't need to return an - * `Option` for structures that are guaranteed to be non-empty. - * - * Example: - * {{{ - * scala> import cats.implicits._ - * scala> val l = List(6, 3, 2) - * This is equivalent to (6 - 3) - 2 - * scala> Foldable[List].reduceLeftOption(l)(_ - _) - * res0: Option[Int] = Some(1) - * - * scala> Foldable[List].reduceLeftOption(List.empty[Int])(_ - _) - * res1: Option[Int] = None - * }}} - */ + * Reduce the elements of this structure down to a single value by applying + * the provided aggregation function in a left-associative manner. + * + * @return `None` if the structure is empty, otherwise the result of combining + * the cumulative left-associative result of the `f` operation over all of the + * elements. + * + * @see [[reduceRightOption]] for a right-associative alternative. + * + * @see [[Reducible#reduceLeft]] for a version that doesn't need to return an + * `Option` for structures that are guaranteed to be non-empty. + * + * Example: + * {{{ + * scala> import cats.implicits._ + * scala> val l = List(6, 3, 2) + * This is equivalent to (6 - 3) - 2 + * scala> Foldable[List].reduceLeftOption(l)(_ - _) + * res0: Option[Int] = Some(1) + * + * scala> Foldable[List].reduceLeftOption(List.empty[Int])(_ - _) + * res1: Option[Int] = None + * }}} + */ def reduceLeftOption[A](fa: F[A])(f: (A, A) => A): Option[A] = reduceLeftToOption(fa)(identity)(f) /** - * Reduce the elements of this structure down to a single value by applying - * the provided aggregation function in a right-associative manner. - * - * @return `None` if the structure is empty, otherwise the result of combining - * the cumulative right-associative result of the `f` operation over the - * `A` elements. - * - * @see [[reduceLeftOption]] for a left-associative alternative - * - * @see [[Reducible#reduceRight]] for a version that doesn't need to return an - * `Option` for structures that are guaranteed to be non-empty. - * - * Example: - * {{{ - * scala> import cats.implicits._ - * scala> val l = List(6, 3, 2) - * This is eqivalent to 6 - (3 - 2) - * scala> Foldable[List].reduceRightOption(l)((current, rest) => rest.map(current - _)).value - * res0: Option[Int] = Some(5) - * - * scala> Foldable[List].reduceRightOption(List.empty[Int])((current, rest) => rest.map(current - _)).value - * res1: Option[Int] = None - * }}} - */ + * Reduce the elements of this structure down to a single value by applying + * the provided aggregation function in a right-associative manner. + * + * @return `None` if the structure is empty, otherwise the result of combining + * the cumulative right-associative result of the `f` operation over the + * `A` elements. + * + * @see [[reduceLeftOption]] for a left-associative alternative + * + * @see [[Reducible#reduceRight]] for a version that doesn't need to return an + * `Option` for structures that are guaranteed to be non-empty. + * + * Example: + * {{{ + * scala> import cats.implicits._ + * scala> val l = List(6, 3, 2) + * This is eqivalent to 6 - (3 - 2) + * scala> Foldable[List].reduceRightOption(l)((current, rest) => rest.map(current - _)).value + * res0: Option[Int] = Some(5) + * + * scala> Foldable[List].reduceRightOption(List.empty[Int])((current, rest) => rest.map(current - _)).value + * res1: Option[Int] = None + * }}} + */ def reduceRightOption[A](fa: F[A])(f: (A, Eval[A]) => Eval[A]): Eval[Option[A]] = reduceRightToOption(fa)(identity)(f) /** - * Find the minimum `A` item in this structure according to the `Order[A]`. - * - * @return `None` if the structure is empty, otherwise the minimum element - * wrapped in a `Some`. - * - * @see [[Reducible#minimum]] for a version that doesn't need to return an - * `Option` for structures that are guaranteed to be non-empty. - * - * @see [[maximumOption]] for maximum instead of minimum. - */ + * Find the minimum `A` item in this structure according to the `Order[A]`. + * + * @return `None` if the structure is empty, otherwise the minimum element + * wrapped in a `Some`. + * + * @see [[Reducible#minimum]] for a version that doesn't need to return an + * `Option` for structures that are guaranteed to be non-empty. + * + * @see [[maximumOption]] for maximum instead of minimum. + */ def minimumOption[A](fa: F[A])(implicit A: Order[A]): Option[A] = reduceLeftOption(fa)(A.min) /** - * Find the maximum `A` item in this structure according to the `Order[A]`. - * - * @return `None` if the structure is empty, otherwise the maximum element - * wrapped in a `Some`. - * - * @see [[Reducible#maximum]] for a version that doesn't need to return an - * `Option` for structures that are guaranteed to be non-empty. - * - * @see [[minimumOption]] for minimum instead of maximum. - */ + * Find the maximum `A` item in this structure according to the `Order[A]`. + * + * @return `None` if the structure is empty, otherwise the maximum element + * wrapped in a `Some`. + * + * @see [[Reducible#maximum]] for a version that doesn't need to return an + * `Option` for structures that are guaranteed to be non-empty. + * + * @see [[minimumOption]] for minimum instead of maximum. + */ def maximumOption[A](fa: F[A])(implicit A: Order[A]): Option[A] = reduceLeftOption(fa)(A.max) @@ -203,7 +202,7 @@ import Foldable.sentinel foldM[Either[A, ?], A, Long](fa, 0L) { (i, a) => if (i == idx) Left(a) else Right(i + 1L) } match { - case Left(a) => Some(a) + case Left(a) => Some(a) case Right(_) => None } @@ -215,21 +214,20 @@ import Foldable.sentinel else lb }.value - /** - * Like `collectFirst` from `scala.collection.Traversable` but takes `A => Option[B]` - * instead of `PartialFunction`s. - * {{{ - * scala> import cats.implicits._ - * scala> val keys = List(1, 2, 4, 5) - * scala> val map = Map(4 -> "Four", 5 -> "Five") - * scala> keys.collectFirstSome(map.get) - * res0: Option[String] = Some(Four) - * scala> val map2 = Map(6 -> "Six", 7 -> "Seven") - * scala> keys.collectFirstSome(map2.get) - * res1: Option[String] = None - * }}} - */ + * Like `collectFirst` from `scala.collection.Traversable` but takes `A => Option[B]` + * instead of `PartialFunction`s. + * {{{ + * scala> import cats.implicits._ + * scala> val keys = List(1, 2, 4, 5) + * scala> val map = Map(4 -> "Four", 5 -> "Five") + * scala> keys.collectFirstSome(map.get) + * res0: Option[String] = Some(Four) + * scala> val map2 = Map(6 -> "Six", 7 -> "Seven") + * scala> keys.collectFirstSome(map2.get) + * res1: Option[String] = None + * }}} + */ def collectFirstSome[A, B](fa: F[A])(f: A => Option[B]): Option[B] = foldRight(fa, Eval.now(Option.empty[B])) { (a, lb) => val ob = f(a) @@ -237,161 +235,166 @@ import Foldable.sentinel }.value /** - * Fold implemented using the given Monoid[A] instance. - */ + * Fold implemented using the given Monoid[A] instance. + */ def fold[A](fa: F[A])(implicit A: Monoid[A]): A = foldLeft(fa, A.empty) { (acc, a) => A.combine(acc, a) } /** - * Alias for [[fold]]. - */ + * Alias for [[fold]]. + */ def combineAll[A: Monoid](fa: F[A]): A = fold(fa) /** - * Fold implemented by mapping `A` values into `B` and then - * combining them using the given `Monoid[B]` instance. - */ + * Fold implemented by mapping `A` values into `B` and then + * combining them using the given `Monoid[B]` instance. + */ def foldMap[A, B](fa: F[A])(f: A => B)(implicit B: Monoid[B]): B = foldLeft(fa, B.empty)((b, a) => B.combine(b, f(a))) /** - * Perform a stack-safe monadic left fold from the source context `F` - * into the target monad `G`. - * - * This method can express short-circuiting semantics. Even when - * `fa` is an infinite structure, this method can potentially - * terminate if the `foldRight` implementation for `F` and the - * `tailRecM` implementation for `G` are sufficiently lazy. - * - * Instances for concrete structures (e.g. `List`) will often - * have a more efficient implementation than the default one - * in terms of `foldRight`. - */ + * Perform a stack-safe monadic left fold from the source context `F` + * into the target monad `G`. + * + * This method can express short-circuiting semantics. Even when + * `fa` is an infinite structure, this method can potentially + * terminate if the `foldRight` implementation for `F` and the + * `tailRecM` implementation for `G` are sufficiently lazy. + * + * Instances for concrete structures (e.g. `List`) will often + * have a more efficient implementation than the default one + * in terms of `foldRight`. + */ def foldM[G[_], A, B](fa: F[A], z: B)(f: (B, A) => G[B])(implicit G: Monad[G]): G[B] = { val src = Foldable.Source.fromFoldable(fa)(self) - G.tailRecM((z, src)) { case (b, src) => src.uncons match { - case Some((a, src)) => G.map(f(b, a))(b => Left((b, src.value))) - case None => G.pure(Right(b)) - }} + G.tailRecM((z, src)) { + case (b, src) => + src.uncons match { + case Some((a, src)) => G.map(f(b, a))(b => Left((b, src.value))) + case None => G.pure(Right(b)) + } + } } /** - * Alias for [[foldM]]. - */ + * Alias for [[foldM]]. + */ final def foldLeftM[G[_], A, B](fa: F[A], z: B)(f: (B, A) => G[B])(implicit G: Monad[G]): G[B] = foldM(fa, z)(f) /** - * Monadic folding on `F` by mapping `A` values to `G[B]`, combining the `B` - * values using the given `Monoid[B]` instance. - * - * Similar to [[foldM]], but using a `Monoid[B]`. - * - * {{{ - * scala> import cats.Foldable - * scala> import cats.implicits._ - * scala> val evenNumbers = List(2,4,6,8,10) - * scala> val evenOpt: Int => Option[Int] = - * | i => if (i % 2 == 0) Some(i) else None - * scala> Foldable[List].foldMapM(evenNumbers)(evenOpt) - * res0: Option[Int] = Some(30) - * scala> Foldable[List].foldMapM(evenNumbers :+ 11)(evenOpt) - * res1: Option[Int] = None - * }}} - */ + * Monadic folding on `F` by mapping `A` values to `G[B]`, combining the `B` + * values using the given `Monoid[B]` instance. + * + * Similar to [[foldM]], but using a `Monoid[B]`. + * + * {{{ + * scala> import cats.Foldable + * scala> import cats.implicits._ + * scala> val evenNumbers = List(2,4,6,8,10) + * scala> val evenOpt: Int => Option[Int] = + * | i => if (i % 2 == 0) Some(i) else None + * scala> Foldable[List].foldMapM(evenNumbers)(evenOpt) + * res0: Option[Int] = Some(30) + * scala> Foldable[List].foldMapM(evenNumbers :+ 11)(evenOpt) + * res1: Option[Int] = None + * }}} + */ def foldMapM[G[_], A, B](fa: F[A])(f: A => G[B])(implicit G: Monad[G], B: Monoid[B]): G[B] = foldM(fa, B.empty)((b, a) => G.map(f(a))(B.combine(b, _))) /** - * Traverse `F[A]` using `Applicative[G]`. - * - * `A` values will be mapped into `G[B]` and combined using - * `Applicative#map2`. - * - * For example: - * - * {{{ - * scala> import cats.implicits._ - * scala> def parseInt(s: String): Option[Int] = Either.catchOnly[NumberFormatException](s.toInt).toOption - * scala> val F = Foldable[List] - * scala> F.traverse_(List("333", "444"))(parseInt) - * res0: Option[Unit] = Some(()) - * scala> F.traverse_(List("333", "zzz"))(parseInt) - * res1: Option[Unit] = None - * }}} - * - * This method is primarily useful when `G[_]` represents an action - * or effect, and the specific `A` aspect of `G[A]` is not otherwise - * needed. - */ + * Traverse `F[A]` using `Applicative[G]`. + * + * `A` values will be mapped into `G[B]` and combined using + * `Applicative#map2`. + * + * For example: + * + * {{{ + * scala> import cats.implicits._ + * scala> def parseInt(s: String): Option[Int] = Either.catchOnly[NumberFormatException](s.toInt).toOption + * scala> val F = Foldable[List] + * scala> F.traverse_(List("333", "444"))(parseInt) + * res0: Option[Unit] = Some(()) + * scala> F.traverse_(List("333", "zzz"))(parseInt) + * res1: Option[Unit] = None + * }}} + * + * This method is primarily useful when `G[_]` represents an action + * or effect, and the specific `A` aspect of `G[A]` is not otherwise + * needed. + */ def traverse_[G[_], A, B](fa: F[A])(f: A => G[B])(implicit G: Applicative[G]): G[Unit] = foldRight(fa, Always(G.pure(()))) { (a, acc) => - G.map2Eval(f(a), acc) { (_, _) => () } + G.map2Eval(f(a), acc) { (_, _) => + () + } }.value /** - * Sequence `F[G[A]]` using `Applicative[G]`. - * - * This is similar to `traverse_` except it operates on `F[G[A]]` - * values, so no additional functions are needed. - * - * For example: - * - * {{{ - * scala> import cats.implicits._ - * scala> val F = Foldable[List] - * scala> F.sequence_(List(Option(1), Option(2), Option(3))) - * res0: Option[Unit] = Some(()) - * scala> F.sequence_(List(Option(1), None, Option(3))) - * res1: Option[Unit] = None - * }}} - */ + * Sequence `F[G[A]]` using `Applicative[G]`. + * + * This is similar to `traverse_` except it operates on `F[G[A]]` + * values, so no additional functions are needed. + * + * For example: + * + * {{{ + * scala> import cats.implicits._ + * scala> val F = Foldable[List] + * scala> F.sequence_(List(Option(1), Option(2), Option(3))) + * res0: Option[Unit] = Some(()) + * scala> F.sequence_(List(Option(1), None, Option(3))) + * res1: Option[Unit] = None + * }}} + */ def sequence_[G[_]: Applicative, A](fga: F[G[A]]): G[Unit] = traverse_(fga)(identity) /** - * Fold implemented using the given `MonoidK[G]` instance. - * - * This method is identical to fold, except that we use the universal monoid (`MonoidK[G]`) - * to get a `Monoid[G[A]]` instance. - * - * For example: - * - * {{{ - * scala> import cats.implicits._ - * scala> val F = Foldable[List] - * scala> F.foldK(List(1 :: 2 :: Nil, 3 :: 4 :: 5 :: Nil)) - * res0: List[Int] = List(1, 2, 3, 4, 5) - * }}} - */ + * Fold implemented using the given `MonoidK[G]` instance. + * + * This method is identical to fold, except that we use the universal monoid (`MonoidK[G]`) + * to get a `Monoid[G[A]]` instance. + * + * For example: + * + * {{{ + * scala> import cats.implicits._ + * scala> val F = Foldable[List] + * scala> F.foldK(List(1 :: 2 :: Nil, 3 :: 4 :: 5 :: Nil)) + * res0: List[Int] = List(1, 2, 3, 4, 5) + * }}} + */ def foldK[G[_], A](fga: F[G[A]])(implicit G: MonoidK[G]): G[A] = fold(fga)(G.algebra) /** - * Find the first element matching the predicate, if one exists. - */ + * Find the first element matching the predicate, if one exists. + */ def find[A](fa: F[A])(f: A => Boolean): Option[A] = foldRight(fa, Now(Option.empty[A])) { (a, lb) => if (f(a)) Now(Some(a)) else lb }.value /** - * Check whether at least one element satisfies the predicate. - * - * If there are no elements, the result is `false`. - */ + * Check whether at least one element satisfies the predicate. + * + * If there are no elements, the result is `false`. + */ override def exists[A](fa: F[A])(p: A => Boolean): Boolean = foldRight(fa, Eval.False) { (a, lb) => if (p(a)) Eval.True else lb }.value /** - * Check whether all elements satisfy the predicate. - * - * If there are no elements, the result is `true`. - */ + * Check whether all elements satisfy the predicate. + * + * If there are no elements, the result is `true`. + */ override def forall[A](fa: F[A])(p: A => Boolean): Boolean = foldRight(fa, Eval.True) { (a, lb) => if (p(a)) lb else Eval.False @@ -424,14 +427,13 @@ import Foldable.sentinel * res4: Option[Boolean] = None * }}} */ - def existsM[G[_], A](fa: F[A])(p: A => G[Boolean])(implicit G: Monad[G]): G[Boolean] = { - G.tailRecM(Foldable.Source.fromFoldable(fa)(self)) { - src => src.uncons match { + def existsM[G[_], A](fa: F[A])(p: A => G[Boolean])(implicit G: Monad[G]): G[Boolean] = + G.tailRecM(Foldable.Source.fromFoldable(fa)(self)) { src => + src.uncons match { case Some((a, src)) => G.map(p(a))(bb => if (bb) Right(true) else Left(src.value)) - case None => G.pure(Right(false)) + case None => G.pure(Right(false)) } } - } /** * Check whether all elements satisfy the effectful predicate. @@ -460,18 +462,17 @@ import Foldable.sentinel * res4: Option[Boolean] = None * }}} */ - def forallM[G[_], A](fa: F[A])(p: A => G[Boolean])(implicit G: Monad[G]): G[Boolean] = { - G.tailRecM(Foldable.Source.fromFoldable(fa)(self)) { - src => src.uncons match { + def forallM[G[_], A](fa: F[A])(p: A => G[Boolean])(implicit G: Monad[G]): G[Boolean] = + G.tailRecM(Foldable.Source.fromFoldable(fa)(self)) { src => + src.uncons match { case Some((a, src)) => G.map(p(a))(bb => if (!bb) Right(false) else Left(src.value)) - case None => G.pure(Right(true)) + case None => G.pure(Right(true)) } } - } /** - * Convert F[A] to a List[A]. - */ + * Convert F[A] to a List[A]. + */ def toList[A](fa: F[A]): List[A] = foldLeft(fa, mutable.ListBuffer.empty[A]) { (buf, a) => buf += a @@ -496,41 +497,44 @@ import Foldable.sentinel implicit val mb: Monoid[F[B]] = A.algebra[B] implicit val mc: Monoid[F[C]] = A.algebra[C] - foldMap(fa)(a => f(a) match { - case Right(c) => (A.empty[B], A.pure(c)) - case Left(b) => (A.pure(b), A.empty[C]) - }) + foldMap(fa)( + a => + f(a) match { + case Right(c) => (A.empty[B], A.pure(c)) + case Left(b) => (A.pure(b), A.empty[C]) + } + ) } /** - * Convert F[A] to a List[A], only including elements which match `p`. - */ + * Convert F[A] to a List[A], only including elements which match `p`. + */ def filter_[A](fa: F[A])(p: A => Boolean): List[A] = foldLeft(fa, mutable.ListBuffer.empty[A]) { (buf, a) => if (p(a)) buf += a else buf }.toList /** - * Convert F[A] to a List[A], retaining only initial elements which - * match `p`. - */ + * Convert F[A] to a List[A], retaining only initial elements which + * match `p`. + */ def takeWhile_[A](fa: F[A])(p: A => Boolean): List[A] = foldRight(fa, Now(List.empty[A])) { (a, llst) => if (p(a)) llst.map(a :: _) else Now(Nil) }.value /** - * Convert F[A] to a List[A], dropping all initial elements which - * match `p`. - */ + * Convert F[A] to a List[A], dropping all initial elements which + * match `p`. + */ def dropWhile_[A](fa: F[A])(p: A => Boolean): List[A] = foldLeft(fa, mutable.ListBuffer.empty[A]) { (buf, a) => if (buf.nonEmpty || !p(a)) buf += a else buf }.toList /** - * Returns true if there are no elements. Otherwise false. - */ + * Returns true if there are no elements. Otherwise false. + */ override def isEmpty[A](fa: F[A]): Boolean = foldRight(fa, Eval.True)((_, _) => Eval.False).value @@ -538,20 +542,20 @@ import Foldable.sentinel !isEmpty(fa) /** - * Intercalate/insert an element between the existing elements while folding. - * - * {{{ - * scala> import cats.implicits._ - * scala> Foldable[List].intercalate(List("a","b","c"), "-") - * res0: String = a-b-c - * scala> Foldable[List].intercalate(List("a"), "-") - * res1: String = a - * scala> Foldable[List].intercalate(List.empty[String], "-") - * res2: String = "" - * scala> Foldable[Vector].intercalate(Vector(1,2,3), 1) - * res3: Int = 8 - * }}} - */ + * Intercalate/insert an element between the existing elements while folding. + * + * {{{ + * scala> import cats.implicits._ + * scala> Foldable[List].intercalate(List("a","b","c"), "-") + * res0: String = a-b-c + * scala> Foldable[List].intercalate(List("a"), "-") + * res1: String = a + * scala> Foldable[List].intercalate(List.empty[String], "-") + * res2: String = "" + * scala> Foldable[Vector].intercalate(Vector(1,2,3), 1) + * res3: Int = 8 + * }}} + */ def intercalate[A](fa: F[A], a: A)(implicit A: Monoid[A]): A = A.combineAll(intersperseList(toList(fa), a)) @@ -560,7 +564,7 @@ import Foldable.sentinel val it = xs.iterator if (it.hasNext) { bld += it.next - while(it.hasNext) { + while (it.hasNext) { bld += x bld += it.next } @@ -581,7 +585,7 @@ import Foldable.sentinel } object Foldable { - private val sentinel: Function1[Any, Any] = new scala.runtime.AbstractFunction1[Any, Any]{ def apply(a: Any) = this } + private val sentinel: Function1[Any, Any] = new scala.runtime.AbstractFunction1[Any, Any] { def apply(a: Any) = this } def iterateRight[A, B](iterable: Iterable[A], lb: Eval[B])(f: (A, Eval[B]) => Eval[B]): Eval[B] = { def loop(it: Iterator[A]): Eval[B] = @@ -590,18 +594,17 @@ object Foldable { Eval.always(iterable.iterator).flatMap(loop) } - /** - * Isomorphic to - * - * type Source[+A] = () => Option[(A, Source[A])] - * - * (except that recursive type aliases are not allowed). - * - * It could be made a value class after - * https://github.com/scala/bug/issues/9600 is resolved. - */ - private[cats] sealed abstract class Source[+A] { + * Isomorphic to + * + * type Source[+A] = () => Option[(A, Source[A])] + * + * (except that recursive type aliases are not allowed). + * + * It could be made a value class after + * https://github.com/scala/bug/issues/9600 is resolved. + */ + sealed abstract private[cats] class Source[+A] { def uncons: Option[(A, Eval[Source[A]])] } @@ -615,8 +618,6 @@ object Foldable { } def fromFoldable[F[_], A](fa: F[A])(implicit F: Foldable[F]): Source[A] = - F.foldRight[A, Source[A]](fa, Now(Empty))((a, evalSrc) => - Later(cons(a, evalSrc)) - ).value + F.foldRight[A, Source[A]](fa, Now(Empty))((a, evalSrc) => Later(cons(a, evalSrc))).value } } diff --git a/core/src/main/scala/cats/Functor.scala b/core/src/main/scala/cats/Functor.scala index ec5425d0be3..44f4e9047bf 100644 --- a/core/src/main/scala/cats/Functor.scala +++ b/core/src/main/scala/cats/Functor.scala @@ -3,12 +3,12 @@ package cats import simulacrum.typeclass /** - * Functor. - * - * The name is short for "covariant functor". - * - * Must obey the laws defined in cats.laws.FunctorLaws. - */ + * Functor. + * + * The name is short for "covariant functor". + * + * Must obey the laws defined in cats.laws.FunctorLaws. + */ @typeclass trait Functor[F[_]] extends Invariant[F] { self => def map[A, B](fa: F[A])(f: A => B): F[B] @@ -17,131 +17,131 @@ import simulacrum.typeclass // derived methods /** - * Alias for [[map]], since [[map]] can't be injected as syntax if - * the implementing type already had a built-in `.map` method. - * - * Example: - * {{{ - * scala> import cats.implicits._ - * - * scala> val m: Map[Int, String] = Map(1 -> "hi", 2 -> "there", 3 -> "you") - * - * scala> m.fmap(_ ++ "!") - * res0: Map[Int,String] = Map(1 -> hi!, 2 -> there!, 3 -> you!) - * }}} - */ + * Alias for [[map]], since [[map]] can't be injected as syntax if + * the implementing type already had a built-in `.map` method. + * + * Example: + * {{{ + * scala> import cats.implicits._ + * + * scala> val m: Map[Int, String] = Map(1 -> "hi", 2 -> "there", 3 -> "you") + * + * scala> m.fmap(_ ++ "!") + * res0: Map[Int,String] = Map(1 -> hi!, 2 -> there!, 3 -> you!) + * }}} + */ final def fmap[A, B](fa: F[A])(f: A => B): F[B] = map(fa)(f) /** - * Lifts natural subtyping covariance of covariant Functors. - * - * NOTE: In certain (perhaps contrived) situations that rely on universal - * equality this can result in a `ClassCastException`, because it is - * implemented as a type cast. It could be implemented as `map(identity)`, but - * according to the functor laws, that should be equal to `fa`, and a type - * cast is often much more performant. - * See [[https://github.com/typelevel/cats/issues/1080#issuecomment-225892635 this example]] - * of `widen` creating a `ClassCastException`. - * - * Example: - * {{{ - * scala> import cats.Functor - * scala> import cats.implicits.catsStdInstancesForOption - * - * scala> val s = Some(42) - * scala> Functor[Option].widen(s) - * res0: Option[Int] = Some(42) - * }}} - */ + * Lifts natural subtyping covariance of covariant Functors. + * + * NOTE: In certain (perhaps contrived) situations that rely on universal + * equality this can result in a `ClassCastException`, because it is + * implemented as a type cast. It could be implemented as `map(identity)`, but + * according to the functor laws, that should be equal to `fa`, and a type + * cast is often much more performant. + * See [[https://github.com/typelevel/cats/issues/1080#issuecomment-225892635 this example]] + * of `widen` creating a `ClassCastException`. + * + * Example: + * {{{ + * scala> import cats.Functor + * scala> import cats.implicits.catsStdInstancesForOption + * + * scala> val s = Some(42) + * scala> Functor[Option].widen(s) + * res0: Option[Int] = Some(42) + * }}} + */ def widen[A, B >: A](fa: F[A]): F[B] = fa.asInstanceOf[F[B]] /** - * Lift a function f to operate on Functors - * - * Example: - * {{{ - * scala> import cats.Functor - * scala> import cats.implicits.catsStdInstancesForOption - * - * scala> val o = Option(42) - * scala> Functor[Option].lift((x: Int) => x + 10)(o) - * res0: Option[Int] = Some(52) - * }}} - */ + * Lift a function f to operate on Functors + * + * Example: + * {{{ + * scala> import cats.Functor + * scala> import cats.implicits.catsStdInstancesForOption + * + * scala> val o = Option(42) + * scala> Functor[Option].lift((x: Int) => x + 10)(o) + * res0: Option[Int] = Some(52) + * }}} + */ def lift[A, B](f: A => B): F[A] => F[B] = map(_)(f) /** - * Empty the fa of the values, preserving the structure - * - * Example: - * {{{ - * scala> import cats.Functor - * scala> import cats.implicits.catsStdInstancesForList - * - * scala> Functor[List].void(List(1,2,3)) - * res0: List[Unit] = List((), (), ()) - * }}} - */ + * Empty the fa of the values, preserving the structure + * + * Example: + * {{{ + * scala> import cats.Functor + * scala> import cats.implicits.catsStdInstancesForList + * + * scala> Functor[List].void(List(1,2,3)) + * res0: List[Unit] = List((), (), ()) + * }}} + */ def void[A](fa: F[A]): F[Unit] = as(fa, ()) /** - * Tuple the values in fa with the result of applying a function - * with the value - * - * Example: - * {{{ - * scala> import cats.Functor - * scala> import cats.implicits.catsStdInstancesForOption - * - * scala> Functor[Option].fproduct(Option(42))(_.toString) - * res0: Option[(Int, String)] = Some((42,42)) - * }}} - */ + * Tuple the values in fa with the result of applying a function + * with the value + * + * Example: + * {{{ + * scala> import cats.Functor + * scala> import cats.implicits.catsStdInstancesForOption + * + * scala> Functor[Option].fproduct(Option(42))(_.toString) + * res0: Option[(Int, String)] = Some((42,42)) + * }}} + */ def fproduct[A, B](fa: F[A])(f: A => B): F[(A, B)] = map(fa)(a => a -> f(a)) /** - * Replaces the `A` value in `F[A]` with the supplied value. - * - * Example: - * - * {{{ - * scala> import cats.Functor - * scala> import cats.implicits.catsStdInstancesForList - * - * scala> Functor[List].as(List(1,2,3), "hello") - * res0: List[String] = List(hello, hello, hello) - * }}} - */ + * Replaces the `A` value in `F[A]` with the supplied value. + * + * Example: + * + * {{{ + * scala> import cats.Functor + * scala> import cats.implicits.catsStdInstancesForList + * + * scala> Functor[List].as(List(1,2,3), "hello") + * res0: List[String] = List(hello, hello, hello) + * }}} + */ def as[A, B](fa: F[A], b: B): F[B] = map(fa)(_ => b) /** - * Tuples the `A` value in `F[A]` with the supplied `B` value, with the `B` value on the left. - * - * Example: - * {{{ - * scala> import scala.collection.immutable.Queue - * scala> import cats.Functor - * scala> import cats.implicits.catsStdInstancesForQueue - * - * scala> Functor[Queue].tupleLeft(Queue("hello", "world"), 42) - * res0: scala.collection.immutable.Queue[(Int, String)] = Queue((42,hello), (42,world)) - * }}} - */ + * Tuples the `A` value in `F[A]` with the supplied `B` value, with the `B` value on the left. + * + * Example: + * {{{ + * scala> import scala.collection.immutable.Queue + * scala> import cats.Functor + * scala> import cats.implicits.catsStdInstancesForQueue + * + * scala> Functor[Queue].tupleLeft(Queue("hello", "world"), 42) + * res0: scala.collection.immutable.Queue[(Int, String)] = Queue((42,hello), (42,world)) + * }}} + */ def tupleLeft[A, B](fa: F[A], b: B): F[(B, A)] = map(fa)(a => (b, a)) /** - * Tuples the `A` value in `F[A]` with the supplied `B` value, with the `B` value on the right. - * - * Example: - * {{{ - * scala> import scala.collection.immutable.Queue - * scala> import cats.Functor - * scala> import cats.implicits.catsStdInstancesForQueue - * - * scala> Functor[Queue].tupleRight(Queue("hello", "world"), 42) - * res0: scala.collection.immutable.Queue[(String, Int)] = Queue((hello,42), (world,42)) - * }}} - */ + * Tuples the `A` value in `F[A]` with the supplied `B` value, with the `B` value on the right. + * + * Example: + * {{{ + * scala> import scala.collection.immutable.Queue + * scala> import cats.Functor + * scala> import cats.implicits.catsStdInstancesForQueue + * + * scala> Functor[Queue].tupleRight(Queue("hello", "world"), 42) + * res0: scala.collection.immutable.Queue[(String, Int)] = Queue((hello,42), (world,42)) + * }}} + */ def tupleRight[A, B](fa: F[A], b: B): F[(A, B)] = map(fa)(a => (a, b)) def compose[G[_]: Functor]: Functor[λ[α => F[G[α]]]] = diff --git a/core/src/main/scala/cats/FunctorFilter.scala b/core/src/main/scala/cats/FunctorFilter.scala index 4abcc08b253..f2b30bce690 100644 --- a/core/src/main/scala/cats/FunctorFilter.scala +++ b/core/src/main/scala/cats/FunctorFilter.scala @@ -3,67 +3,67 @@ package cats import simulacrum.typeclass /** - * `FunctorFilter[F]` allows you to `map` and filter out elements simultaneously. - */ + * `FunctorFilter[F]` allows you to `map` and filter out elements simultaneously. + */ @typeclass trait FunctorFilter[F[_]] extends Serializable { def functor: Functor[F] /** - * A combined `map` and `filter`. Filtering is handled via `Option` - * instead of `Boolean` such that the output type `B` can be different than - * the input type `A`. - * - * Example: - * {{{ - * scala> import cats.implicits._ - * scala> val m: Map[Int, String] = Map(1 -> "one", 3 -> "three") - * scala> val l: List[Int] = List(1, 2, 3, 4) - * scala> def asString(i: Int): Option[String] = m.get(i) - * scala> l.mapFilter(i => m.get(i)) - * res0: List[String] = List(one, three) - * }}} - */ + * A combined `map` and `filter`. Filtering is handled via `Option` + * instead of `Boolean` such that the output type `B` can be different than + * the input type `A`. + * + * Example: + * {{{ + * scala> import cats.implicits._ + * scala> val m: Map[Int, String] = Map(1 -> "one", 3 -> "three") + * scala> val l: List[Int] = List(1, 2, 3, 4) + * scala> def asString(i: Int): Option[String] = m.get(i) + * scala> l.mapFilter(i => m.get(i)) + * res0: List[String] = List(one, three) + * }}} + */ def mapFilter[A, B](fa: F[A])(f: A => Option[B]): F[B] /** - * Similar to [[mapFilter]] but uses a partial function instead of a function - * that returns an `Option`. - * - * Example: - * {{{ - * scala> import cats.implicits._ - * scala> val l: List[Int] = List(1, 2, 3, 4) - * scala> FunctorFilter[List].collect(l){ - * | case 1 => "one" - * | case 3 => "three" - * | } - * res0: List[String] = List(one, three) - * }}} - */ + * Similar to [[mapFilter]] but uses a partial function instead of a function + * that returns an `Option`. + * + * Example: + * {{{ + * scala> import cats.implicits._ + * scala> val l: List[Int] = List(1, 2, 3, 4) + * scala> FunctorFilter[List].collect(l){ + * | case 1 => "one" + * | case 3 => "three" + * | } + * res0: List[String] = List(one, three) + * }}} + */ def collect[A, B](fa: F[A])(f: PartialFunction[A, B]): F[B] = mapFilter(fa)(f.lift) /** - * "Flatten" out a structure by collapsing `Option`s. - * Equivalent to using `mapFilter` with `identity`. - * - * Example: - * {{{ - * scala> import cats.implicits._ - * scala> val l: List[Option[Int]] = List(Some(1), None, Some(3), None) - * scala> l.flattenOption - * res0: List[Int] = List(1, 3) - * }}} - */ + * "Flatten" out a structure by collapsing `Option`s. + * Equivalent to using `mapFilter` with `identity`. + * + * Example: + * {{{ + * scala> import cats.implicits._ + * scala> val l: List[Option[Int]] = List(Some(1), None, Some(3), None) + * scala> l.flattenOption + * res0: List[Int] = List(1, 3) + * }}} + */ def flattenOption[A](fa: F[Option[A]]): F[A] = mapFilter(fa)(identity) /** - * Apply a filter to a structure such that the output structure contains all - * `A` elements in the input structure that satisfy the predicate `f` but none - * that don't. - */ + * Apply a filter to a structure such that the output structure contains all + * `A` elements in the input structure that satisfy the predicate `f` but none + * that don't. + */ def filter[A](fa: F[A])(f: A => Boolean): F[A] = mapFilter(fa)(a => if (f(a)) Some(a) else None) } diff --git a/core/src/main/scala/cats/Inject.scala b/core/src/main/scala/cats/Inject.scala index 04c075eb46c..df5403258cb 100644 --- a/core/src/main/scala/cats/Inject.scala +++ b/core/src/main/scala/cats/Inject.scala @@ -25,7 +25,7 @@ abstract class Inject[A, B] { final def unapply(b: B): Option[A] = prj(b) } -private[cats] sealed abstract class InjectInstances { +sealed abstract private[cats] class InjectInstances { implicit def catsReflexiveInjectInstance[A]: Inject[A, A] = new Inject[A, A] { val inj = identity(_: A) diff --git a/core/src/main/scala/cats/InjectK.scala b/core/src/main/scala/cats/InjectK.scala index f2b8d805593..497e9e82102 100644 --- a/core/src/main/scala/cats/InjectK.scala +++ b/core/src/main/scala/cats/InjectK.scala @@ -32,7 +32,7 @@ abstract class InjectK[F[_], G[_]] { final def unapply[A](ga: G[A]): Option[F[A]] = prj(ga) } -private[cats] sealed abstract class InjectKInstances { +sealed abstract private[cats] class InjectKInstances { implicit def catsReflexiveInjectKInstance[F[_]]: InjectK[F, F] = new InjectK[F, F] { val inj = FunctionK.id[F] @@ -49,7 +49,7 @@ private[cats] sealed abstract class InjectKInstances { implicit def catsRightInjectKInstance[F[_], G[_], H[_]](implicit I: InjectK[F, G]): InjectK[F, EitherK[H, G, ?]] = new InjectK[F, EitherK[H, G, ?]] { - val inj = λ[FunctionK[G, EitherK[H, G, ?]]](EitherK.rightc(_)) compose I.inj + val inj = λ[FunctionK[G, EitherK[H, G, ?]]](EitherK.rightc(_)).compose(I.inj) val prj = λ[FunctionK[EitherK[H, G, ?], λ[α => Option[F[α]]]]](_.run.right.toOption.flatMap(I.prj(_))) } diff --git a/core/src/main/scala/cats/Invariant.scala b/core/src/main/scala/cats/Invariant.scala index ccaf7af3881..ac7895cdca6 100644 --- a/core/src/main/scala/cats/Invariant.scala +++ b/core/src/main/scala/cats/Invariant.scala @@ -2,25 +2,26 @@ package cats import cats.kernel._ import simulacrum.typeclass + /** - * Must obey the laws defined in cats.laws.InvariantLaws. - */ + * Must obey the laws defined in cats.laws.InvariantLaws. + */ @typeclass trait Invariant[F[_]] { self => /** - * Transform an `F[A]` into an `F[B]` by providing a transformation from `A` - * to `B` and one from `B` to `A`. - * - * Example: - * {{{ - * scala> import cats.implicits._ - * scala> import scala.concurrent.duration._ - * scala> val durSemigroup: Semigroup[FiniteDuration] = - * | Invariant[Semigroup].imap(Semigroup[Long])(Duration.fromNanos)(_.toNanos) - * scala> durSemigroup.combine(2.seconds, 3.seconds) - * res1: FiniteDuration = 5 seconds - * }}} - */ + * Transform an `F[A]` into an `F[B]` by providing a transformation from `A` + * to `B` and one from `B` to `A`. + * + * Example: + * {{{ + * scala> import cats.implicits._ + * scala> import scala.concurrent.duration._ + * scala> val durSemigroup: Semigroup[FiniteDuration] = + * | Invariant[Semigroup].imap(Semigroup[Long])(Duration.fromNanos)(_.toNanos) + * scala> durSemigroup.combine(2.seconds, 3.seconds) + * res1: FiniteDuration = 5 seconds + * }}} + */ def imap[A, B](fa: F[A])(f: A => B)(g: B => A): F[B] def compose[G[_]: Invariant]: Invariant[λ[α => F[G[α]]]] = @@ -73,8 +74,6 @@ object Invariant { } - - implicit val catsInvariantCommutativeMonoid: Invariant[CommutativeMonoid] = new Invariant[CommutativeMonoid] { def imap[A, B](fa: CommutativeMonoid[A])(f: A => B)(g: B => A): CommutativeMonoid[B] = new CommutativeMonoid[B] { @@ -97,7 +96,6 @@ object Invariant { } - implicit val catsInvariantGroup: Invariant[Group] = new Invariant[Group] { def imap[A, B](fa: Group[A])(f: A => B)(g: B => A): Group[B] = new Group[B] { diff --git a/core/src/main/scala/cats/InvariantMonoidal.scala b/core/src/main/scala/cats/InvariantMonoidal.scala index d5eeb5498c8..892c7c1c966 100644 --- a/core/src/main/scala/cats/InvariantMonoidal.scala +++ b/core/src/main/scala/cats/InvariantMonoidal.scala @@ -3,11 +3,12 @@ package cats import simulacrum.typeclass /** - * Invariant version of a Monoidal. - * - * Must obey the laws defined in cats.laws.InvariantMonoidalLaws. - */ + * Invariant version of a Monoidal. + * + * Must obey the laws defined in cats.laws.InvariantMonoidalLaws. + */ @typeclass trait InvariantMonoidal[F[_]] extends InvariantSemigroupal[F] { + /** * `point` lifts any value into a Monoidal Functor. * @@ -23,10 +24,10 @@ import simulacrum.typeclass def unit: F[Unit] - } object InvariantMonoidal { + /** * Gives a `Monoid` instance if A itself has a `Monoid` instance. */ @@ -34,7 +35,8 @@ object InvariantMonoidal { new InvariantMonoidalMonoid[F, A](F, A) } - -private[cats] class InvariantMonoidalMonoid[F[_], A](f: InvariantMonoidal[F], monoid: Monoid[A]) extends InvariantSemigroupalSemigroup(f, monoid) with Monoid[F[A]] { +private[cats] class InvariantMonoidalMonoid[F[_], A](f: InvariantMonoidal[F], monoid: Monoid[A]) + extends InvariantSemigroupalSemigroup(f, monoid) + with Monoid[F[A]] { def empty: F[A] = f.point(monoid.empty) } diff --git a/core/src/main/scala/cats/InvariantSemigroupal.scala b/core/src/main/scala/cats/InvariantSemigroupal.scala index a323f933a76..5c127a22d75 100644 --- a/core/src/main/scala/cats/InvariantSemigroupal.scala +++ b/core/src/main/scala/cats/InvariantSemigroupal.scala @@ -8,15 +8,16 @@ import simulacrum.typeclass */ @typeclass trait InvariantSemigroupal[F[_]] extends Semigroupal[F] with Invariant[F] { self => - def composeApply[G[_]: Apply]: InvariantSemigroupal[λ[α => F[G[α]]]] = - new ComposedInvariantApplySemigroupal[F, G] { - def F = self - def G = Apply[G] - } + def composeApply[G[_]: Apply]: InvariantSemigroupal[λ[α => F[G[α]]]] = + new ComposedInvariantApplySemigroupal[F, G] { + def F = self + def G = Apply[G] + } } object InvariantSemigroupal extends SemigroupalArityFunctions { + /** * Gives a `Semigroup` instance if A itself has a `Semigroup` instance. */ @@ -24,7 +25,8 @@ object InvariantSemigroupal extends SemigroupalArityFunctions { new InvariantSemigroupalSemigroup[F, A](F, A) } -private[cats] class InvariantSemigroupalSemigroup[F[_], A](f: InvariantSemigroupal[F], sg: Semigroup[A]) extends Semigroup[F[A]] { +private[cats] class InvariantSemigroupalSemigroup[F[_], A](f: InvariantSemigroupal[F], sg: Semigroup[A]) + extends Semigroup[F[A]] { def combine(a: F[A], b: F[A]): F[A] = InvariantSemigroupal.imap2(a, b)(sg.combine)(a => (a, a))(f, f) } diff --git a/core/src/main/scala/cats/Monad.scala b/core/src/main/scala/cats/Monad.scala index fa4d05079c5..86af953e680 100644 --- a/core/src/main/scala/cats/Monad.scala +++ b/core/src/main/scala/cats/Monad.scala @@ -3,88 +3,94 @@ package cats import simulacrum.typeclass /** - * Monad. - * - * Allows composition of dependent effectful functions. - * - * See: [[http://homepages.inf.ed.ac.uk/wadler/papers/marktoberdorf/baastad.pdf Monads for functional programming]] - * - * Must obey the laws defined in cats.laws.MonadLaws. - */ + * Monad. + * + * Allows composition of dependent effectful functions. + * + * See: [[http://homepages.inf.ed.ac.uk/wadler/papers/marktoberdorf/baastad.pdf Monads for functional programming]] + * + * Must obey the laws defined in cats.laws.MonadLaws. + */ @typeclass trait Monad[F[_]] extends FlatMap[F] with Applicative[F] { override def map[A, B](fa: F[A])(f: A => B): F[B] = flatMap(fa)(a => pure(f(a))) /** - * Execute an action repeatedly as long as the given `Boolean` expression - * returns `true`. The condition is evaluated before the loop body. - * Collects the results into an arbitrary `Alternative` value, such as a `Vector`. - * This implementation uses append on each evaluation result, - * so avoid data structures with non-constant append performance, e.g. `List`. - */ + * Execute an action repeatedly as long as the given `Boolean` expression + * returns `true`. The condition is evaluated before the loop body. + * Collects the results into an arbitrary `Alternative` value, such as a `Vector`. + * This implementation uses append on each evaluation result, + * so avoid data structures with non-constant append performance, e.g. `List`. + */ def whileM[G[_], A](p: F[Boolean])(body: => F[A])(implicit G: Alternative[G]): F[G[A]] = { val b = Eval.later(body) - tailRecM[G[A], G[A]](G.empty)(xs => ifM(p)( - ifTrue = { - map(b.value) { bv => - Left(G.combineK(xs, G.pure(bv))) - } - }, - ifFalse = pure(Right(xs)) - )) + tailRecM[G[A], G[A]](G.empty)( + xs => + ifM(p)( + ifTrue = { + map(b.value) { bv => + Left(G.combineK(xs, G.pure(bv))) + } + }, + ifFalse = pure(Right(xs)) + ) + ) } /** - * Execute an action repeatedly as long as the given `Boolean` expression - * returns `true`. The condition is evaluated before the loop body. - * Discards results. - */ + * Execute an action repeatedly as long as the given `Boolean` expression + * returns `true`. The condition is evaluated before the loop body. + * Discards results. + */ def whileM_[A](p: F[Boolean])(body: => F[A]): F[Unit] = { val continue: Either[Unit, Unit] = Left(()) val stop: F[Either[Unit, Unit]] = pure(Right(())) val b = Eval.later(body) - tailRecM(())(_ => ifM(p)( - ifTrue = { - map(b.value)(_ => continue) - }, - ifFalse = stop - )) + tailRecM(())( + _ => + ifM(p)( + ifTrue = { + map(b.value)(_ => continue) + }, + ifFalse = stop + ) + ) } /** - * Execute an action repeatedly until the `Boolean` condition returns `true`. - * The condition is evaluated after the loop body. Collects results into an - * arbitrary `Alternative` value, such as a `Vector`. - * This implementation uses append on each evaluation result, - * so avoid data structures with non-constant append performance, e.g. `List`. - */ + * Execute an action repeatedly until the `Boolean` condition returns `true`. + * The condition is evaluated after the loop body. Collects results into an + * arbitrary `Alternative` value, such as a `Vector`. + * This implementation uses append on each evaluation result, + * so avoid data structures with non-constant append performance, e.g. `List`. + */ def untilM[G[_], A](f: F[A])(cond: => F[Boolean])(implicit G: Alternative[G]): F[G[A]] = { val p = Eval.later(cond) flatMap(f)(x => map(whileM(map(p.value)(!_))(f))(xs => G.combineK(G.pure(x), xs))) } /** - * Execute an action repeatedly until the `Boolean` condition returns `true`. - * The condition is evaluated after the loop body. Discards results. - */ + * Execute an action repeatedly until the `Boolean` condition returns `true`. + * The condition is evaluated after the loop body. Discards results. + */ def untilM_[A](f: F[A])(cond: => F[Boolean]): F[Unit] = { val p = Eval.later(cond) flatMap(f)(_ => whileM_(map(p.value)(!_))(f)) } /** - * Execute an action repeatedly until its result fails to satisfy the given predicate - * and return that result, discarding all others. - */ + * Execute an action repeatedly until its result fails to satisfy the given predicate + * and return that result, discarding all others. + */ def iterateWhile[A](f: F[A])(p: A => Boolean): F[A] = flatMap(f) { i => iterateWhileM(i)(_ => f)(p) } /** - * Execute an action repeatedly until its result satisfies the given predicate - * and return that result, discarding all others. - */ + * Execute an action repeatedly until its result satisfies the given predicate + * and return that result, discarding all others. + */ def iterateUntil[A](f: F[A])(p: A => Boolean): F[A] = flatMap(f) { i => iterateUntilM(i)(_ => f)(p) diff --git a/core/src/main/scala/cats/MonadError.scala b/core/src/main/scala/cats/MonadError.scala index f861f828033..82541c81211 100644 --- a/core/src/main/scala/cats/MonadError.scala +++ b/core/src/main/scala/cats/MonadError.scala @@ -1,15 +1,15 @@ package cats /** - * A monad that also allows you to raise and or handle an error value. - * - * This type class allows one to abstract over error-handling monads. - */ + * A monad that also allows you to raise and or handle an error value. + * + * This type class allows one to abstract over error-handling monads. + */ 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. - */ + * 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)) @@ -20,45 +20,45 @@ trait MonadError[F[_], E] extends ApplicativeError[F, E] with Monad[F] { flatMap(fa)(a => if (predicate(a)) pure(a) else raiseError(error(a))) /** - * Transform certain errors using `pf` and rethrow them. - * Non matching errors and successful values are not affected by this function. - * - * Example: - * {{{ - * scala> import cats._, implicits._ - * - * scala> def pf: PartialFunction[String, String] = { case "error" => "ERROR" } - * - * scala> "error".asLeft[Int].adaptError(pf) - * res0: Either[String,Int] = Left(ERROR) - * - * scala> "err".asLeft[Int].adaptError(pf) - * res1: Either[String,Int] = Left(err) - * - * scala> 1.asRight[String].adaptError(pf) - * res2: Either[String,Int] = Right(1) - * }}} - */ + * Transform certain errors using `pf` and rethrow them. + * Non matching errors and successful values are not affected by this function. + * + * Example: + * {{{ + * scala> import cats._, implicits._ + * + * scala> def pf: PartialFunction[String, String] = { case "error" => "ERROR" } + * + * scala> "error".asLeft[Int].adaptError(pf) + * res0: Either[String,Int] = Left(ERROR) + * + * scala> "err".asLeft[Int].adaptError(pf) + * res1: Either[String,Int] = Left(err) + * + * scala> 1.asRight[String].adaptError(pf) + * res2: Either[String,Int] = Right(1) + * }}} + */ def adaptError[A](fa: F[A])(pf: PartialFunction[E, E]): F[A] = flatMap(attempt(fa))(_.fold(e => raiseError(pf.applyOrElse[E, E](e, _ => e)), pure)) /** - * Inverse of `attempt` - * - * Example: - * {{{ - * scala> import cats.implicits._ - * scala> import scala.util.{Try, Success} - * - * scala> val a: Try[Either[Throwable, Int]] = Success(Left(new java.lang.Exception)) - * scala> a.rethrow - * res0: scala.util.Try[Int] = Failure(java.lang.Exception) - * - * scala> val b: Try[Either[Throwable, Int]] = Success(Right(1)) - * scala> b.rethrow - * res1: scala.util.Try[Int] = Success(1) - * }}} - */ + * Inverse of `attempt` + * + * Example: + * {{{ + * scala> import cats.implicits._ + * scala> import scala.util.{Try, Success} + * + * scala> val a: Try[Either[Throwable, Int]] = Success(Left(new java.lang.Exception)) + * scala> a.rethrow + * res0: scala.util.Try[Int] = Failure(java.lang.Exception) + * + * scala> val b: Try[Either[Throwable, Int]] = Success(Right(1)) + * scala> b.rethrow + * res1: scala.util.Try[Int] = Success(1) + * }}} + */ def rethrow[A](fa: F[Either[E, A]]): F[A] = flatMap(fa)(_.fold(raiseError, pure)) } diff --git a/core/src/main/scala/cats/MonoidK.scala b/core/src/main/scala/cats/MonoidK.scala index 5e5c1b08235..9c7eef5ede4 100644 --- a/core/src/main/scala/cats/MonoidK.scala +++ b/core/src/main/scala/cats/MonoidK.scala @@ -3,42 +3,42 @@ package cats import simulacrum.typeclass /** - * MonoidK is a universal monoid which operates on kinds. - * - * This type class is useful when its type parameter F[_] has a - * structure that can be combined for any particular type, and which - * also has an "empty" representation. Thus, MonoidK is like a Monoid - * for kinds (i.e. parametrized types). - * - * A MonoidK[F] can produce a Monoid[F[A]] for any type A. - * - * Here's how to distinguish Monoid and MonoidK: - * - * - Monoid[A] allows A values to be combined, and also means there - * is an "empty" A value that functions as an identity. - * - * - MonoidK[F] allows two F[A] values to be combined, for any A. It - * also means that for any A, there is an "empty" F[A] value. The - * combination operation and empty value just depend on the - * structure of F, but not on the structure of A. - */ + * MonoidK is a universal monoid which operates on kinds. + * + * This type class is useful when its type parameter F[_] has a + * structure that can be combined for any particular type, and which + * also has an "empty" representation. Thus, MonoidK is like a Monoid + * for kinds (i.e. parametrized types). + * + * A MonoidK[F] can produce a Monoid[F[A]] for any type A. + * + * Here's how to distinguish Monoid and MonoidK: + * + * - Monoid[A] allows A values to be combined, and also means there + * is an "empty" A value that functions as an identity. + * + * - MonoidK[F] allows two F[A] values to be combined, for any A. It + * also means that for any A, there is an "empty" F[A] value. The + * combination operation and empty value just depend on the + * structure of F, but not on the structure of A. + */ @typeclass trait MonoidK[F[_]] extends SemigroupK[F] { self => /** - * Given a type A, create an "empty" F[A] value. - * - * Example: - * {{{ - * scala> import cats.implicits._ - * scala> MonoidK[List].empty[Long] - * res0: List[Long] = List() - * }}} - */ + * Given a type A, create an "empty" F[A] value. + * + * Example: + * {{{ + * scala> import cats.implicits._ + * scala> MonoidK[List].empty[Long] + * res0: List[Long] = List() + * }}} + */ def empty[A]: F[A] /** - * Given a type A, create a concrete Monoid[F[A]]. - */ + * Given a type A, create a concrete Monoid[F[A]]. + */ override def algebra[A]: Monoid[F[A]] = new Monoid[F[A]] { def empty: F[A] = self.empty diff --git a/core/src/main/scala/cats/NonEmptyTraverse.scala b/core/src/main/scala/cats/NonEmptyTraverse.scala index 100d731bc51..ab25a998ab1 100644 --- a/core/src/main/scala/cats/NonEmptyTraverse.scala +++ b/core/src/main/scala/cats/NonEmptyTraverse.scala @@ -45,7 +45,6 @@ import simulacrum.typeclass def nonEmptySequence[G[_]: Apply, A](fga: F[G[A]]): G[F[A]] = nonEmptyTraverse(fga)(identity) - /** * A nonEmptyTraverse followed by flattening the inner result. * @@ -80,7 +79,7 @@ import simulacrum.typeclass def nonEmptyFlatSequence[G[_], A](fgfa: F[G[F[A]]])(implicit G: Apply[G], F: FlatMap[F]): G[F[A]] = G.map(nonEmptyTraverse(fgfa)(identity))(F.flatten) - override def traverse[G[_] : Applicative, A, B](fa: F[A])(f: (A) => G[B]): G[F[B]] = + override def traverse[G[_]: Applicative, A, B](fa: F[A])(f: (A) => G[B]): G[F[B]] = nonEmptyTraverse(fa)(f) def compose[G[_]: NonEmptyTraverse]: NonEmptyTraverse[λ[α => F[G[α]]]] = @@ -89,5 +88,4 @@ import simulacrum.typeclass val G = NonEmptyTraverse[G] } - } diff --git a/core/src/main/scala/cats/NotNull.scala b/core/src/main/scala/cats/NotNull.scala index 39dbba6691f..01a97e4e5cd 100644 --- a/core/src/main/scala/cats/NotNull.scala +++ b/core/src/main/scala/cats/NotNull.scala @@ -1,30 +1,35 @@ package cats /** - * An instance of `NotNull[A]` indicates that `A` does not have a static type - * of `Null`. - * - * This can be useful in preventing `Null` from being inferred when a type - * parameter is omitted. - * - * This trait is used along with ambiguous implicits to achieve the goal of - * preventing inference of `Null`. This ambiguous implicit trick has been used - * in the Scala community for some time. [[https://gist.github.com/milessabin/de58f3ba7024d51dcc1a Here]] - * is an early example of such a trick being used in a similar way to prevent a - * `Nothing` type. - */ + * An instance of `NotNull[A]` indicates that `A` does not have a static type + * of `Null`. + * + * This can be useful in preventing `Null` from being inferred when a type + * parameter is omitted. + * + * This trait is used along with ambiguous implicits to achieve the goal of + * preventing inference of `Null`. This ambiguous implicit trick has been used + * in the Scala community for some time. [[https://gist.github.com/milessabin/de58f3ba7024d51dcc1a Here]] + * is an early example of such a trick being used in a similar way to prevent a + * `Nothing` type. + */ sealed trait NotNull[A] object NotNull { + /** - * Since NotNull is just a marker trait with no functionality, it's safe to - * reuse a single instance of it. This helps prevent unnecessary allocations. - */ + * Since NotNull is just a marker trait with no functionality, it's safe to + * reuse a single instance of it. This helps prevent unnecessary allocations. + */ private[this] val singleton: NotNull[Any] = new NotNull[Any] {} - private[this] def ambiguousException: Exception = new Exception("An instance of NotNull[Null] was used. This should never happen. Both ambiguous NotNull[Null] instances should always be in scope if one of them is.") + private[this] def ambiguousException: Exception = + new Exception( + "An instance of NotNull[Null] was used. This should never happen. Both ambiguous NotNull[Null] instances should always be in scope if one of them is." + ) - implicit def `If you are seeing this, you probably need to add an explicit type parameter somewhere, because Null is being inferred.`: NotNull[Null] = throw ambiguousException + implicit def `If you are seeing this, you probably need to add an explicit type parameter somewhere, because Null is being inferred.` + : NotNull[Null] = throw ambiguousException implicit def catsAmbiguousNotNullNull2: NotNull[Null] = throw ambiguousException diff --git a/core/src/main/scala/cats/Parallel.scala b/core/src/main/scala/cats/Parallel.scala index 3d48d4fe03b..1121fd8880c 100644 --- a/core/src/main/scala/cats/Parallel.scala +++ b/core/src/main/scala/cats/Parallel.scala @@ -7,6 +7,7 @@ import cats.arrow.FunctionK * The NonEmptyParallel type class allows us to represent this relationship. */ trait NonEmptyParallel[M[_], F[_]] extends Serializable { + /** * The Apply instance for F[_] */ @@ -27,7 +28,6 @@ trait NonEmptyParallel[M[_], F[_]] extends Serializable { */ def parallel: M ~> F - /** * Like [[Apply.productR]], but uses the apply instance * corresponding to the Parallel instance instead. @@ -38,7 +38,6 @@ trait NonEmptyParallel[M[_], F[_]] extends Serializable { @deprecated("Use parProductR instead.", "1.0.0-RC2") @inline def parFollowedBy[A, B](ma: M[A])(mb: M[B]): M[B] = parProductR(ma)(mb) - /** * Like [[Apply.productL]], but uses the apply instance * corresponding to the Parallel instance instead. @@ -56,6 +55,7 @@ trait NonEmptyParallel[M[_], F[_]] extends Serializable { * The Parallel type class allows us to represent this relationship. */ trait Parallel[M[_], F[_]] extends NonEmptyParallel[M, F] { + /** * The applicative instance for F[_] */ @@ -82,7 +82,7 @@ trait Parallel[M[_], F[_]] extends NonEmptyParallel[M, F] { parallel(MonadError[M, E].raiseError(e)) def handleErrorWith[A](fa: F[A])(f: (E) => F[A]): F[A] = { - val ma = MonadError[M, E].handleErrorWith(sequential(fa))(f andThen sequential.apply) + val ma = MonadError[M, E].handleErrorWith(sequential(fa))(f.andThen(sequential.apply)) parallel(ma) } @@ -117,8 +117,7 @@ object Parallel extends ParallelArityFunctions2 { * Like `Traverse[A].sequence`, but uses the applicative instance * corresponding to the Parallel instance instead. */ - def parSequence[T[_]: Traverse, M[_], F[_], A] - (tma: T[M[A]])(implicit P: Parallel[M, F]): M[T[A]] = { + def parSequence[T[_]: Traverse, M[_], F[_], A](tma: T[M[A]])(implicit P: Parallel[M, F]): M[T[A]] = { val fta: F[T[A]] = Traverse[T].traverse(tma)(P.parallel.apply)(P.applicative) P.sequential(fta) } @@ -127,9 +126,8 @@ object Parallel extends ParallelArityFunctions2 { * Like `Traverse[A].traverse`, but uses the applicative instance * corresponding to the Parallel instance instead. */ - def parTraverse[T[_]: Traverse, M[_], F[_], A, B] - (ta: T[A])(f: A => M[B])(implicit P: Parallel[M, F]): M[T[B]] = { - val gtb: F[T[B]] = Traverse[T].traverse(ta)(f andThen P.parallel.apply)(P.applicative) + def parTraverse[T[_]: Traverse, M[_], F[_], A, B](ta: T[A])(f: A => M[B])(implicit P: Parallel[M, F]): M[T[B]] = { + val gtb: F[T[B]] = Traverse[T].traverse(ta)(f.andThen(P.parallel.apply))(P.applicative) P.sequential(gtb) } @@ -137,9 +135,10 @@ object Parallel extends ParallelArityFunctions2 { * Like `Traverse[A].flatTraverse`, but uses the applicative instance * corresponding to the Parallel instance instead. */ - def parFlatTraverse[T[_]: Traverse: FlatMap, M[_], F[_], A, B] - (ta: T[A])(f: A => M[T[B]])(implicit P: Parallel[M, F]): M[T[B]] = { - val gtb: F[T[B]] = Traverse[T].flatTraverse(ta)(f andThen P.parallel.apply)(P.applicative, FlatMap[T]) + def parFlatTraverse[T[_]: Traverse: FlatMap, M[_], F[_], A, B]( + ta: T[A] + )(f: A => M[T[B]])(implicit P: Parallel[M, F]): M[T[B]] = { + val gtb: F[T[B]] = Traverse[T].flatTraverse(ta)(f.andThen(P.parallel.apply))(P.applicative, FlatMap[T]) P.sequential(gtb) } @@ -147,8 +146,7 @@ object Parallel extends ParallelArityFunctions2 { * Like `Traverse[A].flatSequence`, but uses the applicative instance * corresponding to the Parallel instance instead. */ - def parFlatSequence[T[_]: Traverse: FlatMap, M[_], F[_], A] - (tma: T[M[T[A]]])(implicit P: Parallel[M, F]): M[T[A]] = { + def parFlatSequence[T[_]: Traverse: FlatMap, M[_], F[_], A](tma: T[M[T[A]]])(implicit P: Parallel[M, F]): M[T[A]] = { val fta: F[T[A]] = Traverse[T].flatTraverse(tma)(P.parallel.apply)(P.applicative, FlatMap[T]) P.sequential(fta) } @@ -157,8 +155,7 @@ object Parallel extends ParallelArityFunctions2 { * Like `Foldable[A].sequence_`, but uses the applicative instance * corresponding to the Parallel instance instead. */ - def parSequence_[T[_]: Foldable, M[_], F[_], A] - (tma: T[M[A]])(implicit P: Parallel[M, F]): M[Unit] = { + def parSequence_[T[_]: Foldable, M[_], F[_], A](tma: T[M[A]])(implicit P: Parallel[M, F]): M[Unit] = { val fu: F[Unit] = Foldable[T].traverse_(tma)(P.parallel.apply)(P.applicative) P.sequential(fu) } @@ -167,9 +164,8 @@ object Parallel extends ParallelArityFunctions2 { * Like `Foldable[A].traverse_`, but uses the applicative instance * corresponding to the Parallel instance instead. */ - def parTraverse_[T[_]: Foldable, M[_], F[_], A, B] - (ta: T[A])(f: A => M[B])(implicit P: Parallel[M, F]): M[Unit] = { - val gtb: F[Unit] = Foldable[T].traverse_(ta)(f andThen P.parallel.apply)(P.applicative) + def parTraverse_[T[_]: Foldable, M[_], F[_], A, B](ta: T[A])(f: A => M[B])(implicit P: Parallel[M, F]): M[Unit] = { + val gtb: F[Unit] = Foldable[T].traverse_(ta)(f.andThen(P.parallel.apply))(P.applicative) P.sequential(gtb) } @@ -177,8 +173,9 @@ object Parallel extends ParallelArityFunctions2 { * Like `NonEmptyTraverse[A].nonEmptySequence`, but uses the apply instance * corresponding to the Parallel instance instead. */ - def parNonEmptySequence[T[_]: NonEmptyTraverse, M[_], F[_], A] - (tma: T[M[A]])(implicit P: NonEmptyParallel[M, F]): M[T[A]] = { + def parNonEmptySequence[T[_]: NonEmptyTraverse, M[_], F[_], A]( + tma: T[M[A]] + )(implicit P: NonEmptyParallel[M, F]): M[T[A]] = { val fta: F[T[A]] = NonEmptyTraverse[T].nonEmptyTraverse(tma)(P.parallel.apply)(P.apply) P.sequential(fta) } @@ -187,30 +184,31 @@ object Parallel extends ParallelArityFunctions2 { * Like `NonEmptyTraverse[A].nonEmptyTraverse`, but uses the apply instance * corresponding to the Parallel instance instead. */ - def parNonEmptyTraverse[T[_]: NonEmptyTraverse, M[_], F[_], A, B] - (ta: T[A])(f: A => M[B])(implicit P: NonEmptyParallel[M, F]): M[T[B]] = { - val gtb: F[T[B]] = NonEmptyTraverse[T].nonEmptyTraverse(ta)(f andThen P.parallel.apply)(P.apply) + def parNonEmptyTraverse[T[_]: NonEmptyTraverse, M[_], F[_], A, B]( + ta: T[A] + )(f: A => M[B])(implicit P: NonEmptyParallel[M, F]): M[T[B]] = { + val gtb: F[T[B]] = NonEmptyTraverse[T].nonEmptyTraverse(ta)(f.andThen(P.parallel.apply))(P.apply) P.sequential(gtb) } - /** * Like `NonEmptyTraverse[A].nonEmptyFlatTraverse`, but uses the apply instance * corresponding to the Parallel instance instead. */ - def parNonEmptyFlatTraverse[T[_]: NonEmptyTraverse: FlatMap, M[_], F[_], A, B] - (ta: T[A])(f: A => M[T[B]])(implicit P: NonEmptyParallel[M, F]): M[T[B]] = { - val gtb: F[T[B]] = NonEmptyTraverse[T].nonEmptyFlatTraverse(ta)(f andThen P.parallel.apply)(P.apply, FlatMap[T]) + def parNonEmptyFlatTraverse[T[_]: NonEmptyTraverse: FlatMap, M[_], F[_], A, B]( + ta: T[A] + )(f: A => M[T[B]])(implicit P: NonEmptyParallel[M, F]): M[T[B]] = { + val gtb: F[T[B]] = NonEmptyTraverse[T].nonEmptyFlatTraverse(ta)(f.andThen(P.parallel.apply))(P.apply, FlatMap[T]) P.sequential(gtb) } - /** * Like `NonEmptyTraverse[A].nonEmptyFlatSequence`, but uses the apply instance * corresponding to the Parallel instance instead. */ - def parNonEmptyFlatSequence[T[_]: NonEmptyTraverse: FlatMap, M[_], F[_], A] - (tma: T[M[T[A]]])(implicit P: NonEmptyParallel[M, F]): M[T[A]] = { + def parNonEmptyFlatSequence[T[_]: NonEmptyTraverse: FlatMap, M[_], F[_], A]( + tma: T[M[T[A]]] + )(implicit P: NonEmptyParallel[M, F]): M[T[A]] = { val fta: F[T[A]] = NonEmptyTraverse[T].nonEmptyFlatTraverse(tma)(P.parallel.apply)(P.apply, FlatMap[T]) P.sequential(fta) } @@ -219,8 +217,9 @@ object Parallel extends ParallelArityFunctions2 { * Like `Reducible[A].nonEmptySequence_`, but uses the apply instance * corresponding to the Parallel instance instead. */ - def parNonEmptySequence_[T[_]: Reducible, M[_], F[_], A] - (tma: T[M[A]])(implicit P: NonEmptyParallel[M, F]): M[Unit] = { + def parNonEmptySequence_[T[_]: Reducible, M[_], F[_], A]( + tma: T[M[A]] + )(implicit P: NonEmptyParallel[M, F]): M[Unit] = { val fu: F[Unit] = Reducible[T].nonEmptyTraverse_(tma)(P.parallel.apply)(P.apply) P.sequential(fu) } @@ -229,9 +228,10 @@ object Parallel extends ParallelArityFunctions2 { * Like `Reducible[A].nonEmptyTraverse_`, but uses the apply instance * corresponding to the Parallel instance instead. */ - def parNonEmptyTraverse_[T[_]: Reducible, M[_], F[_], A, B] - (ta: T[A])(f: A => M[B])(implicit P: NonEmptyParallel[M, F]): M[Unit] = { - val gtb: F[Unit] = Reducible[T].nonEmptyTraverse_(ta)(f andThen P.parallel.apply)(P.apply) + def parNonEmptyTraverse_[T[_]: Reducible, M[_], F[_], A, B]( + ta: T[A] + )(f: A => M[B])(implicit P: NonEmptyParallel[M, F]): M[Unit] = { + val gtb: F[Unit] = Reducible[T].nonEmptyTraverse_(ta)(f.andThen(P.parallel.apply))(P.apply) P.sequential(gtb) } @@ -239,26 +239,21 @@ object Parallel extends ParallelArityFunctions2 { * Like `Applicative[F].ap`, but uses the applicative instance * corresponding to the Parallel instance instead. */ - def parAp[M[_], F[_], A, B](mf: M[A => B]) - (ma: M[A]) - (implicit P: NonEmptyParallel[M, F]): M[B] = + def parAp[M[_], F[_], A, B](mf: M[A => B])(ma: M[A])(implicit P: NonEmptyParallel[M, F]): M[B] = P.sequential(P.apply.ap(P.parallel(mf))(P.parallel(ma))) /** * Like `Applicative[F].product`, but uses the applicative instance * corresponding to the Parallel instance instead. */ - def parProduct[M[_], F[_], A, B](ma: M[A], mb: M[B]) - (implicit P: NonEmptyParallel[M, F]): M[(A, B)] = + def parProduct[M[_], F[_], A, B](ma: M[A], mb: M[B])(implicit P: NonEmptyParallel[M, F]): M[(A, B)] = P.sequential(P.apply.product(P.parallel(ma), P.parallel(mb))) /** * Like `Applicative[F].ap2`, but uses the applicative instance * corresponding to the Parallel instance instead. */ - def parAp2[M[_], F[_], A, B, Z](ff: M[(A, B) => Z]) - (ma: M[A], mb: M[B]) - (implicit P: NonEmptyParallel[M, F]): M[Z] = + def parAp2[M[_], F[_], A, B, Z](ff: M[(A, B) => Z])(ma: M[A], mb: M[B])(implicit P: NonEmptyParallel[M, F]): M[Z] = P.sequential( P.apply.ap2(P.parallel(ff))(P.parallel(ma), P.parallel(mb)) ) @@ -269,8 +264,8 @@ object Parallel extends ParallelArityFunctions2 { * I.e. if you have a type M[_], that supports parallel composition through type F[_], * then you can get `ApplicativeError[F, E]` from `MonadError[M, E]`. */ - def applicativeError[M[_], F[_], E] - (implicit P: Parallel[M, F], E: MonadError[M, E]): ApplicativeError[F, E] = P.applicativeError + def applicativeError[M[_], F[_], E](implicit P: Parallel[M, F], E: MonadError[M, E]): ApplicativeError[F, E] = + P.applicativeError /** * A Parallel instance for any type `M[_]` that supports parallel composition through itself. diff --git a/core/src/main/scala/cats/Reducible.scala b/core/src/main/scala/cats/Reducible.scala index 7a7a6173a6f..a64be32a6ec 100644 --- a/core/src/main/scala/cats/Reducible.scala +++ b/core/src/main/scala/cats/Reducible.scala @@ -4,138 +4,138 @@ import cats.data.{Ior, NonEmptyList} import simulacrum.typeclass /** - * Data structures that can be reduced to a summary value. - * - * `Reducible` is like a non-empty `Foldable`. In addition to the fold - * methods it provides reduce methods which do not require an initial - * value. - * - * In addition to the methods needed by `Foldable`, `Reducible` is - * implemented in terms of two methods: - * - * - `reduceLeftTo(fa)(f)(g)` eagerly reduces with an additional mapping function - * - `reduceRightTo(fa)(f)(g)` lazily reduces with an additional mapping function - */ + * Data structures that can be reduced to a summary value. + * + * `Reducible` is like a non-empty `Foldable`. In addition to the fold + * methods it provides reduce methods which do not require an initial + * value. + * + * In addition to the methods needed by `Foldable`, `Reducible` is + * implemented in terms of two methods: + * + * - `reduceLeftTo(fa)(f)(g)` eagerly reduces with an additional mapping function + * - `reduceRightTo(fa)(f)(g)` lazily reduces with an additional mapping function + */ @typeclass trait Reducible[F[_]] extends Foldable[F] { self => /** - * Left-associative reduction on `F` using the function `f`. - * - * Implementations should override this method when possible. - */ + * Left-associative reduction on `F` using the function `f`. + * + * Implementations should override this method when possible. + */ def reduceLeft[A](fa: F[A])(f: (A, A) => A): A = reduceLeftTo(fa)(identity)(f) /** - * Right-associative reduction on `F` using the function `f`. - */ + * Right-associative reduction on `F` using the function `f`. + */ def reduceRight[A](fa: F[A])(f: (A, Eval[A]) => Eval[A]): Eval[A] = reduceRightTo(fa)(identity)(f) /** - * Reduce a `F[A]` value using the given `Semigroup[A]`. - */ + * Reduce a `F[A]` value using the given `Semigroup[A]`. + */ def reduce[A](fa: F[A])(implicit A: Semigroup[A]): A = reduceLeft(fa)(A.combine) /** - * Reduce a `F[G[A]]` value using `SemigroupK[G]`, a universal - * semigroup for `G[_]`. - * - * This method is a generalization of `reduce`. - */ + * Reduce a `F[G[A]]` value using `SemigroupK[G]`, a universal + * semigroup for `G[_]`. + * + * This method is a generalization of `reduce`. + */ def reduceK[G[_], A](fga: F[G[A]])(implicit G: SemigroupK[G]): G[A] = reduce(fga)(G.algebra) /** - * Apply `f` to each element of `fa` and combine them using the - * given `Semigroup[B]`. - */ + * Apply `f` to each element of `fa` and combine them using the + * given `Semigroup[B]`. + */ def reduceMap[A, B](fa: F[A])(f: A => B)(implicit B: Semigroup[B]): B = reduceLeftTo(fa)(f)((b, a) => B.combine(b, f(a))) /** - * Apply `f` to the "initial element" of `fa` and combine it with - * every other value using the given function `g`. - */ + * Apply `f` to the "initial element" of `fa` and combine it with + * every other value using the given function `g`. + */ def reduceLeftTo[A, B](fa: F[A])(f: A => B)(g: (B, A) => B): B /** - * Monadic variant of [[reduceLeftTo]] - */ + * Monadic variant of [[reduceLeftTo]] + */ def reduceLeftM[G[_], A, B](fa: F[A])(f: A => G[B])(g: (B, A) => G[B])(implicit G: FlatMap[G]): G[B] = reduceLeftTo(fa)(f)((gb, a) => G.flatMap(gb)(g(_, a))) /** - * Monadic reducing by mapping the `A` values to `G[B]`. combining - * the `B` values using the given `Semigroup[B]` instance. - * - * Similar to [[reduceLeftM]], but using a `Semigroup[B]`. - * - * {{{ - * scala> import cats.Reducible - * scala> import cats.data.NonEmptyList - * scala> import cats.implicits._ - * scala> val evenOpt: Int => Option[Int] = - * | i => if (i % 2 == 0) Some(i) else None - * scala> val allEven = NonEmptyList.of(2,4,6,8,10) - * allEven: cats.data.NonEmptyList[Int] = NonEmptyList(2, 4, 6, 8, 10) - * scala> val notAllEven = allEven ++ List(11) - * notAllEven: cats.data.NonEmptyList[Int] = NonEmptyList(2, 4, 6, 8, 10, 11) - * scala> Reducible[NonEmptyList].reduceMapM(allEven)(evenOpt) - * res0: Option[Int] = Some(30) - * scala> Reducible[NonEmptyList].reduceMapM(notAllEven)(evenOpt) - * res1: Option[Int] = None - * }}} - */ + * Monadic reducing by mapping the `A` values to `G[B]`. combining + * the `B` values using the given `Semigroup[B]` instance. + * + * Similar to [[reduceLeftM]], but using a `Semigroup[B]`. + * + * {{{ + * scala> import cats.Reducible + * scala> import cats.data.NonEmptyList + * scala> import cats.implicits._ + * scala> val evenOpt: Int => Option[Int] = + * | i => if (i % 2 == 0) Some(i) else None + * scala> val allEven = NonEmptyList.of(2,4,6,8,10) + * allEven: cats.data.NonEmptyList[Int] = NonEmptyList(2, 4, 6, 8, 10) + * scala> val notAllEven = allEven ++ List(11) + * notAllEven: cats.data.NonEmptyList[Int] = NonEmptyList(2, 4, 6, 8, 10, 11) + * scala> Reducible[NonEmptyList].reduceMapM(allEven)(evenOpt) + * res0: Option[Int] = Some(30) + * scala> Reducible[NonEmptyList].reduceMapM(notAllEven)(evenOpt) + * res1: Option[Int] = None + * }}} + */ def reduceMapM[G[_], A, B](fa: F[A])(f: A => G[B])(implicit G: FlatMap[G], B: Semigroup[B]): G[B] = reduceLeftM(fa)(f)((b, a) => G.map(f(a))(B.combine(b, _))) /** - * Overridden from [[Foldable]] for efficiency. - */ + * Overridden from [[Foldable]] for efficiency. + */ override def reduceLeftToOption[A, B](fa: F[A])(f: A => B)(g: (B, A) => B): Option[B] = Some(reduceLeftTo(fa)(f)(g)) /** - * Apply `f` to the "initial element" of `fa` and lazily combine it - * with every other value using the given function `g`. - */ + * Apply `f` to the "initial element" of `fa` and lazily combine it + * with every other value using the given function `g`. + */ def reduceRightTo[A, B](fa: F[A])(f: A => B)(g: (A, Eval[B]) => Eval[B]): Eval[B] /** - * Overridden from [[Foldable]] for efficiency. - */ + * Overridden from [[Foldable]] for efficiency. + */ override def reduceRightToOption[A, B](fa: F[A])(f: A => B)(g: (A, Eval[B]) => Eval[B]): Eval[Option[B]] = reduceRightTo(fa)(f)(g).map(Some(_)) /** - * Traverse `F[A]` using `Apply[G]`. - * - * `A` values will be mapped into `G[B]` and combined using - * `Apply#map2`. - * - * This method is similar to [[Foldable.traverse_]]. There are two - * main differences: - * - * 1. We only need an [[Apply]] instance for `G` here, since we - * don't need to call [[Applicative.pure]] for a starting value. - * 2. This performs a strict left-associative traversal and thus - * must always traverse the entire data structure. Prefer - * [[Foldable.traverse_]] if you have an [[Applicative]] instance - * available for `G` and want to take advantage of short-circuiting - * the traversal. - */ + * Traverse `F[A]` using `Apply[G]`. + * + * `A` values will be mapped into `G[B]` and combined using + * `Apply#map2`. + * + * This method is similar to [[Foldable.traverse_]]. There are two + * main differences: + * + * 1. We only need an [[Apply]] instance for `G` here, since we + * don't need to call [[Applicative.pure]] for a starting value. + * 2. This performs a strict left-associative traversal and thus + * must always traverse the entire data structure. Prefer + * [[Foldable.traverse_]] if you have an [[Applicative]] instance + * available for `G` and want to take advantage of short-circuiting + * the traversal. + */ def nonEmptyTraverse_[G[_], A, B](fa: F[A])(f: A => G[B])(implicit G: Apply[G]): G[Unit] = G.void(reduceLeftTo(fa)(f)((x, y) => G.map2(x, f(y))((_, b) => b))) /** - * Sequence `F[G[A]]` using `Apply[G]`. - * - * This method is similar to [[Foldable.sequence_]] but requires only - * an [[Apply]] instance for `G` instead of [[Applicative]]. See the - * [[nonEmptyTraverse_]] documentation for a description of the differences. - */ + * Sequence `F[G[A]]` using `Apply[G]`. + * + * This method is similar to [[Foldable.sequence_]] but requires only + * an [[Apply]] instance for `G` instead of [[Applicative]]. See the + * [[nonEmptyTraverse_]] documentation for a description of the differences. + */ def nonEmptySequence_[G[_], A](fga: F[G[A]])(implicit G: Apply[G]): G[Unit] = G.void(reduceLeft(fga)((x, y) => G.map2(x, y)((_, b) => b))) @@ -157,18 +157,18 @@ import simulacrum.typeclass reduceLeft(fa)(A.max) /** - * Intercalate/insert an element between the existing elements while reducing. - * - * {{{ - * scala> import cats.implicits._ - * scala> import cats.data.NonEmptyList - * scala> val nel = NonEmptyList.of("a", "b", "c") - * scala> Reducible[NonEmptyList].nonEmptyIntercalate(nel, "-") - * res0: String = a-b-c - * scala> Reducible[NonEmptyList].nonEmptyIntercalate(NonEmptyList.of("a"), "-") - * res1: String = a - * }}} - */ + * Intercalate/insert an element between the existing elements while reducing. + * + * {{{ + * scala> import cats.implicits._ + * scala> import cats.data.NonEmptyList + * scala> val nel = NonEmptyList.of("a", "b", "c") + * scala> Reducible[NonEmptyList].nonEmptyIntercalate(nel, "-") + * res0: String = a-b-c + * scala> Reducible[NonEmptyList].nonEmptyIntercalate(NonEmptyList.of("a"), "-") + * res1: String = a + * }}} + */ def nonEmptyIntercalate[A](fa: F[A], a: A)(implicit A: Semigroup[A]): A = toNonEmptyList(fa) match { case NonEmptyList(hd, Nil) => hd @@ -191,15 +191,16 @@ import simulacrum.typeclass def nonEmptyPartition[A, B, C](fa: F[A])(f: A => Either[B, C]): Ior[NonEmptyList[B], NonEmptyList[C]] = { import cats.syntax.either._ - def g(a: A, eval: Eval[Ior[NonEmptyList[B], NonEmptyList[C]]]): Eval[Ior[NonEmptyList[B], NonEmptyList[C]]] = { - eval.map(ior => - (f(a), ior) match { - case (Right(c), Ior.Left(_)) => ior.putRight(NonEmptyList.one(c)) - case (Right(c), _) => ior.map(c :: _) - case (Left(b), Ior.Right(r)) => Ior.bothNel(b, r) - case (Left(b), _) => ior.leftMap(b :: _) - }) - } + def g(a: A, eval: Eval[Ior[NonEmptyList[B], NonEmptyList[C]]]): Eval[Ior[NonEmptyList[B], NonEmptyList[C]]] = + eval.map( + ior => + (f(a), ior) match { + case (Right(c), Ior.Left(_)) => ior.putRight(NonEmptyList.one(c)) + case (Right(c), _) => ior.map(c :: _) + case (Left(b), Ior.Right(r)) => Ior.bothNel(b, r) + case (Left(b), _) => ior.leftMap(b :: _) + } + ) reduceRightTo(fa)(a => f(a).bimap(NonEmptyList.one, NonEmptyList.one).toIor)(g).value } @@ -216,12 +217,12 @@ import simulacrum.typeclass } /** - * This class defines a `Reducible[F]` in terms of a `Foldable[G]` - * together with a `split` method, `F[A]` => `(A, G[A])`. - * - * This class can be used on any type where the first value (`A`) and - * the "rest" of the values (`G[A]`) can be easily found. - */ + * This class defines a `Reducible[F]` in terms of a `Foldable[G]` + * together with a `split` method, `F[A]` => `(A, G[A])`. + * + * This class can be used on any type where the first value (`A`) and + * the "rest" of the values (`G[A]`) can be easily found. + */ abstract class NonEmptyReducible[F[_], G[_]](implicit G: Foldable[G]) extends Reducible[F] { def split[A](fa: F[A]): (A, G[A]) @@ -231,8 +232,9 @@ abstract class NonEmptyReducible[F[_], G[_]](implicit G: Foldable[G]) extends Re } def foldRight[A, B](fa: F[A], lb: Eval[B])(f: (A, Eval[B]) => Eval[B]): Eval[B] = - Always(split(fa)).flatMap { case (a, ga) => - f(a, G.foldRight(ga, lb)(f)) + Always(split(fa)).flatMap { + case (a, ga) => + f(a, G.foldRight(ga, lb)(f)) } def reduceLeftTo[A, B](fa: F[A])(f: A => B)(g: (B, A) => B): B = { @@ -241,11 +243,12 @@ abstract class NonEmptyReducible[F[_], G[_]](implicit G: Foldable[G]) extends Re } def reduceRightTo[A, B](fa: F[A])(f: A => B)(g: (A, Eval[B]) => Eval[B]): Eval[B] = - Always(split(fa)).flatMap { case (a, ga) => - G.reduceRightToOption(ga)(f)(g).flatMap { - case Some(b) => g(a, Now(b)) - case None => Later(f(a)) - } + Always(split(fa)).flatMap { + case (a, ga) => + G.reduceRightToOption(ga)(f)(g).flatMap { + case Some(b) => g(a, Now(b)) + case None => Later(f(a)) + } } override def size[A](fa: F[A]): Long = { diff --git a/core/src/main/scala/cats/Representable.scala b/core/src/main/scala/cats/Representable.scala index 8fb7dd30059..c3e1fa39d77 100644 --- a/core/src/main/scala/cats/Representable.scala +++ b/core/src/main/scala/cats/Representable.scala @@ -1,18 +1,18 @@ package cats /** - * Representable. - * - * Is a witness to the isomorphism forall A. F[A] <-> Representation => A - * - * Must obey the laws defined in cats.laws.RepresentableLaws - * i.e. - * tabulate andThen index = identity - * index andThen tabulate = identity - * - * Inspired by the Haskell representable package - * http://hackage.haskell.org/package/representable-functors-3.2.0.2/docs/Data-Functor-Representable.html - */ + * Representable. + * + * Is a witness to the isomorphism forall A. F[A] <-> Representation => A + * + * Must obey the laws defined in cats.laws.RepresentableLaws + * i.e. + * tabulate andThen index = identity + * index andThen tabulate = identity + * + * Inspired by the Haskell representable package + * http://hackage.haskell.org/package/representable-functors-3.2.0.2/docs/Data-Functor-Representable.html + */ trait Representable[F[_]] extends Serializable { def F: Functor[F] @@ -20,43 +20,43 @@ trait Representable[F[_]] extends Serializable { type Representation /** - * Create a function that "indexes" into the `F` structure using `Representation` - * - * Example: - * {{{ - * scala> import cats.implicits._ - * - * scala> type Pair[A] = (A, A) - * - * scala> val indexed: Boolean => String = Representable[Pair].index(("foo", "bar")) - * - * scala> indexed(true) - * res0: String = foo - * - * scala> indexed(false) - * res1: String = bar - * }}} - */ + * Create a function that "indexes" into the `F` structure using `Representation` + * + * Example: + * {{{ + * scala> import cats.implicits._ + * + * scala> type Pair[A] = (A, A) + * + * scala> val indexed: Boolean => String = Representable[Pair].index(("foo", "bar")) + * + * scala> indexed(true) + * res0: String = foo + * + * scala> indexed(false) + * res1: String = bar + * }}} + */ def index[A](f: F[A]): Representation => A /** - * Reconstructs the `F` structure using the index function - * - * Example: - * {{{ - * scala> import cats.implicits._ - * - * scala> type Pair[A] = (A, A) - * - * scala> val f: Boolean => String = { - * | case true => "foo" - * | case false => "bar" - * | } - * - * scala> f.tabulate[Pair] - * res0: Pair[String] = (foo,bar) - * }}} - */ + * Reconstructs the `F` structure using the index function + * + * Example: + * {{{ + * scala> import cats.implicits._ + * + * scala> type Pair[A] = (A, A) + * + * scala> val f: Boolean => String = { + * | case true => "foo" + * | case false => "bar" + * | } + * + * scala> f.tabulate[Pair] + * res0: Pair[String] = (foo,bar) + * }}} + */ def tabulate[A](f: Representation => A): F[A] } @@ -69,18 +69,17 @@ private trait RepresentableMonad[F[_], R] extends Monad[F] { override def flatMap[A, B](fa: F[A])(f: A => F[B]): F[B] = R.tabulate(a => R.index(f(R.index(fa)(a)))(a)) - override def tailRecM[A, B](a: A)(f: A => F[Either[A, B]]): F[B] = { + override def tailRecM[A, B](a: A)(f: A => F[Either[A, B]]): F[B] = R.tabulate { r: R => @annotation.tailrec def loop(a: A): B = R.index(f(a))(r) match { case Right(b) => b - case Left(a) => loop(a) + case Left(a) => loop(a) } loop(a) } - } } private trait RepresentableBimonad[F[_], R] extends RepresentableMonad[F, R] with Bimonad[F] { @@ -98,33 +97,34 @@ object Representable { type Aux[F[_], R] = Representable[F] { type Representation = R } /** - * Summon the `Representable` instance for `F` - * - * Example: - * {{{ - * scala> import cats.implicits._ - * - * scala> type Pair[A] = (A, A) - * - * scala> Representable[Pair].index(("foo", "bar"))(false) - * res0: String = bar - * }}} - */ + * Summon the `Representable` instance for `F` + * + * Example: + * {{{ + * scala> import cats.implicits._ + * + * scala> type Pair[A] = (A, A) + * + * scala> Representable[Pair].index(("foo", "bar"))(false) + * res0: String = bar + * }}} + */ def apply[F[_]](implicit ev: Representable[F]): Representable.Aux[F, ev.Representation] = ev /** - * Derives a `Monad` instance for any `Representable` functor - */ + * Derives a `Monad` instance for any `Representable` functor + */ def monad[F[_]](implicit Rep: Representable[F]): Monad[F] = new RepresentableMonad[F, Rep.Representation] { override def R: Representable.Aux[F, Rep.Representation] = Rep } /** - * Derives a `Bimonad` instance for any `Representable` functor whos representation - * has a `Monoid` instance. - */ - def bimonad[F[_], R](implicit Rep: Representable.Aux[F, R], Mon: Monoid[R]): Bimonad[F] = new RepresentableBimonad[F, R] { - override def R: Representable.Aux[F, R] = Rep - override def M: Monoid[R] = Mon - } + * Derives a `Bimonad` instance for any `Representable` functor whos representation + * has a `Monoid` instance. + */ + def bimonad[F[_], R](implicit Rep: Representable.Aux[F, R], Mon: Monoid[R]): Bimonad[F] = + new RepresentableBimonad[F, R] { + override def R: Representable.Aux[F, R] = Rep + override def M: Monoid[R] = Mon + } } diff --git a/core/src/main/scala/cats/SemigroupK.scala b/core/src/main/scala/cats/SemigroupK.scala index f3ca1b5965f..a31827a6def 100644 --- a/core/src/main/scala/cats/SemigroupK.scala +++ b/core/src/main/scala/cats/SemigroupK.scala @@ -3,66 +3,66 @@ package cats import simulacrum.typeclass /** - * SemigroupK is a universal semigroup which operates on kinds. - * - * This type class is useful when its type parameter F[_] has a - * structure that can be combined for any particular type. Thus, - * SemigroupK is like a Semigroup for kinds (i.e. parametrized - * types). - * - * A SemigroupK[F] can produce a Semigroup[F[A]] for any type A. - * - * Here's how to distinguish Semigroup and SemigroupK: - * - * - Semigroup[A] allows two A values to be combined. - * - * - SemigroupK[F] allows two F[A] values to be combined, for any A. - * The combination operation just depends on the structure of F, - * but not the structure of A. - */ + * SemigroupK is a universal semigroup which operates on kinds. + * + * This type class is useful when its type parameter F[_] has a + * structure that can be combined for any particular type. Thus, + * SemigroupK is like a Semigroup for kinds (i.e. parametrized + * types). + * + * A SemigroupK[F] can produce a Semigroup[F[A]] for any type A. + * + * Here's how to distinguish Semigroup and SemigroupK: + * + * - Semigroup[A] allows two A values to be combined. + * + * - SemigroupK[F] allows two F[A] values to be combined, for any A. + * The combination operation just depends on the structure of F, + * but not the structure of A. + */ @typeclass trait SemigroupK[F[_]] { self => /** - * Combine two F[A] values. - * - * Example: - * {{{ - * scala> import cats.implicits._ - * scala> SemigroupK[List].combineK(List(1, 2), List(3, 4)) - * res0: List[Int] = List(1, 2, 3, 4) - * }}} - */ + * Combine two F[A] values. + * + * Example: + * {{{ + * scala> import cats.implicits._ + * scala> SemigroupK[List].combineK(List(1, 2), List(3, 4)) + * res0: List[Int] = List(1, 2, 3, 4) + * }}} + */ @simulacrum.op("<+>", alias = true) def combineK[A](x: F[A], y: F[A]): F[A] /** - * Given a type A, create a concrete Semigroup[F[A]]. - * - * Example: - * {{{ - * scala> import cats.implicits._ - * scala> val s: Semigroup[List[Int]] = SemigroupK[List].algebra[Int] - * }}} - */ + * Given a type A, create a concrete Semigroup[F[A]]. + * + * Example: + * {{{ + * scala> import cats.implicits._ + * scala> val s: Semigroup[List[Int]] = SemigroupK[List].algebra[Int] + * }}} + */ def algebra[A]: Semigroup[F[A]] = new Semigroup[F[A]] { def combine(x: F[A], y: F[A]): F[A] = self.combineK(x, y) } /** - * "Compose" with a `G[_]` type to form a `SemigroupK` for `λ[α => F[G[α]]]`. - * Note that this universally works for any `G`, because the "inner" structure - * isn't considered when combining two instances. - * - * Example: - * {{{ - * scala> import cats.implicits._ - * scala> type ListOption[A] = List[Option[A]] - * scala> val s: SemigroupK[ListOption] = SemigroupK[List].compose[Option] - * scala> s.combineK(List(Some(1), None, Some(2)), List(Some(3), None)) - * res0: List[Option[Int]] = List(Some(1), None, Some(2), Some(3), None) - * }}} - */ + * "Compose" with a `G[_]` type to form a `SemigroupK` for `λ[α => F[G[α]]]`. + * Note that this universally works for any `G`, because the "inner" structure + * isn't considered when combining two instances. + * + * Example: + * {{{ + * scala> import cats.implicits._ + * scala> type ListOption[A] = List[Option[A]] + * scala> val s: SemigroupK[ListOption] = SemigroupK[List].compose[Option] + * scala> s.combineK(List(Some(1), None, Some(2)), List(Some(3), None)) + * res0: List[Option[Int]] = List(Some(1), None, Some(2), Some(3), None) + * }}} + */ def compose[G[_]]: SemigroupK[λ[α => F[G[α]]]] = new ComposedSemigroupK[F, G] { val F = self diff --git a/core/src/main/scala/cats/Semigroupal.scala b/core/src/main/scala/cats/Semigroupal.scala index 500e9cd010a..84d6304c85e 100644 --- a/core/src/main/scala/cats/Semigroupal.scala +++ b/core/src/main/scala/cats/Semigroupal.scala @@ -3,42 +3,42 @@ package cats import simulacrum.typeclass /** - * [[Semigroupal]] captures the idea of composing independent effectful values. - * It is of particular interest when taken together with [[Functor]] - where [[Functor]] - * captures the idea of applying a unary pure function to an effectful value, - * calling `product` with `map` allows one to apply a function of arbitrary arity to multiple - * independent effectful values. - * - * That same idea is also manifested in the form of [[Apply]], and indeed [[Apply]] extends both - * [[Semigroupal]] and [[Functor]] to illustrate this. - */ + * [[Semigroupal]] captures the idea of composing independent effectful values. + * It is of particular interest when taken together with [[Functor]] - where [[Functor]] + * captures the idea of applying a unary pure function to an effectful value, + * calling `product` with `map` allows one to apply a function of arbitrary arity to multiple + * independent effectful values. + * + * That same idea is also manifested in the form of [[Apply]], and indeed [[Apply]] extends both + * [[Semigroupal]] and [[Functor]] to illustrate this. + */ @typeclass trait Semigroupal[F[_]] { /** - * Combine an `F[A]` and an `F[B]` into an `F[(A, B)]` that maintains the effects of both `fa` and `fb`. - * - * Example: - * {{{ - * scala> import cats.implicits._ - * - * scala> val noneInt: Option[Int] = None - * scala> val some3: Option[Int] = Some(3) - * scala> val noneString: Option[String] = None - * scala> val someFoo: Option[String] = Some("foo") - * - * scala> Semigroupal[Option].product(noneInt, noneString) - * res0: Option[(Int, String)] = None - * - * scala> Semigroupal[Option].product(noneInt, someFoo) - * res1: Option[(Int, String)] = None - * - * scala> Semigroupal[Option].product(some3, noneString) - * res2: Option[(Int, String)] = None - * - * scala> Semigroupal[Option].product(some3, someFoo) - * res3: Option[(Int, String)] = Some((3,foo)) - * }}} - */ + * Combine an `F[A]` and an `F[B]` into an `F[(A, B)]` that maintains the effects of both `fa` and `fb`. + * + * Example: + * {{{ + * scala> import cats.implicits._ + * + * scala> val noneInt: Option[Int] = None + * scala> val some3: Option[Int] = Some(3) + * scala> val noneString: Option[String] = None + * scala> val someFoo: Option[String] = Some("foo") + * + * scala> Semigroupal[Option].product(noneInt, noneString) + * res0: Option[(Int, String)] = None + * + * scala> Semigroupal[Option].product(noneInt, someFoo) + * res1: Option[(Int, String)] = None + * + * scala> Semigroupal[Option].product(some3, noneString) + * res2: Option[(Int, String)] = None + * + * scala> Semigroupal[Option].product(some3, someFoo) + * res3: Option[(Int, String)] = Some((3,foo)) + * }}} + */ def product[A, B](fa: F[A], fb: F[B]): F[(A, B)] } diff --git a/core/src/main/scala/cats/Show.scala b/core/src/main/scala/cats/Show.scala index 80cdf17797b..850b2440ed5 100644 --- a/core/src/main/scala/cats/Show.scala +++ b/core/src/main/scala/cats/Show.scala @@ -1,17 +1,17 @@ package cats /** - * A type class to provide textual representation. It is meant to be a - * better "toString". Whereas toString exists for any Object, - * regardless of whether or not the creator of the class explicitly - * made a toString method, a Show instance will only exist if someone - * explicitly provided one. - */ + * A type class to provide textual representation. It is meant to be a + * better "toString". Whereas toString exists for any Object, + * regardless of whether or not the creator of the class explicitly + * made a toString method, a Show instance will only exist if someone + * explicitly provided one. + */ trait Show[T] extends Show.ContravariantShow[T] /** - * Hand rolling the type class boilerplate due to scala/bug#6260 and scala/bug#10458 - */ + * Hand rolling the type class boilerplate due to scala/bug#6260 and scala/bug#10458 + */ object Show { def apply[A](implicit instance: Show[A]): Show[A] = instance @@ -45,15 +45,15 @@ object Show { final case class Shown(override val toString: String) extends AnyVal object Shown { - implicit def mat[A](x: A)(implicit z: ContravariantShow[A]): Shown = Shown(z show x) + implicit def mat[A](x: A)(implicit z: ContravariantShow[A]): Shown = Shown(z.show(x)) } final case class ShowInterpolator(_sc: StringContext) extends AnyVal { - def show(args: Shown*): String = _sc s (args: _*) + def show(args: Shown*): String = _sc.s(args: _*) } implicit val catsContravariantForShow: Contravariant[Show] = new Contravariant[Show] { def contramap[A, B](fa: Show[A])(f: B => A): Show[B] = - show[B](fa.show _ compose f) + show[B]((fa.show _).compose(f)) } } diff --git a/core/src/main/scala/cats/StackSafeMonad.scala b/core/src/main/scala/cats/StackSafeMonad.scala index b2f8afb20a1..9e581e7864d 100644 --- a/core/src/main/scala/cats/StackSafeMonad.scala +++ b/core/src/main/scala/cats/StackSafeMonad.scala @@ -3,17 +3,17 @@ package cats import scala.util.{Either, Left, Right} /** - * A mix-in for inheriting tailRecM on monads which define a stack-safe flatMap. This is - * ''not'' an appropriate trait to use unless you are 100% certain your monad is stack-safe - * by definition! If your monad is not stack-safe, then the tailRecM implementation you - * will inherit will not be sound, and will result in unexpected stack overflows. This - * trait is only provided because a large number of monads ''do'' define a stack-safe - * flatMap, and so this particular implementation was being repeated over and over again. - */ + * A mix-in for inheriting tailRecM on monads which define a stack-safe flatMap. This is + * ''not'' an appropriate trait to use unless you are 100% certain your monad is stack-safe + * by definition! If your monad is not stack-safe, then the tailRecM implementation you + * will inherit will not be sound, and will result in unexpected stack overflows. This + * trait is only provided because a large number of monads ''do'' define a stack-safe + * flatMap, and so this particular implementation was being repeated over and over again. + */ trait StackSafeMonad[F[_]] extends Monad[F] { override def tailRecM[A, B](a: A)(f: A => F[Either[A, B]]): F[B] = flatMap(f(a)) { - case Left(a) => tailRecM(a)(f) + case Left(a) => tailRecM(a)(f) case Right(b) => pure(b) } } diff --git a/core/src/main/scala/cats/Traverse.scala b/core/src/main/scala/cats/Traverse.scala index 3e1f1ac5fb1..fe2bd6ed6c7 100644 --- a/core/src/main/scala/cats/Traverse.scala +++ b/core/src/main/scala/cats/Traverse.scala @@ -6,83 +6,83 @@ import cats.data.StateT import simulacrum.typeclass /** - * Traverse, also known as Traversable. - * - * Traversal over a structure with an effect. - * - * Traversing with the [[cats.Id]] effect is equivalent to [[cats.Functor]]#map. - * Traversing with the [[cats.data.Const]] effect where the first type parameter has - * a [[cats.Monoid]] instance is equivalent to [[cats.Foldable]]#fold. - * - * See: [[https://www.cs.ox.ac.uk/jeremy.gibbons/publications/iterator.pdf The Essence of the Iterator Pattern]] - */ + * Traverse, also known as Traversable. + * + * Traversal over a structure with an effect. + * + * Traversing with the [[cats.Id]] effect is equivalent to [[cats.Functor]]#map. + * Traversing with the [[cats.data.Const]] effect where the first type parameter has + * a [[cats.Monoid]] instance is equivalent to [[cats.Foldable]]#fold. + * + * See: [[https://www.cs.ox.ac.uk/jeremy.gibbons/publications/iterator.pdf The Essence of the Iterator Pattern]] + */ @typeclass trait Traverse[F[_]] extends Functor[F] with Foldable[F] with UnorderedTraverse[F] { self => /** - * Given a function which returns a G effect, thread this effect - * through the running of this function on all the values in F, - * returning an F[B] in a G context. - * - * Example: - * {{{ - * scala> import cats.implicits._ - * scala> def parseInt(s: String): Option[Int] = Either.catchOnly[NumberFormatException](s.toInt).toOption - * scala> List("1", "2", "3").traverse(parseInt) - * res0: Option[List[Int]] = Some(List(1, 2, 3)) - * scala> List("1", "two", "3").traverse(parseInt) - * res1: Option[List[Int]] = None - * }}} - */ + * Given a function which returns a G effect, thread this effect + * through the running of this function on all the values in F, + * returning an F[B] in a G context. + * + * Example: + * {{{ + * scala> import cats.implicits._ + * scala> def parseInt(s: String): Option[Int] = Either.catchOnly[NumberFormatException](s.toInt).toOption + * scala> List("1", "2", "3").traverse(parseInt) + * res0: Option[List[Int]] = Some(List(1, 2, 3)) + * scala> List("1", "two", "3").traverse(parseInt) + * res1: Option[List[Int]] = None + * }}} + */ def traverse[G[_]: Applicative, A, B](fa: F[A])(f: A => G[B]): G[F[B]] /** - * A traverse followed by flattening the inner result. - * - * Example: - * {{{ - * scala> import cats.implicits._ - * scala> def parseInt(s: String): Option[Int] = Either.catchOnly[NumberFormatException](s.toInt).toOption - * scala> val x = Option(List("1", "two", "3")) - * scala> x.flatTraverse(_.map(parseInt)) - * res0: List[Option[Int]] = List(Some(1), None, Some(3)) - * }}} - */ + * A traverse followed by flattening the inner result. + * + * Example: + * {{{ + * scala> import cats.implicits._ + * scala> def parseInt(s: String): Option[Int] = Either.catchOnly[NumberFormatException](s.toInt).toOption + * scala> val x = Option(List("1", "two", "3")) + * scala> x.flatTraverse(_.map(parseInt)) + * res0: List[Option[Int]] = List(Some(1), None, Some(3)) + * }}} + */ def flatTraverse[G[_], A, B](fa: F[A])(f: A => G[F[B]])(implicit G: Applicative[G], F: FlatMap[F]): G[F[B]] = G.map(traverse(fa)(f))(F.flatten) /** - * Thread all the G effects through the F structure to invert the - * structure from F[G[A]] to G[F[A]]. - * - * Example: - * {{{ - * scala> import cats.implicits._ - * scala> val x: List[Option[Int]] = List(Some(1), Some(2)) - * scala> val y: List[Option[Int]] = List(None, Some(2)) - * scala> x.sequence - * res0: Option[List[Int]] = Some(List(1, 2)) - * scala> y.sequence - * res1: Option[List[Int]] = None - * }}} - */ + * Thread all the G effects through the F structure to invert the + * structure from F[G[A]] to G[F[A]]. + * + * Example: + * {{{ + * scala> import cats.implicits._ + * scala> val x: List[Option[Int]] = List(Some(1), Some(2)) + * scala> val y: List[Option[Int]] = List(None, Some(2)) + * scala> x.sequence + * res0: Option[List[Int]] = Some(List(1, 2)) + * scala> y.sequence + * res1: Option[List[Int]] = None + * }}} + */ def sequence[G[_]: Applicative, A](fga: F[G[A]]): G[F[A]] = traverse(fga)(ga => ga) /** - * Thread all the G effects through the F structure and flatten to invert the - * structure from F[G[F[A]]] to G[F[A]]. - * - * Example: - * {{{ - * scala> import cats.implicits._ - * scala> val x: List[Option[List[Int]]] = List(Some(List(1, 2)), Some(List(3))) - * scala> val y: List[Option[List[Int]]] = List(None, Some(List(3))) - * scala> x.flatSequence - * res0: Option[List[Int]] = Some(List(1, 2, 3)) - * scala> y.flatSequence - * res1: Option[List[Int]] = None - * }}} - */ + * Thread all the G effects through the F structure and flatten to invert the + * structure from F[G[F[A]]] to G[F[A]]. + * + * Example: + * {{{ + * scala> import cats.implicits._ + * scala> val x: List[Option[List[Int]]] = List(Some(List(1, 2)), Some(List(3))) + * scala> val y: List[Option[List[Int]]] = List(None, Some(List(3))) + * scala> x.flatSequence + * res0: Option[List[Int]] = Some(List(1, 2, 3)) + * scala> y.flatSequence + * res1: Option[List[Int]] = None + * }}} + */ def flatSequence[G[_], A](fgfa: F[G[F[A]]])(implicit G: Applicative[G], F: FlatMap[F]): G[F[A]] = G.map(sequence(fgfa))(F.flatten) @@ -96,38 +96,36 @@ import simulacrum.typeclass traverse[Id, A, B](fa)(f) /** - * Akin to [[map]], but also provides the value's index in structure - * F when calling the function. - */ + * Akin to [[map]], but also provides the value's index in structure + * F when calling the function. + */ def mapWithIndex[A, B](fa: F[A])(f: (A, Int) => B): F[B] = - traverse(fa)(a => - State((s: Int) => (s + 1, f(a, s)))).runA(0).value + traverse(fa)(a => State((s: Int) => (s + 1, f(a, s)))).runA(0).value /** - * Akin to [[traverse]], but also provides the value's index in - * structure F when calling the function. - * - * This performs the traversal in a single pass but requires that - * effect G is monadic. An applicative traversal can be performed in - * two passes using [[zipWithIndex]] followed by [[traverse]]. - */ + * Akin to [[traverse]], but also provides the value's index in + * structure F when calling the function. + * + * This performs the traversal in a single pass but requires that + * effect G is monadic. An applicative traversal can be performed in + * two passes using [[zipWithIndex]] followed by [[traverse]]. + */ def traverseWithIndexM[G[_], A, B](fa: F[A])(f: (A, Int) => G[B])(implicit G: Monad[G]): G[F[B]] = - traverse(fa)(a => - StateT((s: Int) => G.map(f(a, s))(b => (s + 1, b)))).runA(0) + traverse(fa)(a => StateT((s: Int) => G.map(f(a, s))(b => (s + 1, b)))).runA(0) /** - * Traverses through the structure F, pairing the values with - * assigned indices. - * - * The behavior is consistent with the Scala collection library's - * `zipWithIndex` for collections such as `List`. - */ + * Traverses through the structure F, pairing the values with + * assigned indices. + * + * The behavior is consistent with the Scala collection library's + * `zipWithIndex` for collections such as `List`. + */ def zipWithIndex[A](fa: F[A]): F[(A, Int)] = mapWithIndex(fa)((a, i) => (a, i)) - override def unorderedTraverse[G[_] : CommutativeApplicative, A, B](sa: F[A])(f: (A) => G[B]): G[F[B]] = + override def unorderedTraverse[G[_]: CommutativeApplicative, A, B](sa: F[A])(f: (A) => G[B]): G[F[B]] = traverse(sa)(f) - override def unorderedSequence[G[_] : CommutativeApplicative, A](fga: F[G[A]]): G[F[A]] = + override def unorderedSequence[G[_]: CommutativeApplicative, A](fga: F[G[A]]): G[F[A]] = sequence(fga) } diff --git a/core/src/main/scala/cats/TraverseFilter.scala b/core/src/main/scala/cats/TraverseFilter.scala index ea2848de638..55a7acec5d0 100644 --- a/core/src/main/scala/cats/TraverseFilter.scala +++ b/core/src/main/scala/cats/TraverseFilter.scala @@ -3,12 +3,12 @@ package cats import simulacrum.typeclass /** - * `TraverseFilter`, also known as `Witherable`, represents list-like structures - * that can essentially have a `traverse` and a `filter` applied as a single - * combined operation (`traverseFilter`). - * - * Based on Haskell's [[https://hackage.haskell.org/package/witherable-0.1.3.3/docs/Data-Witherable.html Data.Witherable]] - */ + * `TraverseFilter`, also known as `Witherable`, represents list-like structures + * that can essentially have a `traverse` and a `filter` applied as a single + * combined operation (`traverseFilter`). + * + * Based on Haskell's [[https://hackage.haskell.org/package/witherable-0.1.3.3/docs/Data-Witherable.html Data.Witherable]] + */ @typeclass trait TraverseFilter[F[_]] extends FunctorFilter[F] { @@ -17,43 +17,43 @@ trait TraverseFilter[F[_]] extends FunctorFilter[F] { final override def functor: Functor[F] = traverse /** - * A combined [[traverse]] and [[filter]]. Filtering is handled via `Option` - * instead of `Boolean` such that the output type `B` can be different than - * the input type `A`. - * - * Example: - * {{{ - * scala> import cats.implicits._ - * scala> val m: Map[Int, String] = Map(1 -> "one", 3 -> "three") - * scala> val l: List[Int] = List(1, 2, 3, 4) - * scala> def asString(i: Int): Eval[Option[String]] = Now(m.get(i)) - * scala> val result: Eval[List[String]] = l.traverseFilter(asString) - * scala> result.value - * res0: List[String] = List(one, three) - * }}} - */ + * A combined [[traverse]] and [[filter]]. Filtering is handled via `Option` + * instead of `Boolean` such that the output type `B` can be different than + * the input type `A`. + * + * Example: + * {{{ + * scala> import cats.implicits._ + * scala> val m: Map[Int, String] = Map(1 -> "one", 3 -> "three") + * scala> val l: List[Int] = List(1, 2, 3, 4) + * scala> def asString(i: Int): Eval[Option[String]] = Now(m.get(i)) + * scala> val result: Eval[List[String]] = l.traverseFilter(asString) + * scala> result.value + * res0: List[String] = List(one, three) + * }}} + */ def traverseFilter[G[_], A, B](fa: F[A])(f: A => G[Option[B]])(implicit G: Applicative[G]): G[F[B]] /** - * - * Filter values inside a `G` context. - * - * This is a generalized version of Haskell's [[http://hackage.haskell.org/package/base-4.9.0.0/docs/Control-Monad.html#v:filterM filterM]]. - * [[http://stackoverflow.com/questions/28872396/haskells-filterm-with-filterm-x-true-false-1-2-3 This StackOverflow question]] about `filterM` may be helpful in understanding how it behaves. - * - * Example: - * {{{ - * scala> import cats.implicits._ - * scala> val l: List[Int] = List(1, 2, 3, 4) - * scala> def odd(i: Int): Eval[Boolean] = Now(i % 2 == 1) - * scala> val res: Eval[List[Int]] = l.filterA(odd) - * scala> res.value - * res0: List[Int] = List(1, 3) - * - * scala> List(1, 2, 3).filterA(_ => List(true, false)) - * res1: List[List[Int]] = List(List(1, 2, 3), List(1, 2), List(1, 3), List(1), List(2, 3), List(2), List(3), List()) - * }}} - */ + * + * Filter values inside a `G` context. + * + * This is a generalized version of Haskell's [[http://hackage.haskell.org/package/base-4.9.0.0/docs/Control-Monad.html#v:filterM filterM]]. + * [[http://stackoverflow.com/questions/28872396/haskells-filterm-with-filterm-x-true-false-1-2-3 This StackOverflow question]] about `filterM` may be helpful in understanding how it behaves. + * + * Example: + * {{{ + * scala> import cats.implicits._ + * scala> val l: List[Int] = List(1, 2, 3, 4) + * scala> def odd(i: Int): Eval[Boolean] = Now(i % 2 == 1) + * scala> val res: Eval[List[Int]] = l.filterA(odd) + * scala> res.value + * res0: List[Int] = List(1, 3) + * + * scala> List(1, 2, 3).filterA(_ => List(true, false)) + * res1: List[List[Int]] = List(List(1, 2, 3), List(1, 2), List(1, 3), List(1), List(2, 3), List(2), List(3), List()) + * }}} + */ def filterA[G[_], A](fa: F[A])(f: A => G[Boolean])(implicit G: Applicative[G]): G[F[A]] = traverseFilter(fa)(a => G.map(f(a))(if (_) Some(a) else None)) diff --git a/core/src/main/scala/cats/UnorderedFoldable.scala b/core/src/main/scala/cats/UnorderedFoldable.scala index 6076933a089..ef0831483d2 100644 --- a/core/src/main/scala/cats/UnorderedFoldable.scala +++ b/core/src/main/scala/cats/UnorderedFoldable.scala @@ -3,6 +3,7 @@ package cats import cats.kernel.CommutativeMonoid import simulacrum.typeclass import cats.instances.long._ + /** * `UnorderedFoldable` is like a `Foldable` for unordered containers. */ @@ -13,7 +14,6 @@ import cats.instances.long._ def unorderedFold[A: CommutativeMonoid](fa: F[A]): A = unorderedFoldMap(fa)(identity) - /** * Returns true if there are no elements. Otherwise false. */ @@ -29,8 +29,7 @@ import cats.instances.long._ * If there are no elements, the result is `false`. */ def exists[A](fa: F[A])(p: A => Boolean): Boolean = - unorderedFoldMap(fa)(a => Eval.later(p(a)))(UnorderedFoldable.commutativeMonoidEval(UnorderedFoldable.orMonoid)) - .value + unorderedFoldMap(fa)(a => Eval.later(p(a)))(UnorderedFoldable.commutativeMonoidEval(UnorderedFoldable.orMonoid)).value /** * Check whether all elements satisfy the predicate. @@ -38,8 +37,7 @@ import cats.instances.long._ * If there are no elements, the result is `true`. */ def forall[A](fa: F[A])(p: A => Boolean): Boolean = - unorderedFoldMap(fa)(a => Eval.later(p(a)))(UnorderedFoldable.commutativeMonoidEval(UnorderedFoldable.andMonoid)) - .value + unorderedFoldMap(fa)(a => Eval.later(p(a)))(UnorderedFoldable.commutativeMonoidEval(UnorderedFoldable.andMonoid)).value /** * The size of this UnorderedFoldable. diff --git a/core/src/main/scala/cats/arrow/Arrow.scala b/core/src/main/scala/cats/arrow/Arrow.scala index f607a65f271..77b98b51cf6 100644 --- a/core/src/main/scala/cats/arrow/Arrow.scala +++ b/core/src/main/scala/cats/arrow/Arrow.scala @@ -4,16 +4,16 @@ package arrow import simulacrum.typeclass /** - * Must obey the laws defined in cats.laws.ArrowLaws. - */ + * Must obey the laws defined in cats.laws.ArrowLaws. + */ @typeclass trait Arrow[F[_, _]] extends Category[F] with Strong[F] { self => /** - * Lift a function into the context of an Arrow. - * - * In the reference articles "Arrows are Promiscuous...", and in the corresponding Haskell - * library `Control.Arrow`, this function is called `arr`. - */ + * Lift a function into the context of an Arrow. + * + * In the reference articles "Arrows are Promiscuous...", and in the corresponding Haskell + * library `Control.Arrow`, this function is called `arr`. + */ def lift[A, B](f: A => B): F[A, B] override def id[A]: F[A, A] = lift(identity) @@ -28,45 +28,44 @@ import simulacrum.typeclass } /** - * Create a new computation `F` that splits its input between `f` and `g` - * and combines the output of each. - * - * Example: - * {{{ - * scala> import cats.implicits._ - * scala> import cats.arrow.Arrow - * scala> val toLong: Int => Long = _.toLong - * scala> val toDouble: Float => Double = _.toDouble - * scala> val f: ((Int, Float)) => (Long, Double) = Arrow[Function1].split(toLong, toDouble) - * scala> f((3, 4.0f)) - * res0: (Long, Double) = (3,4.0) - * }}} - * - * Note that the arrow laws do not guarantee the non-interference between the _effects_ of - * `f` and `g` in the context of F. This means that `f *** g` may not be equivalent to `g *** f`. - */ + * Create a new computation `F` that splits its input between `f` and `g` + * and combines the output of each. + * + * Example: + * {{{ + * scala> import cats.implicits._ + * scala> import cats.arrow.Arrow + * scala> val toLong: Int => Long = _.toLong + * scala> val toDouble: Float => Double = _.toDouble + * scala> val f: ((Int, Float)) => (Long, Double) = Arrow[Function1].split(toLong, toDouble) + * scala> f((3, 4.0f)) + * res0: (Long, Double) = (3,4.0) + * }}} + * + * Note that the arrow laws do not guarantee the non-interference between the _effects_ of + * `f` and `g` in the context of F. This means that `f *** g` may not be equivalent to `g *** f`. + */ @simulacrum.op("***", alias = true) def split[A, B, C, D](f: F[A, B], g: F[C, D]): F[(A, C), (B, D)] = andThen(first(f), second(g)) /** - * Create a new computation `F` that merge outputs of `f` and `g` both having the same input - * - * Example: - * {{{ - * scala> import cats.implicits._ - * scala> val addEmpty: Int => Int = _ + 0 - * scala> val multiplyEmpty: Int => Double= _ * 1d - * scala> val f: Int => (Int, Double) = addEmpty &&& multiplyEmpty - * scala> f(1) - * res0: (Int, Double) = (1,1.0) - * }}} - * - * Note that the arrow laws do not guarantee the non-interference between the _effects_ of - * `f` and `g` in the context of F. This means that `f &&& g` may not be equivalent to `g &&& f`. - */ + * Create a new computation `F` that merge outputs of `f` and `g` both having the same input + * + * Example: + * {{{ + * scala> import cats.implicits._ + * scala> val addEmpty: Int => Int = _ + 0 + * scala> val multiplyEmpty: Int => Double= _ * 1d + * scala> val f: Int => (Int, Double) = addEmpty &&& multiplyEmpty + * scala> f(1) + * res0: (Int, Double) = (1,1.0) + * }}} + * + * Note that the arrow laws do not guarantee the non-interference between the _effects_ of + * `f` and `g` in the context of F. This means that `f &&& g` may not be equivalent to `g &&& f`. + */ @simulacrum.op("&&&", alias = true) - def merge[A, B, C](f: F[A, B], g: F[A, C]): F[A, (B, C)] = { + def merge[A, B, C](f: F[A, B], g: F[A, C]): F[A, (B, C)] = andThen(lift((x: A) => (x, x)), split(f, g)) - } } diff --git a/core/src/main/scala/cats/arrow/ArrowChoice.scala b/core/src/main/scala/cats/arrow/ArrowChoice.scala index c0e7870dbbe..4ddeb1beaed 100644 --- a/core/src/main/scala/cats/arrow/ArrowChoice.scala +++ b/core/src/main/scala/cats/arrow/ArrowChoice.scala @@ -4,31 +4,31 @@ package arrow import simulacrum.typeclass /** - * Must obey the laws defined in cats.laws.ArrowChoiceLaws. - */ + * Must obey the laws defined in cats.laws.ArrowChoiceLaws. + */ @typeclass trait ArrowChoice[F[_, _]] extends Arrow[F] with Choice[F] { self => /** - * ArrowChoice yields Arrows with choice, allowing distribution - * over coproducts. - * - * Given two `F`s (`f` and `g`), create a new `F` with - * domain the coproduct of the domains of `f` and `g`, - * and codomain the coproduct of the codomains of `f` and `g`. - * This is the sum notion to `split`'s product. - * - * Example: - * {{{ - * scala> import cats.implicits._ - * scala> val toLong: Int => Long = _.toLong - * scala> val toDouble: Float => Double = _.toDouble - * scala> val f: Either[Int, Float] => Either[Long, Double] = toLong +++ toDouble - * scala> f(Left(3)) - * res0: Either[Long,Double] = Left(3) - * scala> f(Right(3)) - * res1: Either[Long,Double] = Right(3.0) - * }}} - */ + * ArrowChoice yields Arrows with choice, allowing distribution + * over coproducts. + * + * Given two `F`s (`f` and `g`), create a new `F` with + * domain the coproduct of the domains of `f` and `g`, + * and codomain the coproduct of the codomains of `f` and `g`. + * This is the sum notion to `split`'s product. + * + * Example: + * {{{ + * scala> import cats.implicits._ + * scala> val toLong: Int => Long = _.toLong + * scala> val toDouble: Float => Double = _.toDouble + * scala> val f: Either[Int, Float] => Either[Long, Double] = toLong +++ toDouble + * scala> f(Left(3)) + * res0: Either[Long,Double] = Left(3) + * scala> f(Right(3)) + * res1: Either[Long,Double] = Right(3.0) + * }}} + */ @simulacrum.op("+++", alias = true) def choose[A, B, C, D](f: F[A, C])(g: F[B, D]): F[Either[A, B], Either[C, D]] diff --git a/core/src/main/scala/cats/arrow/Category.scala b/core/src/main/scala/cats/arrow/Category.scala index abd05ccab01..3be1e022fa4 100644 --- a/core/src/main/scala/cats/arrow/Category.scala +++ b/core/src/main/scala/cats/arrow/Category.scala @@ -4,8 +4,8 @@ package arrow import simulacrum.typeclass /** - * Must obey the laws defined in cats.laws.CategoryLaws. - */ + * Must obey the laws defined in cats.laws.CategoryLaws. + */ @typeclass trait Category[F[_, _]] extends Compose[F] { self => def id[A]: F[A, A] diff --git a/core/src/main/scala/cats/arrow/Choice.scala b/core/src/main/scala/cats/arrow/Choice.scala index 768f7ce2971..0406e1f1152 100644 --- a/core/src/main/scala/cats/arrow/Choice.scala +++ b/core/src/main/scala/cats/arrow/Choice.scala @@ -4,43 +4,44 @@ package arrow import simulacrum.typeclass @typeclass trait Choice[F[_, _]] extends Category[F] { + /** - * Given two `F`s (`f` and `g`) with a common target type, create a new `F` - * with the same target type, but with a source type of either `f`'s source - * type OR `g`'s source type. - * - * Example: - * {{{ - * scala> import cats.implicits._ - * scala> val b: Boolean => String = _ + " is a boolean" - * scala> val i: Int => String = _ + " is an integer" - * scala> val f: (Either[Boolean, Int]) => String = b ||| i - * - * scala> f(Right(3)) - * res0: String = 3 is an integer - * - * scala> f(Left(false)) - * res0: String = false is a boolean - * }}} - */ + * Given two `F`s (`f` and `g`) with a common target type, create a new `F` + * with the same target type, but with a source type of either `f`'s source + * type OR `g`'s source type. + * + * Example: + * {{{ + * scala> import cats.implicits._ + * scala> val b: Boolean => String = _ + " is a boolean" + * scala> val i: Int => String = _ + " is an integer" + * scala> val f: (Either[Boolean, Int]) => String = b ||| i + * + * scala> f(Right(3)) + * res0: String = 3 is an integer + * + * scala> f(Left(false)) + * res0: String = false is a boolean + * }}} + */ @simulacrum.op("|||", alias = true) def choice[A, B, C](f: F[A, C], g: F[B, C]): F[Either[A, B], C] /** - * An `F` that, given a source `A` on either the right or left side, will - * return that same `A` object. - * - * Example: - * {{{ - * scala> import cats.implicits._ - * scala> val f: (Either[Int, Int]) => Int = Choice[Function1].codiagonal[Int] - * - * scala> f(Right(3)) - * res0: Int = 3 - * - * scala> f(Left(3)) - * res1: Int = 3 - * }}} - */ + * An `F` that, given a source `A` on either the right or left side, will + * return that same `A` object. + * + * Example: + * {{{ + * scala> import cats.implicits._ + * scala> val f: (Either[Int, Int]) => Int = Choice[Function1].codiagonal[Int] + * + * scala> f(Right(3)) + * res0: Int = 3 + * + * scala> f(Left(3)) + * res1: Int = 3 + * }}} + */ def codiagonal[A]: F[Either[A, A], A] = choice(id, id) } diff --git a/core/src/main/scala/cats/arrow/CommutativeArrow.scala b/core/src/main/scala/cats/arrow/CommutativeArrow.scala index d0742985242..59d299a300c 100644 --- a/core/src/main/scala/cats/arrow/CommutativeArrow.scala +++ b/core/src/main/scala/cats/arrow/CommutativeArrow.scala @@ -10,4 +10,3 @@ import simulacrum.typeclass * Must obey the laws in CommutativeArrowLaws */ @typeclass trait CommutativeArrow[F[_, _]] extends Arrow[F] - diff --git a/core/src/main/scala/cats/arrow/Compose.scala b/core/src/main/scala/cats/arrow/Compose.scala index c520eb5f194..feb8a45447c 100644 --- a/core/src/main/scala/cats/arrow/Compose.scala +++ b/core/src/main/scala/cats/arrow/Compose.scala @@ -4,20 +4,20 @@ package arrow import simulacrum.typeclass /** - * Must obey the laws defined in cats.laws.ComposeLaws. - * - * Here's how you can use `>>>` and `<<<` - * Example: - * {{{ - * scala> import cats.implicits._ - * scala> val f : Int => Int = (_ + 1) - * scala> val g : Int => Int = (_ * 100) - * scala> (f >>> g)(3) - * res0: Int = 400 - * scala> (f <<< g)(3) - * res1: Int = 301 - * }}} - */ + * Must obey the laws defined in cats.laws.ComposeLaws. + * + * Here's how you can use `>>>` and `<<<` + * Example: + * {{{ + * scala> import cats.implicits._ + * scala> val f : Int => Int = (_ + 1) + * scala> val g : Int => Int = (_ * 100) + * scala> (f >>> g)(3) + * res0: Int = 400 + * scala> (f <<< g)(3) + * res1: Int = 301 + * }}} + */ @typeclass trait Compose[F[_, _]] { self => @simulacrum.op("<<<", alias = true) diff --git a/core/src/main/scala/cats/arrow/FunctionK.scala b/core/src/main/scala/cats/arrow/FunctionK.scala index 2316a71ce6f..858e82d21df 100644 --- a/core/src/main/scala/cats/arrow/FunctionK.scala +++ b/core/src/main/scala/cats/arrow/FunctionK.scala @@ -47,18 +47,18 @@ trait FunctionK[F[_], G[_]] extends Serializable { self => λ[FunctionK[EitherK[F, H, ?], G]](fa => fa.fold(self, h)) /** - * Composes two instances of `FunctionK` into a new `FunctionK` that transforms - * one single functor to a [[cats.data.Tuple2K]] of two functors. - * - * {{{ - * scala> import cats.arrow.FunctionK - * scala> val list2option = λ[FunctionK[List, Option]](_.headOption) - * scala> val list2vector = λ[FunctionK[List, Vector]](_.toVector) - * scala> val optionAndVector = list2option and list2vector - * scala> optionAndVector(List(1,2,3)) - * res0: cats.data.Tuple2K[Option,Vector,Int] = Tuple2K(Some(1),Vector(1, 2, 3)) - * }}} - */ + * Composes two instances of `FunctionK` into a new `FunctionK` that transforms + * one single functor to a [[cats.data.Tuple2K]] of two functors. + * + * {{{ + * scala> import cats.arrow.FunctionK + * scala> val list2option = λ[FunctionK[List, Option]](_.headOption) + * scala> val list2vector = λ[FunctionK[List, Vector]](_.toVector) + * scala> val optionAndVector = list2option and list2vector + * scala> optionAndVector(List(1,2,3)) + * res0: cats.data.Tuple2K[Option,Vector,Int] = Tuple2K(Some(1),Vector(1, 2, 3)) + * }}} + */ def and[H[_]](h: FunctionK[F, H]): FunctionK[F, Tuple2K[G, H, ?]] = λ[FunctionK[F, Tuple2K[G, H, ?]]](fa => Tuple2K(self(fa), h(fa))) } @@ -70,7 +70,6 @@ object FunctionK { */ def id[F[_]]: FunctionK[F, F] = λ[FunctionK[F, F]](fa => fa) - /** * Lifts function `f` of `F[A] => G[A]` into a `FunctionK[F, G]`. * @@ -100,25 +99,26 @@ private[arrow] object FunctionKMacros { def lift[F[_], G[_]](c: Context)( f: c.Expr[(F[α] ⇒ G[α]) forSome { type α }] )( - implicit evF: c.WeakTypeTag[F[_]], evG: c.WeakTypeTag[G[_]] + implicit evF: c.WeakTypeTag[F[_]], + evG: c.WeakTypeTag[G[_]] ): c.Expr[FunctionK[F, G]] = - c.Expr[FunctionK[F, G]](new Lifter[c.type ](c).lift[F, G](f.tree)) - // ^^note: extra space after c.type to appease scalastyle + c.Expr[FunctionK[F, G]](new Lifter[c.type](c).lift[F, G](f.tree)) + // ^^note: extra space after c.type to appease scalastyle private[this] class Lifter[C <: Context](val c: C) { import c.universe._ def lift[F[_], G[_]](tree: Tree)( - implicit evF: c.WeakTypeTag[F[_]], evG: c.WeakTypeTag[G[_]] + implicit evF: c.WeakTypeTag[F[_]], + evG: c.WeakTypeTag[G[_]] ): Tree = unblock(tree) match { - case q"($param) => $trans[..$typeArgs](${ arg: Ident })" if param.name == arg.name ⇒ - + case q"($param) => $trans[..$typeArgs](${arg: Ident})" if param.name == arg.name ⇒ typeArgs .collect { case tt: TypeTree => tt } .find(tt => Option(tt.original).isDefined) - .foreach { param => c.abort(param.pos, - s"type parameter $param must not be supplied when lifting function $trans to FunctionK") - } + .foreach { param => + c.abort(param.pos, s"type parameter $param must not be supplied when lifting function $trans to FunctionK") + } val F = punchHole(evF.tpe) val G = punchHole(evG.tpe) @@ -134,7 +134,7 @@ private[arrow] object FunctionKMacros { private[this] def unblock(tree: Tree): Tree = tree match { case Block(Nil, expr) ⇒ expr - case _ ⇒ tree + case _ ⇒ tree } private[this] def punchHole(tpe: Type): Tree = tpe match { @@ -145,7 +145,7 @@ private[arrow] object FunctionKMacros { else { val args = typeRef.args.map { case ref: TypeRef => rebind(ref) - case arg => tq"$arg" + case arg => tq"$arg" } tq"${typeRef.sym}[..$args]" } diff --git a/core/src/main/scala/cats/arrow/Profunctor.scala b/core/src/main/scala/cats/arrow/Profunctor.scala index 31ca4281ba3..6a572686275 100644 --- a/core/src/main/scala/cats/arrow/Profunctor.scala +++ b/core/src/main/scala/cats/arrow/Profunctor.scala @@ -4,39 +4,39 @@ package arrow import simulacrum.typeclass /** - * A [[Profunctor]] is a [[Contravariant]] functor on its first type parameter - * and a [[Functor]] on its second type parameter. - * - * Must obey the laws defined in cats.laws.ProfunctorLaws. - */ + * A [[Profunctor]] is a [[Contravariant]] functor on its first type parameter + * and a [[Functor]] on its second type parameter. + * + * Must obey the laws defined in cats.laws.ProfunctorLaws. + */ @typeclass trait Profunctor[F[_, _]] { self => /** - * Contramap on the first type parameter and map on the second type parameter - * - * Example: - * {{{ - * scala> import cats.implicits._ - * scala> import cats.arrow.Profunctor - * scala> val fab: Double => Double = x => x + 0.3 - * scala> val f: Int => Double = x => x.toDouble / 2 - * scala> val g: Double => Double = x => x * 3 - * scala> val h = Profunctor[Function1].dimap(fab)(f)(g) - * scala> h(3) - * res0: Double = 5.4 - * }}} - */ + * Contramap on the first type parameter and map on the second type parameter + * + * Example: + * {{{ + * scala> import cats.implicits._ + * scala> import cats.arrow.Profunctor + * scala> val fab: Double => Double = x => x + 0.3 + * scala> val f: Int => Double = x => x.toDouble / 2 + * scala> val g: Double => Double = x => x * 3 + * scala> val h = Profunctor[Function1].dimap(fab)(f)(g) + * scala> h(3) + * res0: Double = 5.4 + * }}} + */ def dimap[A, B, C, D](fab: F[A, B])(f: C => A)(g: B => D): F[C, D] /** - * contramap on the first type parameter - */ + * contramap on the first type parameter + */ def lmap[A, B, C](fab: F[A, B])(f: C => A): F[C, B] = dimap(fab)(f)(identity) /** - * map on the second type parameter - */ + * map on the second type parameter + */ def rmap[A, B, C](fab: F[A, B])(f: B => C): F[A, C] = dimap[A, B, A, C](fab)(identity)(f) } diff --git a/core/src/main/scala/cats/arrow/Strong.scala b/core/src/main/scala/cats/arrow/Strong.scala index 46629700a8f..8d9a8af6cd8 100644 --- a/core/src/main/scala/cats/arrow/Strong.scala +++ b/core/src/main/scala/cats/arrow/Strong.scala @@ -4,37 +4,37 @@ package arrow import simulacrum.typeclass /** - * Must obey the laws defined in cats.laws.StrongLaws. - */ + * Must obey the laws defined in cats.laws.StrongLaws. + */ @typeclass trait Strong[F[_, _]] extends Profunctor[F] { /** - * Create a new `F` that takes two inputs, but only modifies the first input - * - * Example: - * {{{ - * scala> import cats.implicits._ - * scala> import cats.arrow.Strong - * scala> val f: Int => Int = _ * 2 - * scala> val fab = Strong[Function1].first[Int,Int,Int](f) - * scala> fab((2,3)) - * res0: (Int, Int) = (4,3) - * }}} - */ + * Create a new `F` that takes two inputs, but only modifies the first input + * + * Example: + * {{{ + * scala> import cats.implicits._ + * scala> import cats.arrow.Strong + * scala> val f: Int => Int = _ * 2 + * scala> val fab = Strong[Function1].first[Int,Int,Int](f) + * scala> fab((2,3)) + * res0: (Int, Int) = (4,3) + * }}} + */ def first[A, B, C](fa: F[A, B]): F[(A, C), (B, C)] /** - * Create a new `F` that takes two inputs, but only modifies the second input - * - * Example: - * {{{ - * scala> import cats.implicits._ - * scala> import cats.arrow.Strong - * scala> val f: Int => Int = _ * 2 - * scala> val fab = Strong[Function1].second[Int,Int,Int](f) - * scala> fab((2,3)) - * res0: (Int, Int) = (2,6) - * }}} - */ + * Create a new `F` that takes two inputs, but only modifies the second input + * + * Example: + * {{{ + * scala> import cats.implicits._ + * scala> import cats.arrow.Strong + * scala> val f: Int => Int = _ * 2 + * scala> val fab = Strong[Function1].second[Int,Int,Int](f) + * scala> fab((2,3)) + * res0: (Int, Int) = (2,6) + * }}} + */ def second[A, B, C](fa: F[A, B]): F[(C, A), (C, B)] } diff --git a/core/src/main/scala/cats/data/AndThen.scala b/core/src/main/scala/cats/data/AndThen.scala index 468382769f6..a523c0cfc75 100644 --- a/core/src/main/scala/cats/data/AndThen.scala +++ b/core/src/main/scala/cats/data/AndThen.scala @@ -4,71 +4,69 @@ package data import java.io.Serializable import cats.arrow.{ArrowChoice, CommutativeArrow} - /** - * A function type of a single input that can do function composition - * (via `andThen` and `compose`) in constant stack space with amortized - * linear time application (in the number of constituent functions). - * - * Example: - * - * {{{ - * val seed = AndThen((x: Int) => x + 1)) - * val f = (0 until 10000).foldLeft(seed)((acc, _) => acc.andThen(_ + 1)) - * - * // This should not trigger stack overflow ;-) - * f(0) - * }}} - * - * This can be used to build stack safe data structures that make - * use of lambdas. The perfect candidates for usage with `AndThen` - * are the data structures using a signature like this (where - * `F[_]` is a monadic type): - * - * {{{ - * A => F[B] - * }}} - * - * As an example, if we described this data structure, the naive - * solution for that `map` is stack unsafe: - * - * {{{ - * case class Resource[F[_], A, B]( - * acquire: F[A], - * use: A => F[B], - * release: A => F[Unit]) { - * - * def flatMap[C](f: B => C)(implicit F: Functor[F]): Resource[F, A, C] = { - * Resource( - * ra.acquire, - * // Stack Unsafe! - * a => ra.use(a).map(f), - * ra.release) - * } - * } - * }}} - * - * To describe a `flatMap` operation for this data type, `AndThen` - * can save the day: - * - * {{{ - * def flatMap[C](f: B => C)(implicit F: Functor[F]): Resource[F, A, C] = { - * Resource( - * ra.acquire, - * AndThen(ra.use).andThen(_.map(f)), - * ra.release) - * } - * }}} - */ -sealed abstract class AndThen[-T, +R] - extends (T => R) with Product with Serializable { + * A function type of a single input that can do function composition + * (via `andThen` and `compose`) in constant stack space with amortized + * linear time application (in the number of constituent functions). + * + * Example: + * + * {{{ + * val seed = AndThen((x: Int) => x + 1)) + * val f = (0 until 10000).foldLeft(seed)((acc, _) => acc.andThen(_ + 1)) + * + * // This should not trigger stack overflow ;-) + * f(0) + * }}} + * + * This can be used to build stack safe data structures that make + * use of lambdas. The perfect candidates for usage with `AndThen` + * are the data structures using a signature like this (where + * `F[_]` is a monadic type): + * + * {{{ + * A => F[B] + * }}} + * + * As an example, if we described this data structure, the naive + * solution for that `map` is stack unsafe: + * + * {{{ + * case class Resource[F[_], A, B]( + * acquire: F[A], + * use: A => F[B], + * release: A => F[Unit]) { + * + * def flatMap[C](f: B => C)(implicit F: Functor[F]): Resource[F, A, C] = { + * Resource( + * ra.acquire, + * // Stack Unsafe! + * a => ra.use(a).map(f), + * ra.release) + * } + * } + * }}} + * + * To describe a `flatMap` operation for this data type, `AndThen` + * can save the day: + * + * {{{ + * def flatMap[C](f: B => C)(implicit F: Functor[F]): Resource[F, A, C] = { + * Resource( + * ra.acquire, + * AndThen(ra.use).andThen(_.map(f)), + * ra.release) + * } + * }}} + */ +sealed abstract class AndThen[-T, +R] extends (T => R) with Product with Serializable { import AndThen._ final def apply(a: T): R = runLoop(a) - override def andThen[A](g: R => A): AndThen[T, A] = { + override def andThen[A](g: R => A): AndThen[T, A] = // Fusing calls up to a certain threshold, using the fusion // technique implemented for `cats.effect.IO#map` this match { @@ -77,9 +75,8 @@ sealed abstract class AndThen[-T, +R] case _ => andThenF(AndThen(g)) } - } - override def compose[A](g: A => T): AndThen[A, R] = { + override def compose[A](g: A => T): AndThen[A, R] = // Fusing calls up to a certain threshold, using the fusion // technique implemented for `cats.effect.IO#map` this match { @@ -88,7 +85,6 @@ sealed abstract class AndThen[-T, +R] case _ => composeF(AndThen(g)) } - } private def runLoop(start: T): R = { var self: AndThen[Any, Any] = this.asInstanceOf[AndThen[Any, Any]] @@ -112,13 +108,13 @@ sealed abstract class AndThen[-T, +R] current.asInstanceOf[R] } - private final def andThenF[X](right: AndThen[R, X]): AndThen[T, X] = + final private def andThenF[X](right: AndThen[R, X]): AndThen[T, X] = Concat(this, right) - private final def composeF[X](right: AndThen[X, T]): AndThen[X, R] = + final private def composeF[X](right: AndThen[X, T]): AndThen[X, R] = Concat(right, this) // converts left-leaning to right-leaning - protected final def rotateAccum[E](_right: AndThen[R, E]): AndThen[T, E] = { + final protected def rotateAccum[E](_right: AndThen[R, E]): AndThen[T, E] = { var self: AndThen[Any, Any] = this.asInstanceOf[AndThen[Any, Any]] var right: AndThen[Any, Any] = _right.asInstanceOf[AndThen[Any, Any]] var continue = true @@ -141,37 +137,37 @@ sealed abstract class AndThen[-T, +R] } object AndThen extends AndThenInstances0 { + /** Builds an [[AndThen]] reference by wrapping a plain function. */ def apply[A, B](f: A => B): AndThen[A, B] = f match { case ref: AndThen[A, B] @unchecked => ref - case _ => Single(f, 0) + case _ => Single(f, 0) } - private final case class Single[-A, +B](f: A => B, index: Int) - extends AndThen[A, B] - private final case class Concat[-A, E, +B](left: AndThen[A, E], right: AndThen[E, B]) - extends AndThen[A, B] + final private case class Single[-A, +B](f: A => B, index: Int) extends AndThen[A, B] + final private case class Concat[-A, E, +B](left: AndThen[A, E], right: AndThen[E, B]) extends AndThen[A, B] /** - * Establishes the maximum stack depth when fusing `andThen` or - * `compose` calls. - * - * The default is `128`, from which we subtract one as an optimization, - * a "!=" comparison being slightly more efficient than a "<". - * - * This value was reached by taking into account the default stack - * size as set on 32 bits or 64 bits, Linux or Windows systems, - * being enough to notice performance gains, but not big enough - * to be in danger of triggering a stack-overflow error. - */ - private final val fusionMaxStackDepth = 127 + * Establishes the maximum stack depth when fusing `andThen` or + * `compose` calls. + * + * The default is `128`, from which we subtract one as an optimization, + * a "!=" comparison being slightly more efficient than a "<". + * + * This value was reached by taking into account the default stack + * size as set on 32 bits or 64 bits, Linux or Windows systems, + * being enough to notice performance gains, but not big enough + * to be in danger of triggering a stack-overflow error. + */ + final private val fusionMaxStackDepth = 127 } -private[data] abstract class AndThenInstances0 extends AndThenInstances1 { +abstract private[data] class AndThenInstances0 extends AndThenInstances1 { + /** - * [[cats.Monad]] instance for [[AndThen]]. - */ + * [[cats.Monad]] instance for [[AndThen]]. + */ implicit def catsDataMonadForAndThen[T]: Monad[AndThen[T, ?]] = new Monad[AndThen[T, ?]] { // Piggybacking on the instance for Function1 @@ -191,9 +187,9 @@ private[data] abstract class AndThenInstances0 extends AndThenInstances1 { } /** - * [[cats.ContravariantMonoidal]] instance for [[AndThen]]. - */ - implicit def catsDataContravariantMonoidalForAndThen[R : Monoid]: ContravariantMonoidal[AndThen[?, R]] = + * [[cats.ContravariantMonoidal]] instance for [[AndThen]]. + */ + implicit def catsDataContravariantMonoidalForAndThen[R: Monoid]: ContravariantMonoidal[AndThen[?, R]] = new ContravariantMonoidal[AndThen[?, R]] { // Piggybacking on the instance for Function1 private[this] val fn1 = instances.all.catsStdContravariantMonoidalForFunction1[R] @@ -209,10 +205,10 @@ private[data] abstract class AndThenInstances0 extends AndThenInstances1 { } /** - * [[cats.arrow.ArrowChoice ArrowChoice]] and - * [[cats.arrow.CommutativeArrow CommutativeArrow]] instances - * for [[AndThen]]. - */ + * [[cats.arrow.ArrowChoice ArrowChoice]] and + * [[cats.arrow.CommutativeArrow CommutativeArrow]] instances + * for [[AndThen]]. + */ implicit val catsDataArrowForAndThen: ArrowChoice[AndThen] with CommutativeArrow[AndThen] = new ArrowChoice[AndThen] with CommutativeArrow[AndThen] { // Piggybacking on the instance for Function1 @@ -235,10 +231,11 @@ private[data] abstract class AndThenInstances0 extends AndThenInstances1 { } } -private[data] abstract class AndThenInstances1 { +abstract private[data] class AndThenInstances1 { + /** - * [[cats.Contravariant]] instance for [[AndThen]]. - */ + * [[cats.Contravariant]] instance for [[AndThen]]. + */ implicit def catsDataContravariantForAndThen[R]: Contravariant[AndThen[?, R]] = new Contravariant[AndThen[?, R]] { def contramap[T1, T0](fa: AndThen[T1, R])(f: T0 => T1): AndThen[T0, R] = diff --git a/core/src/main/scala/cats/data/Binested.scala b/core/src/main/scala/cats/data/Binested.scala index 4dd732c11f5..d2fc701b097 100644 --- a/core/src/main/scala/cats/data/Binested.scala +++ b/core/src/main/scala/cats/data/Binested.scala @@ -4,59 +4,68 @@ package data import cats.arrow._ /** Compose a two-slot type constructor `F[_, _]` with two single-slot type constructors - * `G[_]` and `H[_]`, resulting in a two-slot type constructor with respect to the inner types. - * For example, `List` and `Option` both have `Functor` instances, and `Either` has a - * `Bifunctor` instance. Therefore, `Binested[Either, List, Option, ?, ?]` has a `Bifunctor` - * instance as well: - * - * {{{ - * scala> import cats.Bifunctor - * scala> import cats.data.Binested - * scala> import cats.implicits._ - * scala> val eitherListOption: Either[List[Int], Option[String]] = Right(Some("cats")) - * scala> val f: Int => String = _.toString - * scala> val g: String => String = _ + "-bifunctor" - * scala> val binested = Binested(eitherListOption) - * scala> val bimapped = Bifunctor[Binested[Either, List, Option, ?, ?]].bimap(binested)(f, g).value - * res0: Either[List[String], Option[String]] = Right(Some("cats-bifunctor")) - * }}} - */ + * `G[_]` and `H[_]`, resulting in a two-slot type constructor with respect to the inner types. + * For example, `List` and `Option` both have `Functor` instances, and `Either` has a + * `Bifunctor` instance. Therefore, `Binested[Either, List, Option, ?, ?]` has a `Bifunctor` + * instance as well: + * + * {{{ + * scala> import cats.Bifunctor + * scala> import cats.data.Binested + * scala> import cats.implicits._ + * scala> val eitherListOption: Either[List[Int], Option[String]] = Right(Some("cats")) + * scala> val f: Int => String = _.toString + * scala> val g: String => String = _ + "-bifunctor" + * scala> val binested = Binested(eitherListOption) + * scala> val bimapped = Bifunctor[Binested[Either, List, Option, ?, ?]].bimap(binested)(f, g).value + * res0: Either[List[String], Option[String]] = Right(Some("cats-bifunctor")) + * }}} + */ final case class Binested[F[_, _], G[_], H[_], A, B](value: F[G[A], H[B]]) object Binested extends BinestedInstances trait BinestedInstances extends BinestedInstances0 { implicit def catsDataEqForBinested[F[_, _], G[_], H[_], A, B]( - implicit F: Eq[F[G[A], H[B]]]): Eq[Binested[F, G, H, A, B]] = + implicit F: Eq[F[G[A], H[B]]] + ): Eq[Binested[F, G, H, A, B]] = Eq.by(_.value) - implicit def catsDataProfunctorForBinested[F[_, _], G[_], H[_]]( - implicit F: Profunctor[F], G: Functor[G], H: Functor[H]): Profunctor[Binested[F, G, H, ?, ?]] = + implicit def catsDataProfunctorForBinested[F[_, _], G[_], H[_]](implicit F: Profunctor[F], + G: Functor[G], + H: Functor[H]): Profunctor[Binested[F, G, H, ?, ?]] = new Profunctor[Binested[F, G, H, ?, ?]] { def dimap[A, B, C, D](fab: Binested[F, G, H, A, B])(f: C => A)(g: B => D): Binested[F, G, H, C, D] = Binested(F.dimap(fab.value)(G.map(_: G[C])(f))(H.map(_)(g))) } implicit def catsDataBitraverseForBinested[F[_, _], G[_], H[_]]( - implicit F0: Bitraverse[F], H0: Traverse[H], G0: Traverse[G]): Bitraverse[Binested[F, G, H, ?, ?]] = + implicit F0: Bitraverse[F], + H0: Traverse[H], + G0: Traverse[G] + ): Bitraverse[Binested[F, G, H, ?, ?]] = new BinestedBitraverse[F, G, H] { - override implicit def F: Bitraverse[F] = F0 - override implicit def G: Traverse[G] = G0 - override implicit def H: Traverse[H] = H0 + implicit override def F: Bitraverse[F] = F0 + implicit override def G: Traverse[G] = G0 + implicit override def H: Traverse[H] = H0 } } trait BinestedInstances0 { implicit def catsDataBifoldableForBinested[F[_, _], G[_], H[_]]( - implicit F0: Bifoldable[F], G0: Foldable[G], H0: Foldable[H]): Bifoldable[Binested[F, G, H, ?, ?]] = + implicit F0: Bifoldable[F], + G0: Foldable[G], + H0: Foldable[H] + ): Bifoldable[Binested[F, G, H, ?, ?]] = new BinestedBifoldable[F, G, H] { - override implicit def F: Bifoldable[F] = F0 - override implicit def G: Foldable[G] = G0 - override implicit def H: Foldable[H] = H0 + implicit override def F: Bifoldable[F] = F0 + implicit override def G: Foldable[G] = G0 + implicit override def H: Foldable[H] = H0 } - implicit def catsDataBifunctorForBinested[F[_, _], G[_], H[_]]( - implicit F: Bifunctor[F], G: Functor[G], H: Functor[H]): Bifunctor[Binested[F, G, H, ?, ?]] = + implicit def catsDataBifunctorForBinested[F[_, _], G[_], H[_]](implicit F: Bifunctor[F], + G: Functor[G], + H: Functor[H]): Bifunctor[Binested[F, G, H, ?, ?]] = new Bifunctor[Binested[F, G, H, ?, ?]] { def bimap[A, B, C, D](fab: Binested[F, G, H, A, B])(f: A => C, g: B => D): Binested[F, G, H, C, D] = Binested(F.bimap(fab.value)(G.map(_)(f), H.map(_)(g))) @@ -74,20 +83,23 @@ sealed abstract class BinestedBifoldable[F[_, _], G[_], H[_]] extends Bifoldable (c, hb) => H.foldLeft(hb, c)(g) ) - - def bifoldRight[A, B, C](fab: Binested[F, G, H, A, B], c: Eval[C])(f: (A, Eval[C]) => Eval[C], g: (B, Eval[C]) => Eval[C]): Eval[C] = + def bifoldRight[A, B, C](fab: Binested[F, G, H, A, B], c: Eval[C])(f: (A, Eval[C]) => Eval[C], + g: (B, Eval[C]) => Eval[C]): Eval[C] = F.bifoldRight(fab.value, c)( (ga, ec) => G.foldRight(ga, ec)(f), (hb, ec) => H.foldRight(hb, ec)(g) ) } -sealed abstract class BinestedBitraverse[F[_, _], G[_], H[_]] extends BinestedBifoldable[F, G, H] with Bitraverse[Binested[F, G, H, ?, ?]] { - override implicit def F: Bitraverse[F] - override implicit def G: Traverse[G] - override implicit def H: Traverse[H] +sealed abstract class BinestedBitraverse[F[_, _], G[_], H[_]] + extends BinestedBifoldable[F, G, H] + with Bitraverse[Binested[F, G, H, ?, ?]] { + implicit override def F: Bitraverse[F] + implicit override def G: Traverse[G] + implicit override def H: Traverse[H] - def bitraverse[I[_], A, B, C, D](fab: Binested[F, G, H, A, B])(f: A => I[C], g: B => I[D])(implicit I: Applicative[I]): I[Binested[F, G, H, C, D]] = { + def bitraverse[I[_], A, B, C, D]( + fab: Binested[F, G, H, A, B] + )(f: A => I[C], g: B => I[D])(implicit I: Applicative[I]): I[Binested[F, G, H, C, D]] = I.map(F.bitraverse(fab.value)(G.traverse(_)(f), H.traverse(_)(g)))(Binested(_)) - } } diff --git a/core/src/main/scala/cats/data/Chain.scala b/core/src/main/scala/cats/data/Chain.scala index 904856852d2..71af449b928 100644 --- a/core/src/main/scala/cats/data/Chain.scala +++ b/core/src/main/scala/cats/data/Chain.scala @@ -8,15 +8,15 @@ import scala.collection.immutable.SortedMap import scala.collection.mutable.ListBuffer /** - * Trivial catenable sequence. Supports O(1) append, and (amortized) - * O(1) `uncons`, such that walking the sequence via N successive `uncons` - * steps takes O(N). - */ + * Trivial catenable sequence. Supports O(1) append, and (amortized) + * O(1) `uncons`, such that walking the sequence via N successive `uncons` + * steps takes O(N). + */ sealed abstract class Chain[+A] { /** - * Returns the head and tail of this Chain if non empty, none otherwise. Amortized O(1). - */ + * Returns the head and tail of this Chain if non empty, none otherwise. Amortized O(1). + */ final def uncons: Option[(A, Chain[A])] = { var c: Chain[A] = this val rights = new collection.mutable.ArrayBuffer[Chain[A]] @@ -46,61 +46,60 @@ sealed abstract class Chain[+A] { } /** - * Returns true if there are no elements in this collection. - */ + * Returns true if there are no elements in this collection. + */ def isEmpty: Boolean /** - * Returns false if there are no elements in this collection. - */ + * Returns false if there are no elements in this collection. + */ final def nonEmpty: Boolean = !isEmpty /** - * Concatenates this with `c` in O(1) runtime. - */ + * Concatenates this with `c` in O(1) runtime. + */ final def concat[A2 >: A](c: Chain[A2]): Chain[A2] = Chain.concat(this, c) /** - * Alias for concat - */ + * Alias for concat + */ final def ++[A2 >: A](c: Chain[A2]): Chain[A2] = concat(c) /** - * Returns a new Chain consisting of `a` followed by this. O(1) runtime. - */ + * Returns a new Chain consisting of `a` followed by this. O(1) runtime. + */ final def prepend[A2 >: A](a: A2): Chain[A2] = Chain.concat(one(a), this) /** - * Alias for [[prepend]]. - */ + * Alias for [[prepend]]. + */ final def +:[A2 >: A](a: A2): Chain[A2] = prepend(a) /** - * Returns a new Chain consisting of this followed by `a`. O(1) runtime. - */ + * Returns a new Chain consisting of this followed by `a`. O(1) runtime. + */ final def append[A2 >: A](a: A2): Chain[A2] = Chain.concat(this, one(a)) /** - * Alias for [[append]]. - */ + * Alias for [[append]]. + */ final def :+[A2 >: A](a: A2): Chain[A2] = append(a) /** - * Applies the supplied function to each element and returns a new Chain. - */ + * Applies the supplied function to each element and returns a new Chain. + */ final def map[B](f: A => B): Chain[B] = fromSeq(iterator.map(f).toVector) - /** - * Applies the supplied function to each element and returns a new Chain from the concatenated results - */ + * Applies the supplied function to each element and returns a new Chain from the concatenated results + */ final def flatMap[B](f: A => Chain[B]): Chain[B] = { var result = empty[B] val iter = iterator @@ -109,8 +108,8 @@ sealed abstract class Chain[+A] { } /** - * Folds over the elements from left to right using the supplied initial value and function. - */ + * Folds over the elements from left to right using the supplied initial value and function. + */ final def foldLeft[B](z: B)(f: (B, A) => B): B = { var result = z val iter = iterator @@ -119,8 +118,8 @@ sealed abstract class Chain[+A] { } /** - * Folds over the elements from right to left using the supplied initial value and function. - */ + * Folds over the elements from right to left using the supplied initial value and function. + */ final def foldRight[B](z: B)(f: (A, B) => B): B = { var result = z val iter = reverseIterator @@ -129,8 +128,8 @@ sealed abstract class Chain[+A] { } /** - * Collect `B` from this for which `f` is defined - */ + * Collect `B` from this for which `f` is defined + */ final def collect[B](pf: PartialFunction[A, B]): Chain[B] = foldLeft(Chain.nil: Chain[B]) { (acc, a) => // trick from TraversableOnce, used to avoid calling both isDefined and apply (or calling lift) @@ -140,20 +139,20 @@ sealed abstract class Chain[+A] { } /** - * Remove elements not matching the predicate - */ + * Remove elements not matching the predicate + */ final def filter(f: A => Boolean): Chain[A] = collect { case a if f(a) => a } /** - * Remove elements matching the predicate - */ + * Remove elements matching the predicate + */ final def filterNot(f: A => Boolean): Chain[A] = filter(a => !f(a)) /** - * Find the first element matching the predicate, if one exists - */ + * Find the first element matching the predicate, if one exists + */ final def find(f: A => Boolean): Option[A] = { var result: Option[A] = Option.empty[A] foreachUntil { a => @@ -165,8 +164,8 @@ sealed abstract class Chain[+A] { } /** - * Check whether at least one element satisfies the predicate - */ + * Check whether at least one element satisfies the predicate + */ final def exists(f: A => Boolean): Boolean = { var result: Boolean = false foreachUntil { a => @@ -178,8 +177,8 @@ sealed abstract class Chain[+A] { } /** - * Check whether all elements satisfy the predicate - */ + * Check whether all elements satisfy the predicate + */ final def forall(f: A => Boolean): Boolean = { var result: Boolean = true foreachUntil { a => @@ -191,14 +190,14 @@ sealed abstract class Chain[+A] { } /** - * Check whether an element is in this structure - */ + * Check whether an element is in this structure + */ final def contains[AA >: A](a: AA)(implicit A: Eq[AA]): Boolean = exists(A.eqv(a, _)) /** - * Zips this `Chain` with another `Chain` and applies a function for each pair of elements. - */ + * Zips this `Chain` with another `Chain` and applies a function for each pair of elements. + */ final def zipWith[B, C](other: Chain[B])(f: (A, B) => C): Chain[C] = if (this.isEmpty || other.isEmpty) Chain.Empty else { @@ -214,9 +213,9 @@ sealed abstract class Chain[+A] { } /** - * Groups elements inside this `Chain` according to the `Order` - * of the keys produced by the given mapping function. - */ + * Groups elements inside this `Chain` according to the `Order` + * of the keys produced by the given mapping function. + */ final def groupBy[B](f: A => B)(implicit B: Order[B]): SortedMap[B, NonEmptyChain[A]] = { implicit val ordering: Ordering[B] = B.toOrdering var m = SortedMap.empty[B, NonEmptyChain[A]] @@ -227,7 +226,7 @@ sealed abstract class Chain[+A] { val k = f(elem) m.get(k) match { - case None => m += ((k, NonEmptyChain.one(elem))); () + case None => m += ((k, NonEmptyChain.one(elem))); () case Some(cat) => m = m.updated(k, cat :+ elem) } } @@ -235,17 +234,16 @@ sealed abstract class Chain[+A] { } /** - * Reverses this `Chain` - */ + * Reverses this `Chain` + */ def reverse: Chain[A] = fromSeq(reverseIterator.toVector) - /** - * Yields to Some(a, Chain[A]) with `a` removed where `f` holds for the first time, - * otherwise yields None, if `a` was not found - * Traverses only until `a` is found. - */ + * Yields to Some(a, Chain[A]) with `a` removed where `f` holds for the first time, + * otherwise yields None, if `a` was not found + * Traverses only until `a` is found. + */ final def deleteFirst(f: A => Boolean): Option[(A, Chain[A])] = { @tailrec def go(rem: Chain[A], acc: Chain[A]): Option[(A, Chain[A])] = @@ -260,15 +258,17 @@ sealed abstract class Chain[+A] { } /** - * Applies the supplied function to each element, left to right. - */ - private final def foreach(f: A => Unit): Unit = foreachUntil { a => f(a); false } + * Applies the supplied function to each element, left to right. + */ + final private def foreach(f: A => Unit): Unit = foreachUntil { a => + f(a); false + } /** - * Applies the supplied function to each element, left to right, but stops when true is returned - */ + * Applies the supplied function to each element, left to right, but stops when true is returned + */ // scalastyle:off null return cyclomatic.complexity - private final def foreachUntil(f: A => Boolean): Unit = { + final private def foreachUntil(f: A => Boolean): Unit = { var c: Chain[A] = this val rights = new collection.mutable.ArrayBuffer[Chain[A]] @@ -300,53 +300,51 @@ sealed abstract class Chain[+A] { } // scalastyle:on null return cyclomatic.complexity - final def iterator: Iterator[A] = this match { case Wrap(seq) => seq.iterator - case _ => new ChainIterator[A](this) + case _ => new ChainIterator[A](this) } final def reverseIterator: Iterator[A] = this match { case Wrap(seq) => seq.reverseIterator - case _ => new ChainReverseIterator[A](this) + case _ => new ChainReverseIterator[A](this) } /** - * Returns the number of elements in this structure - */ + * Returns the number of elements in this structure + */ final def length: Long = { val iter = iterator var i: Long = 0 - while(iter.hasNext) { i += 1; iter.next; } + while (iter.hasNext) { i += 1; iter.next; } i } /** - * Alias for length - */ + * Alias for length + */ final def size: Long = length - /** - * Converts to a list. - */ + * Converts to a list. + */ final def toList: List[A] = iterator.toList /** - * Converts to a vector. - */ + * Converts to a vector. + */ final def toVector: Vector[A] = iterator.toVector /** - * Typesafe equality operator. - * - * This method is similar to == except that it only allows two - * Chain[A] values to be compared to each other, and uses - * equality provided by Eq[_] instances, rather than using the - * universal equality provided by .equals. - */ + * Typesafe equality operator. + * + * This method is similar to == except that it only allows two + * Chain[A] values to be compared to each other, and uses + * equality provided by Eq[_] instances, rather than using the + * universal equality provided by .equals. + */ def ===[AA >: A](that: Chain[AA])(implicit A: Eq[AA]): Boolean = (this eq that) || { val iterX = iterator @@ -365,8 +363,7 @@ sealed abstract class Chain[+A] { var first = true foreach { a => - if (first) { builder ++= AA.show(a); first = false } - else builder ++= ", " + AA.show(a) + if (first) { builder ++= AA.show(a); first = false } else builder ++= ", " + AA.show(a) () } builder += ')' @@ -378,20 +375,19 @@ sealed abstract class Chain[+A] { object Chain extends ChainInstances { - private val sentinel: Function1[Any, Any] = new scala.runtime.AbstractFunction1[Any, Any]{ def apply(a: Any) = this } + private val sentinel: Function1[Any, Any] = new scala.runtime.AbstractFunction1[Any, Any] { def apply(a: Any) = this } - private[data] final case object Empty extends Chain[Nothing] { + final private[data] case object Empty extends Chain[Nothing] { def isEmpty: Boolean = true } - private[data] final case class Singleton[A](a: A) extends Chain[A] { + final private[data] case class Singleton[A](a: A) extends Chain[A] { def isEmpty: Boolean = false } - private[data] final case class Append[A](left: Chain[A], right: Chain[A]) - extends Chain[A] { + final private[data] case class Append[A](left: Chain[A], right: Chain[A]) extends Chain[A] { def isEmpty: Boolean = false // b/c `concat` constructor doesn't allow either branch to be empty } - private[data] final case class Wrap[A](seq: Seq[A]) extends Chain[A] { + final private[data] case class Wrap[A](seq: Seq[A]) extends Chain[A] { override def isEmpty: Boolean = false // b/c `fromSeq` constructor doesn't allow either branch to be empty } @@ -463,7 +459,6 @@ object Chain extends ChainInstances { } // scalastyle:on null - // scalastyle:off null private class ChainReverseIterator[A](self: Chain[A]) extends Iterator[A] { private[this] var c: Chain[A] = if (self.isEmpty) null else self @@ -508,14 +503,14 @@ object Chain extends ChainInstances { // scalastyle:on null } -private[data] sealed abstract class ChainInstances extends ChainInstances1 { +sealed abstract private[data] class ChainInstances extends ChainInstances1 { implicit def catsDataMonoidForChain[A]: Monoid[Chain[A]] = new Monoid[Chain[A]] { def empty: Chain[A] = Chain.nil def combine(c: Chain[A], c2: Chain[A]): Chain[A] = Chain.concat(c, c2) } - implicit val catsDataInstancesForChain: Traverse[Chain] with Alternative[Chain] - with Monad[Chain] with CoflatMap[Chain] = + implicit val catsDataInstancesForChain + : Traverse[Chain] with Alternative[Chain] with Monad[Chain] with CoflatMap[Chain] = new Traverse[Chain] with Alternative[Chain] with Monad[Chain] with CoflatMap[Chain] { def foldLeft[A, B](fa: Chain[A], b: B)(f: (B, A) => B): B = fa.foldLeft(b)(f) @@ -536,7 +531,7 @@ private[data] sealed abstract class ChainInstances extends ChainInstances1 { @tailrec def go(as: Chain[A], res: ListBuffer[B]): Chain[B] = as.uncons match { case Some((_, t)) => go(t, res += f(as)) - case None => Chain.fromSeq(res.result()) + case None => Chain.fromSeq(res.result()) } go(fa, ListBuffer.empty) @@ -581,20 +576,22 @@ private[data] sealed abstract class ChainInstances extends ChainInstances1 { implicit def catsDataOrderForChain[A](implicit A0: Order[A]): Order[Chain[A]] = new Order[Chain[A]] with ChainPartialOrder[A] { implicit def A: PartialOrder[A] = A0 - def compare(x: Chain[A], y: Chain[A]): Int = if (x eq y) 0 else { - val iterX = x.iterator - val iterY = y.iterator - while (iterX.hasNext && iterY.hasNext) { - val n = A0.compare(iterX.next, iterY.next) - // scalastyle:off return - if (n != 0) return n - // scalastyle:on return - } + def compare(x: Chain[A], y: Chain[A]): Int = + if (x eq y) 0 + else { + val iterX = x.iterator + val iterY = y.iterator + while (iterX.hasNext && iterY.hasNext) { + val n = A0.compare(iterX.next, iterY.next) + // scalastyle:off return + if (n != 0) return n + // scalastyle:on return + } - if (iterX.hasNext) 1 - else if (iterY.hasNext) -1 - else 0 - } + if (iterX.hasNext) 1 + else if (iterY.hasNext) -1 + else 0 + } } implicit val catsDataTraverseFilterForChain: TraverseFilter[Chain] = new TraverseFilter[Chain] { @@ -614,20 +611,18 @@ private[data] sealed abstract class ChainInstances extends ChainInstances1 { ) override def filterA[G[_], A](fa: Chain[A])(f: A => G[Boolean])(implicit G: Applicative[G]): G[Chain[A]] = - fa.foldRight(G.pure(Chain.empty[A]))( - (a, gca) => - G.map2(f(a), gca)((b, chain) => if (b) a +: chain else chain)) + fa.foldRight(G.pure(Chain.empty[A]))((a, gca) => G.map2(f(a), gca)((b, chain) => if (b) a +: chain else chain)) } } -private[data] sealed abstract class ChainInstances1 extends ChainInstances2 { +sealed abstract private[data] class ChainInstances1 extends ChainInstances2 { implicit def catsDataPartialOrderForChain[A](implicit A0: PartialOrder[A]): PartialOrder[Chain[A]] = new ChainPartialOrder[A] { implicit def A: PartialOrder[A] = A0 } } -private[data] sealed abstract class ChainInstances2 { +sealed abstract private[data] class ChainInstances2 { implicit def catsDataEqForChain[A](implicit A: Eq[A]): Eq[Chain[A]] = new Eq[Chain[A]] { def eqv(x: Chain[A], y: Chain[A]): Boolean = x === y } @@ -636,20 +631,22 @@ private[data] sealed abstract class ChainInstances2 { private[data] trait ChainPartialOrder[A] extends PartialOrder[Chain[A]] { implicit def A: PartialOrder[A] - override def partialCompare(x: Chain[A], y: Chain[A]): Double = if (x eq y) 0.0 else { - val iterX = x.iterator - val iterY = y.iterator - while (iterX.hasNext && iterY.hasNext) { - val n = A.partialCompare(iterX.next, iterY.next) - // scalastyle:off return - if (n != 0.0) return n - // scalastyle:on return - } + override def partialCompare(x: Chain[A], y: Chain[A]): Double = + if (x eq y) 0.0 + else { + val iterX = x.iterator + val iterY = y.iterator + while (iterX.hasNext && iterY.hasNext) { + val n = A.partialCompare(iterX.next, iterY.next) + // scalastyle:off return + if (n != 0.0) return n + // scalastyle:on return + } - if (iterX.hasNext) 1.0 - else if (iterY.hasNext) -1.0 - else 0.0 - } + if (iterX.hasNext) 1.0 + else if (iterY.hasNext) -1.0 + else 0.0 + } override def eqv(x: Chain[A], y: Chain[A]): Boolean = x === y } diff --git a/core/src/main/scala/cats/data/Cokleisli.scala b/core/src/main/scala/cats/data/Cokleisli.scala index 6f64e9b8d6b..163c730875c 100644 --- a/core/src/main/scala/cats/data/Cokleisli.scala +++ b/core/src/main/scala/cats/data/Cokleisli.scala @@ -7,8 +7,8 @@ import cats.{CoflatMap, Comonad, Contravariant, Functor, Monad} import scala.annotation.tailrec /** - * Represents a function `F[A] => B`. - */ + * Represents a function `F[A] => B`. + */ final case class Cokleisli[F[_], A, B](run: F[A] => B) { self => /** @@ -40,7 +40,7 @@ final case class Cokleisli[F[_], A, B](run: F[A] => B) { self => Cokleisli(fc => run(F.map(fc)(f))) def map[C](f: B => C): Cokleisli[F, A, C] = - Cokleisli(f compose run) + Cokleisli(f.compose(run)) /** * Example: @@ -53,7 +53,7 @@ final case class Cokleisli[F[_], A, B](run: F[A] => B) { self => * }}} */ def contramapValue[C](f: F[C] => F[A]): Cokleisli[F, C, B] = - Cokleisli(run compose f) + Cokleisli(run.compose(f)) def flatMap[C](f: B => Cokleisli[F, A, C]): Cokleisli[F, A, C] = Cokleisli(fa => f(self.run(fa)).run(fa)) @@ -62,7 +62,7 @@ final case class Cokleisli[F[_], A, B](run: F[A] => B) { self => Cokleisli(fc => run(F.coflatMap(fc)(c.run))) def andThen[C](c: Cokleisli[F, B, C])(implicit F: CoflatMap[F]): Cokleisli[F, A, C] = - c compose this + c.compose(this) def first[C](implicit F: Comonad[F]): Cokleisli[F, (A, C), (B, C)] = Cokleisli(fac => run(F.map(fac)(_._1)) -> F.extract(F.map(fac)(_._2))) @@ -76,12 +76,12 @@ object Cokleisli extends CokleisliInstances { Cokleisli(_ => x) } -private[data] sealed abstract class CokleisliInstances extends CokleisliInstances0 { +sealed abstract private[data] class CokleisliInstances extends CokleisliInstances0 { implicit val catsDataCommutativeArrowForCokleisliId: CommutativeArrow[Cokleisli[Id, ?, ?]] = new CokleisliArrow[Id] with CommutativeArrow[Cokleisli[Id, ?, ?]] { def F: Comonad[Id] = Comonad[Id] - } + } implicit def catsDataMonadForCokleisli[F[_], A]: Monad[Cokleisli[F, A, ?]] = new CokleisliMonad[F, A] @@ -90,12 +90,12 @@ private[data] sealed abstract class CokleisliInstances extends CokleisliInstance Category[Cokleisli[F, ?, ?]].algebraK } -private[data] sealed abstract class CokleisliInstances0 extends CokleisliInstances1 { +sealed abstract private[data] class CokleisliInstances0 extends CokleisliInstances1 { implicit def catsDataArrowForCokleisli[F[_]](implicit ev: Comonad[F]): Arrow[Cokleisli[F, ?, ?]] = new CokleisliArrow[F] { def F: Comonad[F] = ev } } -private[data] sealed abstract class CokleisliInstances1 { +sealed abstract private[data] class CokleisliInstances1 { implicit def catsDataComposeForCokleisli[F[_]](implicit ev: CoflatMap[F]): Compose[Cokleisli[F, ?, ?]] = new CokleisliCompose[F] { def F: CoflatMap[F] = ev } @@ -111,8 +111,6 @@ private[data] sealed abstract class CokleisliInstances1 { } } - - private[data] class CokleisliMonad[F[_], A] extends Monad[Cokleisli[F, A, ?]] { def pure[B](x: B): Cokleisli[F, A, B] = @@ -136,7 +134,10 @@ private[data] class CokleisliMonad[F[_], A] extends Monad[Cokleisli[F, A, ?]] { } -private trait CokleisliArrow[F[_]] extends Arrow[Cokleisli[F, ?, ?]] with CokleisliCompose[F] with CokleisliProfunctor[F] { +private trait CokleisliArrow[F[_]] + extends Arrow[Cokleisli[F, ?, ?]] + with CokleisliCompose[F] + with CokleisliProfunctor[F] { implicit def F: Comonad[F] def lift[A, B](f: A => B): Cokleisli[F, A, B] = diff --git a/core/src/main/scala/cats/data/Const.scala b/core/src/main/scala/cats/data/Const.scala index 61e513027a9..ae61a3c3875 100644 --- a/core/src/main/scala/cats/data/Const.scala +++ b/core/src/main/scala/cats/data/Const.scala @@ -5,13 +5,14 @@ import cats.Contravariant import cats.kernel.{CommutativeMonoid, CommutativeSemigroup} /** - * [[Const]] is a phantom type, it does not contain a value of its second type parameter `B` - * [[Const]] can be seen as a type level version of `Function.const[A, B]: A => B => A` - */ + * [[Const]] is a phantom type, it does not contain a value of its second type parameter `B` + * [[Const]] can be seen as a type level version of `Function.const[A, B]: A => B => A` + */ final case class Const[A, B](getConst: A) { + /** - * changes the type of the second type parameter - */ + * changes the type of the second type parameter + */ def retag[C]: Const[A, C] = this.asInstanceOf[Const[A, C]] @@ -39,27 +40,27 @@ object Const extends ConstInstances { Const(A.empty) /** - * Uses the [[http://typelevel.org/cats/guidelines.html#partially-applied-type-params Partially Applied Type Params technique]] for ergonomics. - */ - private[data] final class OfPartiallyApplied[B](val dummy: Boolean = true ) extends AnyVal { + * Uses the [[http://typelevel.org/cats/guidelines.html#partially-applied-type-params Partially Applied Type Params technique]] for ergonomics. + */ + final private[data] class OfPartiallyApplied[B](val dummy: Boolean = true) extends AnyVal { def apply[A](a: A): Const[A, B] = Const(a) } /** - * Convenient syntax for creating a Const[A, B] from an `A` - * {{{ - * scala> import cats.data._ - * scala> Const.of[Int]("a") - * res0: Const[String, Int] = Const(a) - * }}} - */ + * Convenient syntax for creating a Const[A, B] from an `A` + * {{{ + * scala> import cats.data._ + * scala> Const.of[Int]("a") + * res0: Const[String, Int] = Const(a) + * }}} + */ def of[B]: OfPartiallyApplied[B] = new OfPartiallyApplied } -private[data] sealed abstract class ConstInstances extends ConstInstances0 { +sealed abstract private[data] class ConstInstances extends ConstInstances0 { 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 + x.compare(y) } implicit def catsDataShowForConst[A: Show, B]: Show[Const[A, B]] = new Show[Const[A, B]] { @@ -89,7 +90,9 @@ private[data] sealed abstract class ConstInstances extends ConstInstances0 { override def filter[A](fa: Const[C, A])(f: (A) => Boolean): Const[C, A] = fa.retag - def traverseFilter[G[_], A, B](fa: Const[C, A])(f: (A) => G[Option[B]])(implicit G: Applicative[G]): G[Const[C, B]] = + def traverseFilter[G[_], A, B]( + fa: Const[C, A] + )(f: (A) => G[Option[B]])(implicit G: Applicative[G]): G[Const[C, B]] = G.pure(fa.retag[B]) override def filterA[G[_], A](fa: Const[C, A])(f: (A) => G[Boolean])(implicit G: Applicative[G]): G[Const[C, A]] = @@ -98,12 +101,12 @@ private[data] sealed abstract class ConstInstances extends ConstInstances0 { val traverse: Traverse[Const[C, ?]] = Const.catsDataTraverseForConst[C] } - implicit def catsDataMonoidForConst[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 def combine(x: Const[A, B], y: Const[A, B]): Const[A, B] = - x combine y + x.combine(y) } implicit val catsDataBifoldableForConst: Bifoldable[Const] = @@ -111,12 +114,13 @@ private[data] sealed abstract class ConstInstances extends ConstInstances0 { def bifoldLeft[A, B, C](fab: Const[A, B], c: C)(f: (C, A) => C, g: (C, B) => C): C = f(c, fab.getConst) - def bifoldRight[A, B, C](fab: Const[A, B], c: Eval[C])(f: (A, Eval[C]) => Eval[C], g: (B, Eval[C]) => Eval[C]): Eval[C] = + def bifoldRight[A, B, C](fab: Const[A, B], c: Eval[C])(f: (A, Eval[C]) => Eval[C], + g: (B, Eval[C]) => Eval[C]): Eval[C] = f(fab.getConst, c) } } -private[data] sealed abstract class ConstInstances0 extends ConstInstances1 { +sealed abstract private[data] class ConstInstances0 extends ConstInstances1 { implicit def catsDataContravariantMonoidalForConst[D: Monoid]: ContravariantMonoidal[Const[D, ?]] = new ContravariantMonoidal[Const[D, ?]] { @@ -124,35 +128,38 @@ private[data] sealed abstract class ConstInstances0 extends ConstInstances1 { override def contramap[A, B](fa: Const[D, A])(f: B => A): Const[D, B] = fa.retag[B] override def product[A, B](fa: Const[D, A], fb: Const[D, B]): Const[D, (A, B)] = - fa.retag[(A, B)] combine fb.retag[(A, B)] + fa.retag[(A, B)].combine(fb.retag[(A, B)]) } - implicit def catsDataCommutativeApplicativeForConst[C](implicit C: CommutativeMonoid[C]): CommutativeApplicative[Const[C, ?]] = + implicit def catsDataCommutativeApplicativeForConst[C]( + implicit C: CommutativeMonoid[C] + ): CommutativeApplicative[Const[C, ?]] = new ConstApplicative[C] with CommutativeApplicative[Const[C, ?]] { val C0: CommutativeMonoid[C] = C } } -private[data] sealed abstract class ConstInstances1 extends ConstInstances2 { +sealed abstract private[data] class ConstInstances1 extends ConstInstances2 { implicit def catsDataCommutativeApplyForConst[C](implicit C: CommutativeSemigroup[C]): CommutativeApply[Const[C, ?]] = new ConstApply[C] with CommutativeApply[Const[C, ?]] { val C0: CommutativeSemigroup[C] = C } } -private[data] sealed abstract class ConstInstances2 extends ConstInstances3 { +sealed abstract private[data] class ConstInstances2 extends ConstInstances3 { 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 + def combine(x: Const[A, B], y: Const[A, B]): Const[A, B] = x.combine(y) } - 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 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 catsDataApplicativeForConst[C](implicit C: Monoid[C]): Applicative[Const[C, ?]] = new ConstApplicative[C] { val C0: Monoid[C] = C } } -private[data] sealed abstract class ConstInstances3 extends ConstInstances4 { +sealed abstract private[data] class ConstInstances3 extends ConstInstances4 { 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 = @@ -163,37 +170,37 @@ private[data] sealed abstract class ConstInstances3 extends ConstInstances4 { new ConstApply[C] { val C0: Semigroup[C] = C } } -private[data] sealed abstract class ConstInstances4 { +sealed abstract private[data] class ConstInstances4 { implicit def catsDataFunctorForConst[C]: Functor[Const[C, ?]] = - new ConstFunctor[C]{} + new ConstFunctor[C] {} implicit def catsDataContravariantForConst[C]: Contravariant[Const[C, ?]] = new ConstContravariant[C] {} } -private[data] sealed trait ConstFunctor[C] extends Functor[Const[C, ?]] { +sealed private[data] trait ConstFunctor[C] extends Functor[Const[C, ?]] { def map[A, B](fa: Const[C, A])(f: A => B): Const[C, B] = fa.retag[B] } -private[data] sealed trait ConstContravariant[C] extends Contravariant[Const[C, ?]] { +sealed private[data] trait ConstContravariant[C] extends Contravariant[Const[C, ?]] { override def contramap[A, B](fa: Const[C, A])(f: B => A): Const[C, B] = fa.retag[B] } -private[data] sealed trait ConstApply[C] extends ConstFunctor[C] with Apply[Const[C, ?]] { +sealed private[data] trait ConstApply[C] extends ConstFunctor[C] with Apply[Const[C, ?]] { implicit def C0: Semigroup[C] def ap[A, B](f: Const[C, A => B])(fa: Const[C, A]): Const[C, B] = - f.retag[B] combine fa.retag[B] + f.retag[B].combine(fa.retag[B]) override def product[A, B](fa: Const[C, A], fb: Const[C, B]): Const[C, (A, B)] = - fa.retag[(A, B)] combine fb.retag[(A, B)] + fa.retag[(A, B)].combine(fb.retag[(A, B)]) } -private[data] sealed trait ConstApplicative[C] extends ConstApply[C] with Applicative[Const[C, ?]] { +sealed private[data] trait ConstApplicative[C] extends ConstApply[C] with Applicative[Const[C, ?]] { implicit def C0: Monoid[C] diff --git a/core/src/main/scala/cats/data/EitherK.scala b/core/src/main/scala/cats/data/EitherK.scala index 6872e876046..52e15fcb356 100644 --- a/core/src/main/scala/cats/data/EitherK.scala +++ b/core/src/main/scala/cats/data/EitherK.scala @@ -6,9 +6,9 @@ import cats.arrow.FunctionK import cats.syntax.either._ /** `F` on the left and `G` on the right of `scala.util.Either`. - * - * @param run The underlying `scala.util.Either`. - */ + * + * @param run The underlying `scala.util.Either`. + */ final case class EitherK[F[_], G[_], A](run: Either[F[A], G[A]]) { import EitherK._ @@ -17,8 +17,8 @@ final case class EitherK[F[_], G[_], A](run: Either[F[A], G[A]]) { EitherK(run.bimap(F.lift(f), G.lift(f))) /** - * Modify the right side context `G` using transformation `f`. - */ + * Modify the right side context `G` using transformation `f`. + */ def mapK[H[_]](f: G ~> H): EitherK[F, H, A] = EitherK(run.map(f.apply)) @@ -28,10 +28,7 @@ final case class EitherK[F[_], G[_], A](run: Either[F[A], G[A]]) { ) def coflatten(implicit F: CoflatMap[F], G: CoflatMap[G]): EitherK[F, G, EitherK[F, G, A]] = - EitherK(run.bimap( - x => F.coflatMap(x)(a => leftc(a)) - , x => G.coflatMap(x)(a => rightc(a))) - ) + EitherK(run.bimap(x => F.coflatMap(x)(a => leftc(a)), x => G.coflatMap(x)(a => rightc(a)))) def extract(implicit F: Comonad[F], G: Comonad[G]): A = run.fold(F.extract, G.extract) @@ -50,8 +47,8 @@ final case class EitherK[F[_], G[_], A](run: Either[F[A], G[A]]) { def traverse[X[_], B](g: A => X[B])(implicit F: Traverse[F], G: Traverse[G], A: Applicative[X]): X[EitherK[F, G, B]] = run.fold( - x => A.map(F.traverse(x)(g))(leftc(_)) - , x => A.map(G.traverse(x)(g))(rightc(_)) + x => A.map(F.traverse(x)(g))(leftc(_)), + x => A.map(G.traverse(x)(g))(rightc(_)) ) def isLeft: Boolean = @@ -67,22 +64,22 @@ final case class EitherK[F[_], G[_], A](run: Either[F[A], G[A]]) { run.toValidated /** - * Fold this eitherK into a new type constructor using two natural transformations. - * - * Example: - * {{{ - * scala> import cats.arrow.FunctionK - * scala> import cats.data.EitherK - * scala> val listToOption = λ[FunctionK[List, Option]](_.headOption) - * scala> val optionToOption = FunctionK.id[Option] - * scala> val cp1: EitherK[List, Option, Int] = EitherK.leftc(List(1,2,3)) - * scala> val cp2: EitherK[List, Option, Int] = EitherK.rightc(Some(4)) - * scala> cp1.fold(listToOption, optionToOption) - * res0: Option[Int] = Some(1) - * scala> cp2.fold(listToOption, optionToOption) - * res1: Option[Int] = Some(4) - * }}} - */ + * Fold this eitherK into a new type constructor using two natural transformations. + * + * Example: + * {{{ + * scala> import cats.arrow.FunctionK + * scala> import cats.data.EitherK + * scala> val listToOption = λ[FunctionK[List, Option]](_.headOption) + * scala> val optionToOption = FunctionK.id[Option] + * scala> val cp1: EitherK[List, Option, Int] = EitherK.leftc(List(1,2,3)) + * scala> val cp2: EitherK[List, Option, Int] = EitherK.rightc(Some(4)) + * scala> cp1.fold(listToOption, optionToOption) + * res0: Option[Int] = Some(1) + * scala> cp2.fold(listToOption, optionToOption) + * res1: Option[Int] = Some(4) + * }}} + */ def fold[H[_]](f: FunctionK[F, H], g: FunctionK[G, H]): H[A] = run.fold(f.apply, g.apply) } @@ -108,19 +105,21 @@ object EitherK extends EitherKInstances { def right[F[_]]: EitherKRight[F] = new EitherKRight[F] } -private[data] sealed abstract class EitherKInstances3 { +sealed abstract private[data] class EitherKInstances3 { implicit def catsDataEqForEitherK[F[_], G[_], A](implicit E: Eq[Either[F[A], G[A]]]): Eq[EitherK[F, G, A]] = Eq.by(_.run) - implicit def catsDataFunctorForEitherK[F[_], G[_]](implicit F0: Functor[F], G0: Functor[G]): Functor[EitherK[F, G, ?]] = + implicit def catsDataFunctorForEitherK[F[_], G[_]](implicit F0: Functor[F], + G0: Functor[G]): Functor[EitherK[F, G, ?]] = new EitherKFunctor[F, G] { implicit def F: Functor[F] = F0 implicit def G: Functor[G] = G0 } - implicit def catsDataFoldableForEitherK[F[_], G[_]](implicit F0: Foldable[F], G0: Foldable[G]): Foldable[EitherK[F, G, ?]] = + implicit def catsDataFoldableForEitherK[F[_], G[_]](implicit F0: Foldable[F], + G0: Foldable[G]): Foldable[EitherK[F, G, ?]] = new EitherKFoldable[F, G] { implicit def F: Foldable[F] = F0 @@ -128,9 +127,10 @@ private[data] sealed abstract class EitherKInstances3 { } } -private[data] sealed abstract class EitherKInstances2 extends EitherKInstances3 { +sealed abstract private[data] class EitherKInstances2 extends EitherKInstances3 { - implicit def catsDataContravariantForEitherK[F[_], G[_]](implicit F0: Contravariant[F], G0: Contravariant[G]): Contravariant[EitherK[F, G, ?]] = + implicit def catsDataContravariantForEitherK[F[_], G[_]](implicit F0: Contravariant[F], + G0: Contravariant[G]): Contravariant[EitherK[F, G, ?]] = new EitherKContravariant[F, G] { implicit def F: Contravariant[F] = F0 @@ -138,8 +138,9 @@ private[data] sealed abstract class EitherKInstances2 extends EitherKInstances3 } } -private[data] sealed abstract class EitherKInstances1 extends EitherKInstances2 { - implicit def catsDataCoflatMapForEitherK[F[_], G[_]](implicit F0: CoflatMap[F], G0: CoflatMap[G]): CoflatMap[EitherK[F, G, ?]] = +sealed abstract private[data] class EitherKInstances1 extends EitherKInstances2 { + implicit def catsDataCoflatMapForEitherK[F[_], G[_]](implicit F0: CoflatMap[F], + G0: CoflatMap[G]): CoflatMap[EitherK[F, G, ?]] = new EitherKCoflatMap[F, G] with EitherKFunctor[F, G] { implicit def F: CoflatMap[F] = F0 @@ -147,8 +148,9 @@ private[data] sealed abstract class EitherKInstances1 extends EitherKInstances2 } } -private[data] sealed abstract class EitherKInstances0 extends EitherKInstances1 { - implicit def catsDataTraverseForEitherK[F[_], G[_]](implicit F0: Traverse[F], G0: Traverse[G]): Traverse[EitherK[F, G, ?]] = +sealed abstract private[data] class EitherKInstances0 extends EitherKInstances1 { + implicit def catsDataTraverseForEitherK[F[_], G[_]](implicit F0: Traverse[F], + G0: Traverse[G]): Traverse[EitherK[F, G, ?]] = new EitherKTraverse[F, G] with EitherKFunctor[F, G] { implicit def F: Traverse[F] = F0 @@ -156,9 +158,10 @@ private[data] sealed abstract class EitherKInstances0 extends EitherKInstances1 } } -private[data] sealed abstract class EitherKInstances extends EitherKInstances0 { +sealed abstract private[data] class EitherKInstances extends EitherKInstances0 { - implicit def catsDataComonadForEitherK[F[_], G[_]](implicit F0: Comonad[F], G0: Comonad[G]): Comonad[EitherK[F, G, ?]] = + implicit def catsDataComonadForEitherK[F[_], G[_]](implicit F0: Comonad[F], + G0: Comonad[G]): Comonad[EitherK[F, G, ?]] = new EitherKComonad[F, G] with EitherKFunctor[F, G] { implicit def F: Comonad[F] = F0 @@ -172,7 +175,7 @@ private[data] trait EitherKFunctor[F[_], G[_]] extends Functor[EitherK[F, G, ?]] implicit def G: Functor[G] override def map[A, B](a: EitherK[F, G, A])(f: A => B): EitherK[F, G, B] = - a map f + a.map(f) } private[data] trait EitherKContravariant[F[_], G[_]] extends Contravariant[EitherK[F, G, ?]] { @@ -181,7 +184,7 @@ private[data] trait EitherKContravariant[F[_], G[_]] extends Contravariant[Eithe implicit def G: Contravariant[G] def contramap[A, B](a: EitherK[F, G, A])(f: B => A): EitherK[F, G, B] = - a contramap f + a.contramap(f) } private[data] trait EitherKFoldable[F[_], G[_]] extends Foldable[EitherK[F, G, ?]] { @@ -202,7 +205,7 @@ private[data] trait EitherKFoldable[F[_], G[_]] extends Foldable[EitherK[F, G, ? fa.run.fold(F.get(_)(idx), G.get(_)(idx)) override def foldMap[A, B](fa: EitherK[F, G, A])(f: A => B)(implicit M: Monoid[B]): B = - fa foldMap f + fa.foldMap(f) } private[data] trait EitherKTraverse[F[_], G[_]] extends EitherKFoldable[F, G] with Traverse[EitherK[F, G, ?]] { @@ -211,10 +214,10 @@ private[data] trait EitherKTraverse[F[_], G[_]] extends EitherKFoldable[F, G] wi implicit def G: Traverse[G] override def map[A, B](a: EitherK[F, G, A])(f: A => B): EitherK[F, G, B] = - a map f + a.map(f) - override def traverse[X[_] : Applicative, A, B](fa: EitherK[F, G, A])(f: A => X[B]): X[EitherK[F, G, B]] = - fa traverse f + override def traverse[X[_]: Applicative, A, B](fa: EitherK[F, G, A])(f: A => X[B]): X[EitherK[F, G, B]] = + fa.traverse(f) } private[data] trait EitherKCoflatMap[F[_], G[_]] extends CoflatMap[EitherK[F, G, ?]] { @@ -223,10 +226,10 @@ private[data] trait EitherKCoflatMap[F[_], G[_]] extends CoflatMap[EitherK[F, G, implicit def G: CoflatMap[G] def map[A, B](a: EitherK[F, G, A])(f: A => B): EitherK[F, G, B] = - a map f + a.map(f) def coflatMap[A, B](a: EitherK[F, G, A])(f: EitherK[F, G, A] => B): EitherK[F, G, B] = - a coflatMap f + a.coflatMap(f) override def coflatten[A](fa: EitherK[F, G, A]): EitherK[F, G, EitherK[F, G, A]] = fa.coflatten diff --git a/core/src/main/scala/cats/data/EitherT.scala b/core/src/main/scala/cats/data/EitherT.scala index 7dc39d170a2..28fd57b5b0e 100644 --- a/core/src/main/scala/cats/data/EitherT.scala +++ b/core/src/main/scala/cats/data/EitherT.scala @@ -6,12 +6,12 @@ import cats.instances.either._ import cats.syntax.either._ /** - * Transformer for `Either`, allowing the effect of an arbitrary type constructor `F` to be combined with the - * fail-fast effect of `Either`. - * - * `EitherT[F, A, B]` wraps a value of type `F[Either[A, B]]`. An `F[C]` can be lifted in to `EitherT[F, A, C]` via `EitherT.right`, - * and lifted in to a `EitherT[F, C, B]` via `EitherT.left`. - */ + * Transformer for `Either`, allowing the effect of an arbitrary type constructor `F` to be combined with the + * fail-fast effect of `Either`. + * + * `EitherT[F, A, B]` wraps a value of type `F[Either[A, B]]`. An `F[C]` can be lifted in to `EitherT[F, A, C]` via `EitherT.right`, + * and lifted in to a `EitherT[F, C, B]` via `EitherT.left`. + */ final case class EitherT[F[_], A, B](value: F[Either[A, B]]) { def fold[C](fa: A => C, fb: B => C)(implicit F: Functor[F]): F[C] = F.map(value)(_.fold(fa, fb)) @@ -23,19 +23,17 @@ final case class EitherT[F[_], A, B](value: F[Either[A, B]]) { def getOrElse[BB >: B](default: => BB)(implicit F: Functor[F]): F[BB] = F.map(value)(_.getOrElse(default)) - def getOrElseF[BB >: B](default: => F[BB])(implicit F: Monad[F]): F[BB] = { + def getOrElseF[BB >: B](default: => F[BB])(implicit F: Monad[F]): F[BB] = F.flatMap(value) { - case Left(_) => default + case Left(_) => default case Right(b) => F.pure(b) } - } - def orElse[AA, BB >: B](default: => EitherT[F, AA, BB])(implicit F: Monad[F]): EitherT[F, AA, BB] = { + def orElse[AA, BB >: B](default: => EitherT[F, AA, BB])(implicit F: Monad[F]): EitherT[F, AA, BB] = EitherT(F.flatMap(value) { - case Left(_) => default.value + case Left(_) => default.value case r @ Right(_) => F.pure(r.leftCast) }) - } def recover(pf: PartialFunction[A, B])(implicit F: Functor[F]): EitherT[F, A, B] = EitherT(F.map(value)(_.recover(pf))) @@ -43,17 +41,16 @@ final case class EitherT[F[_], A, B](value: F[Either[A, B]]) { def recoverWith(pf: PartialFunction[A, EitherT[F, A, B]])(implicit F: Monad[F]): EitherT[F, A, B] = EitherT(F.flatMap(value) { case Left(a) if pf.isDefinedAt(a) => pf(a).value - case other => F.pure(other) + case other => F.pure(other) }) def valueOr[BB >: B](f: A => BB)(implicit F: Functor[F]): F[BB] = fold(f, identity) - def valueOrF[BB >: B](f: A => F[BB])(implicit F: Monad[F]): F[BB] = { - F.flatMap(value){ - case Left(a) => f(a) - case Right(b) => F.pure(b) - } - } + def valueOrF[BB >: B](f: A => F[BB])(implicit F: Monad[F]): F[BB] = + F.flatMap(value) { + case Left(a) => f(a) + case Right(b) => F.pure(b) + } def forall(f: B => Boolean)(implicit F: Functor[F]): F[Boolean] = F.map(value)(_.forall(f)) @@ -73,9 +70,11 @@ final case class EitherT[F[_], A, B](value: F[Either[A, B]]) { def collectRight(implicit FA: Alternative[F], FM: Monad[F]): F[B] = FM.flatMap(value)(_.to[F]) - def bimap[C, D](fa: A => C, fb: B => D)(implicit F: Functor[F]): EitherT[F, C, D] = EitherT(F.map(value)(_.bimap(fa, fb))) + def bimap[C, D](fa: A => C, fb: B => D)(implicit F: Functor[F]): EitherT[F, C, D] = + EitherT(F.map(value)(_.bimap(fa, fb))) - def bitraverse[G[_], C, D](f: A => G[C], g: B => G[D])(implicit traverseF: Traverse[F], applicativeG: Applicative[G]): G[EitherT[F, C, D]] = + def bitraverse[G[_], C, D](f: A => G[C], g: B => G[D])(implicit traverseF: Traverse[F], + applicativeG: Applicative[G]): G[EitherT[F, C, D]] = applicativeG.map(traverseF.traverse(value)(axb => Bitraverse[Either].bitraverse(axb)(f, g)))(EitherT.apply) def applyAlt[D](ff: EitherT[F, A, B => D])(implicit F: Apply[F]): EitherT[F, A, D] = @@ -84,11 +83,11 @@ final case class EitherT[F[_], A, B](value: F[Either[A, B]]) { def flatMap[AA >: A, D](f: B => EitherT[F, AA, D])(implicit F: Monad[F]): EitherT[F, AA, D] = EitherT(F.flatMap(value) { case l @ Left(_) => F.pure(l.rightCast) - case Right(b) => f(b).value + case Right(b) => f(b).value }) def flatMapF[AA >: A, D](f: B => F[Either[AA, D]])(implicit F: Monad[F]): EitherT[F, AA, D] = - flatMap(f andThen EitherT.apply) + flatMap(f.andThen(EitherT.apply)) def transform[C, D](f: Either[A, B] => Either[C, D])(implicit F: Functor[F]): EitherT[F, C, D] = EitherT(F.map(value)(f)) @@ -99,8 +98,8 @@ final case class EitherT[F[_], A, B](value: F[Either[A, B]]) { def map[D](f: B => D)(implicit F: Functor[F]): EitherT[F, A, D] = bimap(identity, f) /** - * Modify the context `F` using transformation `f`. - */ + * Modify the context `F` using transformation `f`. + */ def mapK[G[_]](f: F ~> G): EitherT[G, A, B] = EitherT[G, A, B](f(value)) def semiflatMap[D](f: B => F[D])(implicit F: Monad[F]): EitherT[F, A, D] = @@ -110,14 +109,17 @@ final case class EitherT[F[_], A, B](value: F[Either[A, B]]) { def leftFlatMap[BB >: B, D](f: A => EitherT[F, D, BB])(implicit F: Monad[F]): EitherT[F, D, BB] = EitherT(F.flatMap(value) { - case Left(a) => f(a).value - case r@Right(_) => F.pure(r.leftCast) + case Left(a) => f(a).value + case r @ Right(_) => F.pure(r.leftCast) }) def leftSemiflatMap[D](f: A => F[D])(implicit F: Monad[F]): EitherT[F, D, B] = EitherT(F.flatMap(value) { - case Left(a) => F.map(f(a)) { d => Left(d) } - case r@Right(_) => F.pure(r.leftCast) + case Left(a) => + F.map(f(a)) { d => + Left(d) + } + case r @ Right(_) => F.pure(r.leftCast) }) /** Combine `leftSemiflatMap` and `semiflatMap` together. @@ -134,8 +136,14 @@ final case class EitherT[F[_], A, B](value: F[Either[A, B]]) { */ def biSemiflatMap[C, D](fa: A => F[C], fb: B => F[D])(implicit F: Monad[F]): EitherT[F, C, D] = EitherT(F.flatMap(value) { - case Left(a) => F.map(fa(a)) { c => Left(c) } - case Right(b) => F.map(fb(b)) { d => Right(d) } + case Left(a) => + F.map(fa(a)) { c => + Left(c) + } + case Right(b) => + F.map(fb(b)) { d => + Right(d) + } }) def compare(that: EitherT[F, A, B])(implicit o: Order[F[Either[A, B]]]): Int = @@ -147,7 +155,8 @@ final case class EitherT[F[_], A, B](value: F[Either[A, B]]) { def ===(that: EitherT[F, A, B])(implicit eq: Eq[F[Either[A, B]]]): Boolean = eq.eqv(value, that.value) - def traverse[G[_], D](f: B => G[D])(implicit traverseF: Traverse[F], applicativeG: Applicative[G]): G[EitherT[F, A, D]] = + def traverse[G[_], D](f: B => G[D])(implicit traverseF: Traverse[F], + applicativeG: Applicative[G]): G[EitherT[F, A, D]] = applicativeG.map(traverseF.traverse(value)(axb => Traverse[Either[A, ?]].traverse(axb)(f)))(EitherT.apply) def foldLeft[C](c: C)(f: (C, B) => C)(implicit F: Foldable[F]): C = @@ -159,45 +168,45 @@ final case class EitherT[F[_], A, B](value: F[Either[A, B]]) { def merge[AA >: A](implicit ev: B <:< AA, F: Functor[F]): F[AA] = F.map(value)(_.fold(identity, ev.apply)) /** - * Similar to `Either#combine` but mapped over an `F` context. - * - * Examples: - * {{{ - * scala> import cats.data.EitherT - * scala> import cats.implicits._ - * scala> val l1: EitherT[Option, String, Int] = EitherT.left(Some("error 1")) - * scala> val l2: EitherT[Option, String, Int] = EitherT.left(Some("error 2")) - * scala> val r3: EitherT[Option, String, Int] = EitherT.right(Some(3)) - * scala> val r4: EitherT[Option, String, Int] = EitherT.right(Some(4)) - * scala> val noneEitherT: EitherT[Option, String, Int] = EitherT.left(None) - * - * scala> l1 combine l2 - * res0: EitherT[Option, String, Int] = EitherT(Some(Left(error 1))) - * - * scala> l1 combine r3 - * res1: EitherT[Option, String, Int] = EitherT(Some(Left(error 1))) - * - * scala> r3 combine l1 - * res2: EitherT[Option, String, Int] = EitherT(Some(Left(error 1))) - * - * scala> r3 combine r4 - * res3: EitherT[Option, String, Int] = EitherT(Some(Right(7))) - * - * scala> l1 combine noneEitherT - * res4: EitherT[Option, String, Int] = EitherT(None) - * - * scala> noneEitherT combine l1 - * res5: EitherT[Option, String, Int] = EitherT(None) - * - * scala> r3 combine noneEitherT - * res6: EitherT[Option, String, Int] = EitherT(None) - * - * scala> noneEitherT combine r4 - * res7: EitherT[Option, String, Int] = EitherT(None) - * }}} - */ + * Similar to `Either#combine` but mapped over an `F` context. + * + * Examples: + * {{{ + * scala> import cats.data.EitherT + * scala> import cats.implicits._ + * scala> val l1: EitherT[Option, String, Int] = EitherT.left(Some("error 1")) + * scala> val l2: EitherT[Option, String, Int] = EitherT.left(Some("error 2")) + * scala> val r3: EitherT[Option, String, Int] = EitherT.right(Some(3)) + * scala> val r4: EitherT[Option, String, Int] = EitherT.right(Some(4)) + * scala> val noneEitherT: EitherT[Option, String, Int] = EitherT.left(None) + * + * scala> l1 combine l2 + * res0: EitherT[Option, String, Int] = EitherT(Some(Left(error 1))) + * + * scala> l1 combine r3 + * res1: EitherT[Option, String, Int] = EitherT(Some(Left(error 1))) + * + * scala> r3 combine l1 + * res2: EitherT[Option, String, Int] = EitherT(Some(Left(error 1))) + * + * scala> r3 combine r4 + * res3: EitherT[Option, String, Int] = EitherT(Some(Right(7))) + * + * scala> l1 combine noneEitherT + * res4: EitherT[Option, String, Int] = EitherT(None) + * + * scala> noneEitherT combine l1 + * res5: EitherT[Option, String, Int] = EitherT(None) + * + * scala> r3 combine noneEitherT + * res6: EitherT[Option, String, Int] = EitherT(None) + * + * scala> noneEitherT combine r4 + * res7: EitherT[Option, String, Int] = EitherT(None) + * }}} + */ def combine(that: EitherT[F, A, B])(implicit F: Apply[F], B: Semigroup[B]): EitherT[F, A, B] = - EitherT(F.map2(this.value, that.value)(_ combine _)) + EitherT(F.map2(this.value, that.value)(_.combine(_))) def toValidated(implicit F: Functor[F]): F[Validated[A, B]] = F.map(value)(_.toValidated) @@ -209,47 +218,47 @@ final case class EitherT[F[_], A, B](value: F[Either[A, B]]) { F.map(value)(_.toValidatedNec) /** Run this value as a `[[Validated]]` against the function and convert it back to an `[[EitherT]]`. - * - * The [[Applicative]] instance for `EitherT` "fails fast" - it is often useful to "momentarily" have - * it accumulate errors instead, which is what the `[[Validated]]` data type gives us. - * - * Example: - * {{{ - * scala> import cats.implicits._ - * scala> type Error = String - * scala> val v1: Validated[NonEmptyList[Error], Int] = Validated.invalidNel("error 1") - * scala> val v2: Validated[NonEmptyList[Error], Int] = Validated.invalidNel("error 2") - * scala> val eithert: EitherT[Option, Error, Int] = EitherT.leftT[Option, Int]("error 3") - * scala> eithert.withValidated { v3 => (v1, v2, v3.toValidatedNel).mapN { case (i, j, k) => i + j + k } } - * res0: EitherT[Option, NonEmptyList[Error], Int] = EitherT(Some(Left(NonEmptyList(error 1, error 2, error 3)))) - * }}} - */ + * + * The [[Applicative]] instance for `EitherT` "fails fast" - it is often useful to "momentarily" have + * it accumulate errors instead, which is what the `[[Validated]]` data type gives us. + * + * Example: + * {{{ + * scala> import cats.implicits._ + * scala> type Error = String + * scala> val v1: Validated[NonEmptyList[Error], Int] = Validated.invalidNel("error 1") + * scala> val v2: Validated[NonEmptyList[Error], Int] = Validated.invalidNel("error 2") + * scala> val eithert: EitherT[Option, Error, Int] = EitherT.leftT[Option, Int]("error 3") + * scala> eithert.withValidated { v3 => (v1, v2, v3.toValidatedNel).mapN { case (i, j, k) => i + j + k } } + * res0: EitherT[Option, NonEmptyList[Error], Int] = EitherT(Some(Left(NonEmptyList(error 1, error 2, error 3)))) + * }}} + */ def withValidated[AA, BB](f: Validated[A, B] => Validated[AA, BB])(implicit F: Functor[F]): EitherT[F, AA, BB] = EitherT(F.map(value)(either => f(either.toValidated).toEither)) def show(implicit show: Show[F[Either[A, B]]]): String = show.show(value) /** - * Transform this `EitherT[F, A, B]` into a `[[Nested]][F, Either[A, ?], B]`. - * - * An example where `toNested` can be used, is to get the `Apply.ap` function with the - * behavior from the composed `Apply` instances from `F` and `Either[A, ?]`, which is - * inconsistent with the behavior of the `ap` from `Monad` of `EitherT`. - * - * {{{ - * scala> import cats.data.EitherT - * scala> import cats.implicits._ - * scala> val ff: EitherT[List, String, Int => String] = - * | EitherT(List(Either.right(_.toString), Either.left("error"))) - * scala> val fa: EitherT[List, String, Int] = - * | EitherT(List(Either.right(1), Either.right(2))) - * scala> ff.ap(fa) - * res0: EitherT[List,String,String] = EitherT(List(Right(1), Right(2), Left(error))) - * scala> EitherT((ff.toNested).ap(fa.toNested).value) - * res1: EitherT[List,String,String] = EitherT(List(Right(1), Right(2), Left(error), Left(error))) - * }}} - * - */ + * Transform this `EitherT[F, A, B]` into a `[[Nested]][F, Either[A, ?], B]`. + * + * An example where `toNested` can be used, is to get the `Apply.ap` function with the + * behavior from the composed `Apply` instances from `F` and `Either[A, ?]`, which is + * inconsistent with the behavior of the `ap` from `Monad` of `EitherT`. + * + * {{{ + * scala> import cats.data.EitherT + * scala> import cats.implicits._ + * scala> val ff: EitherT[List, String, Int => String] = + * | EitherT(List(Either.right(_.toString), Either.left("error"))) + * scala> val fa: EitherT[List, String, Int] = + * | EitherT(List(Either.right(1), Either.right(2))) + * scala> ff.ap(fa) + * res0: EitherT[List,String,String] = EitherT(List(Right(1), Right(2), Left(error))) + * scala> EitherT((ff.toNested).ap(fa.toNested).value) + * res1: EitherT[List,String,String] = EitherT(List(Right(1), Right(2), Left(error), Left(error))) + * }}} + * + */ def toNested: Nested[F, Either[A, ?], B] = Nested[F, Either[A, ?], B](value) /** @@ -273,14 +282,14 @@ final case class EitherT[F[_], A, B](value: F[Either[A, B]]) { Nested[F, Validated[A, ?], B](F.map(value)(_.toValidated)) /** - * Transform this `EitherT[F, A, B]` into a `[[Nested]][F, ValidatedNel[A, ?], B]`. - */ + * Transform this `EitherT[F, A, B]` into a `[[Nested]][F, ValidatedNel[A, ?], B]`. + */ def toNestedValidatedNel(implicit F: Functor[F]): Nested[F, ValidatedNel[A, ?], B] = Nested[F, ValidatedNel[A, ?], B](F.map(value)(_.toValidatedNel)) /** - * Transform this `EitherT[F, A, B]` into a `[[Nested]][F, ValidatedNec[A, ?], B]`. - */ + * Transform this `EitherT[F, A, B]` into a `[[Nested]][F, ValidatedNec[A, ?], B]`. + */ def toNestedValidatedNec(implicit F: Functor[F]): Nested[F, ValidatedNec[A, ?], B] = Nested[F, ValidatedNec[A, ?], B](F.map(value)(_.toValidatedNec)) } @@ -288,114 +297,113 @@ final case class EitherT[F[_], A, B](value: F[Either[A, B]]) { object EitherT extends EitherTInstances { /** - * Uses the [[http://typelevel.org/cats/guidelines.html#partially-applied-type-params Partially Applied Type Params technique]] for ergonomics. - */ - private[data] final class LeftPartiallyApplied[B](val dummy: Boolean = true) extends AnyVal { + * Uses the [[http://typelevel.org/cats/guidelines.html#partially-applied-type-params Partially Applied Type Params technique]] for ergonomics. + */ + final private[data] class LeftPartiallyApplied[B](val dummy: Boolean = true) extends AnyVal { def apply[F[_], A](fa: F[A])(implicit F: Functor[F]): EitherT[F, A, B] = EitherT(F.map(fa)(Either.left)) } /** - * Creates a left version of `EitherT[F, A, B]` from a `F[A]` - * {{{ - * scala> import cats.data.EitherT - * scala> import cats.implicits._ - * scala> EitherT.left[Int](Option("err")) - * res0: cats.data.EitherT[Option,String,Int] = EitherT(Some(Left(err))) - * }}} - */ + * Creates a left version of `EitherT[F, A, B]` from a `F[A]` + * {{{ + * scala> import cats.data.EitherT + * scala> import cats.implicits._ + * scala> EitherT.left[Int](Option("err")) + * res0: cats.data.EitherT[Option,String,Int] = EitherT(Some(Left(err))) + * }}} + */ final def left[B]: LeftPartiallyApplied[B] = new LeftPartiallyApplied[B] /** - * Uses the [[http://typelevel.org/cats/guidelines.html#partially-applied-type-params Partially Applied Type Params technique]] for ergonomics. - */ - private[data] final class LeftTPartiallyApplied[F[_], B](val dummy: Boolean = true) extends AnyVal { + * Uses the [[http://typelevel.org/cats/guidelines.html#partially-applied-type-params Partially Applied Type Params technique]] for ergonomics. + */ + final private[data] class LeftTPartiallyApplied[F[_], B](val dummy: Boolean = true) extends AnyVal { def apply[A](a: A)(implicit F: Applicative[F]): EitherT[F, A, B] = EitherT(F.pure(Either.left(a))) } /** - * Creates a left version of `EitherT[F, A, B]` from a `A` - * {{{ - * scala> import cats.data.EitherT - * scala> import cats.implicits._ - * scala> EitherT.leftT[Option, Int]("err") - * res0: cats.data.EitherT[Option,String,Int] = EitherT(Some(Left(err))) - * }}} - */ + * Creates a left version of `EitherT[F, A, B]` from a `A` + * {{{ + * scala> import cats.data.EitherT + * scala> import cats.implicits._ + * scala> EitherT.leftT[Option, Int]("err") + * res0: cats.data.EitherT[Option,String,Int] = EitherT(Some(Left(err))) + * }}} + */ final def leftT[F[_], B]: LeftTPartiallyApplied[F, B] = new LeftTPartiallyApplied[F, B] /** - * Uses the [[http://typelevel.org/cats/guidelines.html#partially-applied-type-params Partially Applied Type Params technique]] for ergonomics. - */ - private[data] final class RightPartiallyApplied[A](val dummy: Boolean = true) extends AnyVal { + * Uses the [[http://typelevel.org/cats/guidelines.html#partially-applied-type-params Partially Applied Type Params technique]] for ergonomics. + */ + final private[data] class RightPartiallyApplied[A](val dummy: Boolean = true) extends AnyVal { def apply[F[_], B](fb: F[B])(implicit F: Functor[F]): EitherT[F, A, B] = EitherT(F.map(fb)(Either.right)) } /** - * Creates a right version of `EitherT[F, A, B]` from a `F[B]` - * {{{ - * scala> import cats.data.EitherT - * scala> import cats.implicits._ - * scala> EitherT.right[String](Option(3)) - * res0: cats.data.EitherT[Option,String,Int] = EitherT(Some(Right(3))) - * }}} - */ + * Creates a right version of `EitherT[F, A, B]` from a `F[B]` + * {{{ + * scala> import cats.data.EitherT + * scala> import cats.implicits._ + * scala> EitherT.right[String](Option(3)) + * res0: cats.data.EitherT[Option,String,Int] = EitherT(Some(Right(3))) + * }}} + */ final def right[A]: RightPartiallyApplied[A] = new RightPartiallyApplied[A] /** - * Uses the [[http://typelevel.org/cats/guidelines.html#partially-applied-type-params Partially Applied Type Params technique]] for ergonomics. - */ - private[data] final class PurePartiallyApplied[F[_], A](val dummy: Boolean = true) extends AnyVal { + * Uses the [[http://typelevel.org/cats/guidelines.html#partially-applied-type-params Partially Applied Type Params technique]] for ergonomics. + */ + final private[data] class PurePartiallyApplied[F[_], A](val dummy: Boolean = true) extends AnyVal { def apply[B](b: B)(implicit F: Applicative[F]): EitherT[F, A, B] = right(F.pure(b)) } /** - * Creates a new `EitherT[F, A, B]` from a `B` - * {{{ - * scala> import cats.data.EitherT - * scala> import cats.implicits._ - * scala> EitherT.pure[Option, String](3) - * res0: cats.data.EitherT[Option,String,Int] = EitherT(Some(Right(3))) - * }}} - */ + * Creates a new `EitherT[F, A, B]` from a `B` + * {{{ + * scala> import cats.data.EitherT + * scala> import cats.implicits._ + * scala> EitherT.pure[Option, String](3) + * res0: cats.data.EitherT[Option,String,Int] = EitherT(Some(Right(3))) + * }}} + */ final def pure[F[_], A]: PurePartiallyApplied[F, A] = new PurePartiallyApplied[F, A] /** - * Alias for [[pure]] - * {{{ - * scala> import cats.data.EitherT - * scala> import cats.implicits._ - * scala> EitherT.rightT[Option, String](3) - * res0: cats.data.EitherT[Option,String,Int] = EitherT(Some(Right(3))) - * }}} - */ + * Alias for [[pure]] + * {{{ + * scala> import cats.data.EitherT + * scala> import cats.implicits._ + * scala> EitherT.rightT[Option, String](3) + * res0: cats.data.EitherT[Option,String,Int] = EitherT(Some(Right(3))) + * }}} + */ final def rightT[F[_], A]: PurePartiallyApplied[F, A] = pure - /** - * Alias for [[right]] - * {{{ - * scala> import cats.data.EitherT - * scala> import cats.implicits._ - * scala> val o: Option[Int] = Some(3) - * scala> val n: Option[Int] = None - * scala> EitherT.liftF(o) - * res0: cats.data.EitherT[Option,Nothing,Int] = EitherT(Some(Right(3))) - * scala> EitherT.liftF(n) - * res1: cats.data.EitherT[Option,Nothing,Int] = EitherT(None) - * }}} - */ + * Alias for [[right]] + * {{{ + * scala> import cats.data.EitherT + * scala> import cats.implicits._ + * scala> val o: Option[Int] = Some(3) + * scala> val n: Option[Int] = None + * scala> EitherT.liftF(o) + * res0: cats.data.EitherT[Option,Nothing,Int] = EitherT(Some(Right(3))) + * scala> EitherT.liftF(n) + * res1: cats.data.EitherT[Option,Nothing,Int] = EitherT(None) + * }}} + */ final def liftF[F[_], A, B](fb: F[B])(implicit F: Functor[F]): EitherT[F, A, B] = right(fb) /** - * Same as [[liftF]], but expressed as a FunctionK for use with mapK - * {{{ - * scala> import cats._, data._, implicits._ - * scala> val a: OptionT[Eval, Int] = 1.pure[OptionT[Eval, ?]] - * scala> val b: OptionT[EitherT[Eval, String, ?], Int] = a.mapK(EitherT.liftK) - * scala> b.value.value.value - * res0: Either[String,Option[Int]] = Right(Some(1)) - * }}} - */ + * Same as [[liftF]], but expressed as a FunctionK for use with mapK + * {{{ + * scala> import cats._, data._, implicits._ + * scala> val a: OptionT[Eval, Int] = 1.pure[OptionT[Eval, ?]] + * scala> val b: OptionT[EitherT[Eval, String, ?], Int] = a.mapK(EitherT.liftK) + * scala> b.value.value.value + * res0: Either[String,Option[Int]] = Right(Some(1)) + * }}} + */ final def liftK[F[_], A](implicit F: Functor[F]): F ~> EitherT[F, A, ?] = λ[F ~> EitherT[F, A, ?]](right(_)) @@ -403,59 +411,59 @@ object EitherT extends EitherTInstances { final def liftT[F[_], A, B](fb: F[B])(implicit F: Functor[F]): EitherT[F, A, B] = right(fb) /** Transforms an `Either` into an `EitherT`, lifted into the specified `Applicative`. - * - * Note: The return type is a FromEitherPartiallyApplied[F], which has an apply method - * on it, allowing you to call fromEither like this: - * {{{ - * scala> import cats.implicits._ - * scala> val t: Either[String, Int] = Either.right(3) - * scala> EitherT.fromEither[Option](t) - * res0: EitherT[Option, String, Int] = EitherT(Some(Right(3))) - * }}} - * - * The reason for the indirection is to emulate currying type parameters. - */ + * + * Note: The return type is a FromEitherPartiallyApplied[F], which has an apply method + * on it, allowing you to call fromEither like this: + * {{{ + * scala> import cats.implicits._ + * scala> val t: Either[String, Int] = Either.right(3) + * scala> EitherT.fromEither[Option](t) + * res0: EitherT[Option, String, Int] = EitherT(Some(Right(3))) + * }}} + * + * The reason for the indirection is to emulate currying type parameters. + */ final def fromEither[F[_]]: FromEitherPartiallyApplied[F] = new FromEitherPartiallyApplied /** - * Uses the [[http://typelevel.org/cats/guidelines.html#partially-applied-type-params Partially Applied Type Params technique]] for ergonomics. - */ - private[data] final class FromEitherPartiallyApplied[F[_]](val dummy: Boolean = true) extends AnyVal { + * Uses the [[http://typelevel.org/cats/guidelines.html#partially-applied-type-params Partially Applied Type Params technique]] for ergonomics. + */ + final private[data] class FromEitherPartiallyApplied[F[_]](val dummy: Boolean = true) extends AnyVal { def apply[E, A](either: Either[E, A])(implicit F: Applicative[F]): EitherT[F, E, A] = EitherT(F.pure(either)) } /** Transforms an `Option` into an `EitherT`, lifted into the specified `Applicative` and using - * the second argument if the `Option` is a `None`. - * {{{ - * scala> import cats.implicits._ - * scala> val o: Option[Int] = None - * scala> EitherT.fromOption[List](o, "Answer not known.") - * res0: EitherT[List, String, Int] = EitherT(List(Left(Answer not known.))) - * scala> EitherT.fromOption[List](Some(42), "Answer not known.") - * res1: EitherT[List, String, Int] = EitherT(List(Right(42))) - * }}} - */ + * the second argument if the `Option` is a `None`. + * {{{ + * scala> import cats.implicits._ + * scala> val o: Option[Int] = None + * scala> EitherT.fromOption[List](o, "Answer not known.") + * res0: EitherT[List, String, Int] = EitherT(List(Left(Answer not known.))) + * scala> EitherT.fromOption[List](Some(42), "Answer not known.") + * res1: EitherT[List, String, Int] = EitherT(List(Right(42))) + * }}} + */ final def fromOption[F[_]]: FromOptionPartiallyApplied[F] = new FromOptionPartiallyApplied /** - * Uses the [[http://typelevel.org/cats/guidelines.html#partially-applied-type-params Partially Applied Type Params technique]] for ergonomics. - */ - private[data] final class FromOptionPartiallyApplied[F[_]](val dummy: Boolean = true) extends AnyVal { + * Uses the [[http://typelevel.org/cats/guidelines.html#partially-applied-type-params Partially Applied Type Params technique]] for ergonomics. + */ + final private[data] class FromOptionPartiallyApplied[F[_]](val dummy: Boolean = true) extends AnyVal { def apply[E, A](opt: Option[A], ifNone: => E)(implicit F: Applicative[F]): EitherT[F, E, A] = EitherT(F.pure(Either.fromOption(opt, ifNone))) } /** Transforms an `F[Option]` into an `EitherT`, using the second argument if the `Option` is a `None`. - * {{{ - * scala> import cats.implicits._ - * scala> val o: Option[Int] = None - * scala> EitherT.fromOptionF(List(o), "Answer not known.") - * res0: EitherT[List, String, Int] = EitherT(List(Left(Answer not known.))) - * scala> EitherT.fromOptionF(List(Option(42)), "Answer not known.") - * res1: EitherT[List, String, Int] = EitherT(List(Right(42))) - * }}} - */ + * {{{ + * scala> import cats.implicits._ + * scala> val o: Option[Int] = None + * scala> EitherT.fromOptionF(List(o), "Answer not known.") + * res0: EitherT[List, String, Int] = EitherT(List(Left(Answer not known.))) + * scala> EitherT.fromOptionF(List(Option(42)), "Answer not known.") + * res1: EitherT[List, String, Int] = EitherT(List(Right(42))) + * }}} + */ final def fromOptionF[F[_], E, A](fopt: F[Option[A]], ifNone: => E)(implicit F: Functor[F]): EitherT[F, E, A] = EitherT(F.map(fopt)(opt => Either.fromOption(opt, ifNone))) @@ -477,15 +485,15 @@ object EitherT extends EitherTInstances { final def cond[F[_]]: CondPartiallyApplied[F] = new CondPartiallyApplied /** - * Uses the [[http://typelevel.org/cats/guidelines.html#partially-applied-type-params Partially Applied Type Params technique]] for ergonomics. - */ - private[data] final class CondPartiallyApplied[F[_]](val dummy: Boolean = true) extends AnyVal { + * Uses the [[http://typelevel.org/cats/guidelines.html#partially-applied-type-params Partially Applied Type Params technique]] for ergonomics. + */ + final private[data] class CondPartiallyApplied[F[_]](val dummy: Boolean = true) extends AnyVal { def apply[E, A](test: Boolean, right: => A, left: => E)(implicit F: Applicative[F]): EitherT[F, E, A] = EitherT(F.pure(Either.cond(test, right, left))) } } -private[data] abstract class EitherTInstances extends EitherTInstances1 { +abstract private[data] class EitherTInstances extends EitherTInstances1 { implicit def catsDataOrderForEitherT[F[_], L, R](implicit F: Order[F[Either[L, R]]]): Order[EitherT[F, L, R]] = new EitherTOrder[F, L, R] { @@ -516,9 +524,11 @@ private[data] abstract class EitherTInstances extends EitherTInstances1 { } } -private[data] abstract class EitherTInstances1 extends EitherTInstances2 { +abstract private[data] class EitherTInstances1 extends EitherTInstances2 { - implicit def catsSemigroupForEitherT[F[_], L, A](implicit F: Semigroup[F[Either[L, A]]]): Semigroup[EitherT[F, L, A]] = + implicit def catsSemigroupForEitherT[F[_], L, A]( + implicit F: Semigroup[F[Either[L, A]]] + ): Semigroup[EitherT[F, L, A]] = new EitherTSemigroup[F, L, A] { implicit val F0 = F } implicit def catsDataFoldableForEitherT[F[_], L](implicit F: Foldable[F]): Foldable[EitherT[F, L, ?]] = @@ -526,7 +536,9 @@ private[data] abstract class EitherTInstances1 extends EitherTInstances2 { val F0: Foldable[F] = F } - implicit def catsDataPartialOrderForEitherT[F[_], L, R](implicit F: PartialOrder[F[Either[L, R]]]): PartialOrder[EitherT[F, L, R]] = + implicit def catsDataPartialOrderForEitherT[F[_], L, R]( + implicit F: PartialOrder[F[Either[L, R]]] + ): PartialOrder[EitherT[F, L, R]] = new EitherTPartialOrder[F, L, R] { val F0: PartialOrder[F[Either[L, R]]] = F } @@ -547,25 +559,27 @@ private[data] abstract class EitherTInstances1 extends EitherTInstances2 { } } -private[data] abstract class EitherTInstances2 extends EitherTInstances3 { +abstract private[data] class EitherTInstances2 extends EitherTInstances3 { + /** Monad error instance for recovering errors in F instead of - * the underlying Either. - * - * {{{ - * scala> import cats.data.EitherT - * scala> import cats.MonadError - * scala> import cats.instances.option._ - * scala> val noInt: Option[Either[String, Int]] = None - * scala> val et = EitherT[Option, String, Int](noInt) - * scala> val me = MonadError[EitherT[Option, String, ?], Unit] - * scala> me.recover(et) { case () => 1 } - * res0: cats.data.EitherT[Option,String,Int] = EitherT(Some(Right(1))) - * }}} - */ - implicit def catsDataMonadErrorFForEitherT[F[_], E, L](implicit FE0: MonadError[F, E]): MonadError[EitherT[F, L, ?], E] = + * the underlying Either. + * + * {{{ + * scala> import cats.data.EitherT + * scala> import cats.MonadError + * scala> import cats.instances.option._ + * scala> val noInt: Option[Either[String, Int]] = None + * scala> val et = EitherT[Option, String, Int](noInt) + * scala> val me = MonadError[EitherT[Option, String, ?], Unit] + * scala> me.recover(et) { case () => 1 } + * res0: cats.data.EitherT[Option,String,Int] = EitherT(Some(Right(1))) + * }}} + */ + implicit def catsDataMonadErrorFForEitherT[F[_], E, L]( + implicit FE0: MonadError[F, E] + ): MonadError[EitherT[F, L, ?], E] = new EitherTMonadErrorF[F, E, L] { implicit val F = FE0 } - implicit def catsDataSemigroupKForEitherT[F[_], L](implicit F0: Monad[F]): SemigroupK[EitherT[F, L, ?]] = new EitherTSemigroupK[F, L] { implicit val F = F0 } @@ -575,14 +589,14 @@ private[data] abstract class EitherTInstances2 extends EitherTInstances3 { } } -private[data] abstract class EitherTInstances3 { +abstract private[data] class EitherTInstances3 { implicit def catsDataFunctorForEitherT[F[_], L](implicit F0: Functor[F]): Functor[EitherT[F, L, ?]] = new EitherTFunctor[F, L] { implicit val F = F0 } } private[data] trait EitherTSemigroup[F[_], L, A] extends Semigroup[EitherT[F, L, A]] { implicit val F0: Semigroup[F[Either[L, A]]] - def combine(x: EitherT[F, L , A], y: EitherT[F, L , A]): EitherT[F, L , A] = + def combine(x: EitherT[F, L, A], y: EitherT[F, L, A]): EitherT[F, L, A] = EitherT(F0.combine(x.value, y.value)) } @@ -595,27 +609,32 @@ private[data] trait EitherTSemigroupK[F[_], L] extends SemigroupK[EitherT[F, L, implicit val F: Monad[F] def combineK[A](x: EitherT[F, L, A], y: EitherT[F, L, A]): EitherT[F, L, A] = EitherT(F.flatMap(x.value) { - case l @ Left(_) => y.value + case l @ Left(_) => y.value case r @ Right(_) => F.pure(r) }) } private[data] trait EitherTFunctor[F[_], L] extends Functor[EitherT[F, L, ?]] { implicit val F: Functor[F] - override def map[A, B](fa: EitherT[F, L, A])(f: A => B): EitherT[F, L, B] = fa map f + override def map[A, B](fa: EitherT[F, L, A])(f: A => B): EitherT[F, L, B] = fa.map(f) } private[data] trait EitherTMonad[F[_], L] extends Monad[EitherT[F, L, ?]] with EitherTFunctor[F, L] { implicit val F: Monad[F] def pure[A](a: A): EitherT[F, L, A] = EitherT.pure(a) - def flatMap[A, B](fa: EitherT[F, L, A])(f: A => EitherT[F, L, B]): EitherT[F, L, B] = fa flatMap f + def flatMap[A, B](fa: EitherT[F, L, A])(f: A => EitherT[F, L, B]): EitherT[F, L, B] = fa.flatMap(f) def tailRecM[A, B](a: A)(f: A => EitherT[F, L, Either[A, B]]): EitherT[F, L, B] = - EitherT(F.tailRecM(a)(a0 => F.map(f(a0).value) { - case Left(l) => Right(Left(l)) - case Right(Left(a1)) => Left(a1) - case Right(Right(b)) => Right(Right(b)) - })) + EitherT( + F.tailRecM(a)( + a0 => + F.map(f(a0).value) { + case Left(l) => Right(Left(l)) + case Right(Left(a1)) => Left(a1) + case Right(Right(b)) => Right(Right(b)) + } + ) + ) } private[data] trait EitherTMonadErrorF[F[_], E, L] extends MonadError[EitherT[F, L, ?], E] with EitherTMonad[F, L] { @@ -630,12 +649,12 @@ private[data] trait EitherTMonadErrorF[F[_], E, L] extends MonadError[EitherT[F, private[data] trait EitherTMonadError[F[_], L] extends MonadError[EitherT[F, L, ?], L] with EitherTMonad[F, L] { def handleErrorWith[A](fea: EitherT[F, L, A])(f: L => EitherT[F, L, A]): EitherT[F, L, A] = EitherT(F.flatMap(fea.value) { - case Left(e) => f(e).value + case Left(e) => f(e).value case r @ Right(_) => F.pure(r) }) override def handleError[A](fea: EitherT[F, L, A])(f: L => A): EitherT[F, L, A] = EitherT(F.flatMap(fea.value) { - case Left(e) => F.pure(Right(f(e))) + case Left(e) => F.pure(Right(f(e))) case r @ Right(_) => F.pure(r) }) def raiseError[A](e: L): EitherT[F, L, A] = EitherT.left(F.pure(e)) @@ -646,7 +665,7 @@ private[data] trait EitherTMonadError[F[_], L] extends MonadError[EitherT[F, L, fla.recoverWith(pf) } -private[data] sealed trait EitherTFoldable[F[_], L] extends Foldable[EitherT[F, L, ?]] { +sealed private[data] trait EitherTFoldable[F[_], L] extends Foldable[EitherT[F, L, ?]] { implicit def F0: Foldable[F] def foldLeft[A, B](fa: EitherT[F, L, A], b: B)(f: (B, A) => B): B = @@ -656,51 +675,56 @@ private[data] sealed trait EitherTFoldable[F[_], L] extends Foldable[EitherT[F, fa.foldRight(lb)(f) } -private[data] sealed trait EitherTTraverse[F[_], L] extends Traverse[EitherT[F, L, ?]] with EitherTFoldable[F, L] { - override implicit def F0: Traverse[F] +sealed private[data] trait EitherTTraverse[F[_], L] extends Traverse[EitherT[F, L, ?]] with EitherTFoldable[F, L] { + implicit override def F0: Traverse[F] override def traverse[G[_]: Applicative, A, B](fa: EitherT[F, L, A])(f: A => G[B]): G[EitherT[F, L, B]] = - fa traverse f + fa.traverse(f) } -private[data] sealed trait EitherTBifoldable[F[_]] extends Bifoldable[EitherT[F, ?, ?]] { +sealed private[data] trait EitherTBifoldable[F[_]] extends Bifoldable[EitherT[F, ?, ?]] { implicit def F0: Foldable[F] def bifoldLeft[A, B, C](fab: EitherT[F, A, B], c: C)(f: (C, A) => C, g: (C, B) => C): C = - F0.foldLeft(fab.value, c)( (acc, axb) => Bifoldable[Either].bifoldLeft(axb, acc)(f, g)) + F0.foldLeft(fab.value, c)((acc, axb) => Bifoldable[Either].bifoldLeft(axb, acc)(f, g)) - def bifoldRight[A, B, C](fab: EitherT[F, A, B], c: Eval[C])(f: (A, Eval[C]) => Eval[C], g: (B, Eval[C]) => Eval[C]): Eval[C] = - F0.foldRight(fab.value, c)( (axb, acc) => Bifoldable[Either].bifoldRight(axb, acc)(f, g)) + def bifoldRight[A, B, C](fab: EitherT[F, A, B], c: Eval[C])(f: (A, Eval[C]) => Eval[C], + g: (B, Eval[C]) => Eval[C]): Eval[C] = + F0.foldRight(fab.value, c)((axb, acc) => Bifoldable[Either].bifoldRight(axb, acc)(f, g)) } -private[data] sealed trait EitherTBitraverse[F[_]] extends Bitraverse[EitherT[F, ?, ?]] with EitherTBifoldable[F] { - override implicit def F0: Traverse[F] +sealed private[data] trait EitherTBitraverse[F[_]] extends Bitraverse[EitherT[F, ?, ?]] with EitherTBifoldable[F] { + implicit override def F0: Traverse[F] - override def bitraverse[G[_], A, B, C, D](fab: EitherT[F, A, B])(f: A => G[C], g: B => G[D])(implicit G: Applicative[G]): G[EitherT[F, C, D]] = + override def bitraverse[G[_], A, B, C, D]( + fab: EitherT[F, A, B] + )(f: A => G[C], g: B => G[D])(implicit G: Applicative[G]): G[EitherT[F, C, D]] = fab.bitraverse(f, g) } -private[data] sealed trait EitherTBifunctor[F[_]] extends Bifunctor[EitherT[F, ?, ?]] { +sealed private[data] trait EitherTBifunctor[F[_]] extends Bifunctor[EitherT[F, ?, ?]] { implicit def F0: Functor[F] override def bimap[A, B, C, D](fab: EitherT[F, A, B])(f: A => C, g: B => D): EitherT[F, C, D] = fab.bimap(f, g) } -private[data] sealed trait EitherTEq[F[_], L, A] extends Eq[EitherT[F, L, A]] { +sealed private[data] trait EitherTEq[F[_], L, A] extends Eq[EitherT[F, L, A]] { implicit def F0: Eq[F[Either[L, A]]] override def eqv(x: EitherT[F, L, A], y: EitherT[F, L, A]): Boolean = x === y } -private[data] sealed trait EitherTPartialOrder[F[_], L, A] extends PartialOrder[EitherT[F, L, A]] with EitherTEq[F, L, A]{ - override implicit def F0: PartialOrder[F[Either[L, A]]] +sealed private[data] trait EitherTPartialOrder[F[_], L, A] + extends PartialOrder[EitherT[F, L, A]] + with EitherTEq[F, L, A] { + implicit override def F0: PartialOrder[F[Either[L, A]]] override def partialCompare(x: EitherT[F, L, A], y: EitherT[F, L, A]): Double = - x partialCompare y + x.partialCompare(y) } -private[data] sealed trait EitherTOrder[F[_], L, A] extends Order[EitherT[F, L, A]] with EitherTPartialOrder[F, L, A]{ - override implicit def F0: Order[F[Either[L, A]]] +sealed private[data] trait EitherTOrder[F[_], L, A] extends Order[EitherT[F, L, A]] with EitherTPartialOrder[F, L, A] { + implicit override def F0: Order[F[Either[L, A]]] - override def compare(x: EitherT[F, L, A], y: EitherT[F, L, A]): Int = x compare y + override def compare(x: EitherT[F, L, A], y: EitherT[F, L, A]): Int = x.compare(y) } diff --git a/core/src/main/scala/cats/data/Func.scala b/core/src/main/scala/cats/data/Func.scala index 17b480048eb..6f19ad9c5d8 100644 --- a/core/src/main/scala/cats/data/Func.scala +++ b/core/src/main/scala/cats/data/Func.scala @@ -4,23 +4,24 @@ package data import cats.Contravariant /** - * [[Func]] is a function `A => F[B]`. - * - * See: [[https://www.cs.ox.ac.uk/jeremy.gibbons/publications/iterator.pdf The Essence of the Iterator Pattern]] - */ + * [[Func]] is a function `A => F[B]`. + * + * See: [[https://www.cs.ox.ac.uk/jeremy.gibbons/publications/iterator.pdf The Essence of the Iterator Pattern]] + */ sealed abstract class Func[F[_], A, B] { self => def run: A => F[B] def map[C](f: B => C)(implicit FF: Functor[F]): Func[F, A, C] = Func.func(a => FF.map(self.run(a))(f)) /** - * Modify the context `F` using transformation `f`. - */ + * Modify the context `F` using transformation `f`. + */ def mapK[G[_]](f: F ~> G): Func[G, A, B] = - Func.func(run andThen f.apply) + Func.func(run.andThen(f.apply)) } object Func extends FuncInstances { + /** function `A => F[B]`. */ def func[F[_], A, B](run0: A => F[B]): Func[F, A, B] = new Func[F, A, B] { @@ -36,45 +37,47 @@ object Func extends FuncInstances { } -private[data] abstract class FuncInstances extends FuncInstances0 { +abstract private[data] class FuncInstances extends FuncInstances0 { implicit def catsDataApplicativeForFunc[F[_], C](implicit FF: Applicative[F]): Applicative[λ[α => Func[F, C, α]]] = new FuncApplicative[F, C] { def F: Applicative[F] = FF } } -private[data] abstract class FuncInstances0 extends FuncInstances1 { +abstract private[data] class FuncInstances0 extends FuncInstances1 { implicit def catsDataApplyForFunc[F[_], C](implicit FF: Apply[F]): Apply[λ[α => Func[F, C, α]]] = new FuncApply[F, C] { def F: Apply[F] = FF } } -private[data] abstract class FuncInstances1 { +abstract private[data] class FuncInstances1 { implicit def catsDataFunctorForFunc[F[_], C](implicit FF: Functor[F]): Functor[λ[α => Func[F, C, α]]] = new FuncFunctor[F, C] { def F: Functor[F] = FF } - implicit def catsDataContravariantForFunc[F[_], C](implicit FC: Contravariant[F]): Contravariant[λ[α => Func[F, α, C]]] = + implicit def catsDataContravariantForFunc[F[_], C]( + implicit FC: Contravariant[F] + ): Contravariant[λ[α => Func[F, α, C]]] = new FuncContravariant[F, C] { def F: Contravariant[F] = FC } } -private[data] sealed trait FuncFunctor[F[_], C] extends Functor[λ[α => Func[F, C, α]]] { +sealed private[data] trait FuncFunctor[F[_], C] extends Functor[λ[α => Func[F, C, α]]] { def F: Functor[F] override def map[A, B](fa: Func[F, C, A])(f: A => B): Func[F, C, B] = fa.map(f)(F) } -private[data] sealed trait FuncContravariant[F[_], C] extends Contravariant[λ[α => Func[F, α, C]]] { +sealed private[data] trait FuncContravariant[F[_], C] extends Contravariant[λ[α => Func[F, α, C]]] { def F: Contravariant[F] def contramap[A, B](fa: Func[F, A, C])(f: B => A): Func[F, B, C] = Func.func(a => fa.run(f(a))) } -private[data] sealed trait FuncApply[F[_], C] extends Apply[λ[α => Func[F, C, α]]] with FuncFunctor[F, C] { +sealed private[data] trait FuncApply[F[_], C] extends Apply[λ[α => Func[F, C, α]]] with FuncFunctor[F, C] { def F: Apply[F] def ap[A, B](f: Func[F, C, A => B])(fa: Func[F, C, A]): Func[F, C, B] = Func.func(c => F.ap(f.run(c))(fa.run(c))) @@ -82,31 +85,30 @@ private[data] sealed trait FuncApply[F[_], C] extends Apply[λ[α => Func[F, C, Func.func(c => F.product(fa.run(c), fb.run(c))) } -private[data] sealed trait FuncApplicative[F[_], C] extends Applicative[λ[α => Func[F, C, α]]] with FuncApply[F, C] { +sealed private[data] trait FuncApplicative[F[_], C] extends Applicative[λ[α => Func[F, C, α]]] with FuncApply[F, C] { def F: Applicative[F] def pure[A](a: A): Func[F, C, A] = Func.func(c => F.pure(a)) } /** - * An implementation of [[Func]] that's specialized to [[Applicative]]. - */ + * An implementation of [[Func]] that's specialized to [[Applicative]]. + */ sealed abstract class AppFunc[F[_], A, B] extends Func[F, A, B] { self => def F: Applicative[F] - def product[G[_]](g: AppFunc[G, A, B]): AppFunc[λ[α => Tuple2K[F, G, α]], A, B] = - { - implicit val FF: Applicative[F] = self.F - implicit val GG: Applicative[G] = g.F - Func.appFunc[λ[α => Tuple2K[F, G, α]], A, B]{ - a: A => Tuple2K(self.run(a), g.run(a)) - } + def product[G[_]](g: AppFunc[G, A, B]): AppFunc[λ[α => Tuple2K[F, G, α]], A, B] = { + implicit val FF: Applicative[F] = self.F + implicit val GG: Applicative[G] = g.F + Func.appFunc[λ[α => Tuple2K[F, G, α]], A, B] { a: A => + Tuple2K(self.run(a), g.run(a)) } + } def compose[G[_], C](g: AppFunc[G, C, A]): AppFunc[Nested[G, F, ?], C, B] = { implicit val gfApplicative: Applicative[Nested[G, F, ?]] = Nested.catsDataApplicativeForNested[G, F](g.F, F) - Func.appFunc[Nested[G, F, ?], C, B]({ - c: C => Nested(g.F.map(g.run(c))(self.run)) + Func.appFunc[Nested[G, F, ?], C, B]({ c: C => + Nested(g.F.map(g.run(c))(self.run)) }) } @@ -124,14 +126,14 @@ sealed abstract class AppFunc[F[_], A, B] extends Func[F, A, B] { self => object AppFunc extends AppFuncInstances -private[data] abstract class AppFuncInstances { +abstract private[data] class AppFuncInstances { implicit def appFuncApplicative[F[_], C](implicit FF: Applicative[F]): Applicative[λ[α => AppFunc[F, C, α]]] = new AppFuncApplicative[F, C] { def F: Applicative[F] = FF } } -private[data] sealed trait AppFuncApplicative[F[_], C] extends Applicative[λ[α => AppFunc[F, C, α]]] { +sealed private[data] trait AppFuncApplicative[F[_], C] extends Applicative[λ[α => AppFunc[F, C, α]]] { def F: Applicative[F] override def map[A, B](fa: AppFunc[F, C, A])(f: A => B): AppFunc[F, C, B] = fa.map(f) diff --git a/core/src/main/scala/cats/data/IdT.scala b/core/src/main/scala/cats/data/IdT.scala index 2c8bcfef519..8e24740c862 100644 --- a/core/src/main/scala/cats/data/IdT.scala +++ b/core/src/main/scala/cats/data/IdT.scala @@ -2,16 +2,16 @@ package cats package data /** - * `IdT[F[_], A]` is the identity monad transformer. - */ + * `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)) /** - * Modify the context `F` using transformation `f`. - */ + * Modify the context `F` using transformation `f`. + */ def mapK[G[_]](f: F ~> G): IdT[G, A] = IdT[G, A](f(value)) @@ -50,14 +50,14 @@ object IdT extends IdTInstances { IdT(F.pure(a)) } -private[data] sealed trait IdTFunctor[F[_]] extends Functor[IdT[F, ?]] { +sealed private[data] trait IdTFunctor[F[_]] extends Functor[IdT[F, ?]] { implicit val F0: Functor[F] override def map[A, B](fa: IdT[F, A])(f: A => B): IdT[F, B] = fa.map(f) } -private[data] sealed trait IdTApply[F[_]] extends Apply[IdT[F, ?]] with IdTFunctor[F] { +sealed private[data] trait IdTApply[F[_]] extends Apply[IdT[F, ?]] with IdTFunctor[F] { implicit val F0: Apply[F] override def ap[A, B](ff: IdT[F, A => B])(fa: IdT[F, A]): IdT[F, B] = fa.ap(ff) @@ -67,13 +67,13 @@ private[data] sealed trait IdTApply[F[_]] extends Apply[IdT[F, ?]] with IdTFunct .map(IdT(_)) } -private[data] sealed trait IdTApplicative[F[_]] extends Applicative[IdT[F, ?]] with IdTApply[F] { +sealed private[data] trait IdTApplicative[F[_]] extends Applicative[IdT[F, ?]] with IdTApply[F] { implicit val F0: Applicative[F] def pure[A](a: A): IdT[F, A] = IdT.pure(a) } -private[data] sealed trait IdTContravariantMonoidal[F[_]] extends ContravariantMonoidal[IdT[F, ?]] { +sealed private[data] trait IdTContravariantMonoidal[F[_]] extends ContravariantMonoidal[IdT[F, ?]] { implicit val F0: ContravariantMonoidal[F] override def unit: IdT[F, Unit] = IdT(F0.unit) @@ -85,7 +85,7 @@ private[data] sealed trait IdTContravariantMonoidal[F[_]] extends ContravariantM IdT(F0.product(fa.value, fb.value)) } -private[data] sealed trait IdTFlatMap[F[_]] extends FlatMap[IdT[F, ?]] with IdTApply[F] { +sealed private[data] trait IdTFlatMap[F[_]] extends FlatMap[IdT[F, ?]] with IdTApply[F] { implicit val F0: FlatMap[F] def flatMap[A, B](fa: IdT[F, A])(f: A => IdT[F, B]): IdT[F, B] = @@ -95,11 +95,11 @@ private[data] sealed trait IdTFlatMap[F[_]] extends FlatMap[IdT[F, ?]] with IdTA IdT(F0.tailRecM(a)(f(_).value)) } -private[data] sealed trait IdTMonad[F[_]] extends Monad[IdT[F, ?]] with IdTApplicative[F] with IdTFlatMap[F] { +sealed private[data] trait IdTMonad[F[_]] extends Monad[IdT[F, ?]] with IdTApplicative[F] with IdTFlatMap[F] { implicit val F0: Monad[F] } -private[data] sealed trait IdTFoldable[F[_]] extends Foldable[IdT[F, ?]] { +sealed private[data] 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 = @@ -115,14 +115,17 @@ private[data] sealed trait IdTFoldable[F[_]] extends Foldable[IdT[F, ?]] { F0.get(fa.value)(idx) } -private[data] sealed trait IdTTraverse[F[_]] extends Traverse[IdT[F, ?]] with IdTFoldable[F] with IdTFunctor[F] { +sealed private[data] trait IdTTraverse[F[_]] extends Traverse[IdT[F, ?]] with IdTFoldable[F] with IdTFunctor[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 trait IdTNonEmptyTraverse[F[_]] extends IdTTraverse[F] with NonEmptyTraverse[IdT[F, ?]] with IdTFunctor[F] { +sealed private[data] trait IdTNonEmptyTraverse[F[_]] + extends IdTTraverse[F] + with NonEmptyTraverse[IdT[F, ?]] + with IdTFunctor[F] { implicit val F0: NonEmptyTraverse[F] def nonEmptyTraverse[G[_]: Apply, A, B](fa: IdT[F, A])(f: A => G[B]): G[IdT[F, B]] = @@ -135,42 +138,46 @@ private[data] sealed trait IdTNonEmptyTraverse[F[_]] extends IdTTraverse[F] with fa.reduceRightTo(f)(g) } -private[data] sealed abstract class IdTInstances8 { - implicit def catsDataCommutativeFlatMapForIdT[F[_]](implicit F: CommutativeFlatMap[F]): CommutativeFlatMap[IdT[F, ?]] = +sealed abstract private[data] class IdTInstances8 { + implicit def catsDataCommutativeFlatMapForIdT[F[_]]( + implicit F: CommutativeFlatMap[F] + ): CommutativeFlatMap[IdT[F, ?]] = new IdTFlatMap[F] with CommutativeFlatMap[IdT[F, ?]] { implicit val F0: CommutativeFlatMap[F] = F } } -private[data] sealed abstract class IdTInstances7 extends IdTInstances8{ +sealed abstract private[data] class IdTInstances7 extends IdTInstances8 { implicit def catsDataCommutativeMonadForIdT[F[_]](implicit F: CommutativeMonad[F]): CommutativeMonad[IdT[F, ?]] = new IdTMonad[F] with CommutativeMonad[IdT[F, ?]] { implicit val F0: CommutativeMonad[F] = F } } -private[data] sealed abstract class IdTInstances6 extends IdTInstances7 { - implicit def catsDataContravariantMonoidalForIdT[F[_]](implicit F: ContravariantMonoidal[F]): ContravariantMonoidal[IdT[F, ?]] = +sealed abstract private[data] class IdTInstances6 extends IdTInstances7 { + implicit def catsDataContravariantMonoidalForIdT[F[_]]( + implicit F: ContravariantMonoidal[F] + ): ContravariantMonoidal[IdT[F, ?]] = new IdTContravariantMonoidal[F] { implicit val F0: ContravariantMonoidal[F] = F } } -private[data] sealed abstract class IdTInstances5 extends IdTInstances6 { +sealed abstract private[data] class IdTInstances5 extends IdTInstances6 { implicit def catsDataFunctorForIdT[F[_]](implicit F: Functor[F]): Functor[IdT[F, ?]] = new IdTFunctor[F] { implicit val F0: Functor[F] = F } } -private[data] sealed abstract class IdTInstances4 extends IdTInstances5 { +sealed abstract private[data] class IdTInstances4 extends IdTInstances5 { implicit def catsDataApplyForIdT[F[_]](implicit F: Apply[F]): Apply[IdT[F, ?]] = new IdTApply[F] { implicit val F0: Apply[F] = F } } -private[data] sealed abstract class IdTInstances3 extends IdTInstances4 { +sealed abstract private[data] class IdTInstances3 extends IdTInstances4 { implicit def catsDataApplicativeForIdT[F[_]](implicit F: Applicative[F]): Applicative[IdT[F, ?]] = new IdTApplicative[F] { implicit val F0: Applicative[F] = F } } -private[data] sealed abstract class IdTInstances2 extends IdTInstances3 { +sealed abstract private[data] class IdTInstances2 extends IdTInstances3 { implicit def catsDataFlatMapForIdT[F[_]](implicit F: FlatMap[F]): FlatMap[IdT[F, ?]] = new IdTFlatMap[F] { implicit val F0: FlatMap[F] = F } } -private[data] sealed abstract class IdTInstances1 extends IdTInstances2 { +sealed abstract private[data] class IdTInstances1 extends IdTInstances2 { implicit def catsDataMonadForIdT[F[_]](implicit F: Monad[F]): Monad[IdT[F, ?]] = new IdTMonad[F] { implicit val F0: Monad[F] = F } @@ -178,7 +185,7 @@ private[data] sealed abstract class IdTInstances1 extends IdTInstances2 { new IdTFoldable[F] { implicit val F0: Foldable[F] = F } } -private[data] sealed abstract class IdTInstances0 extends IdTInstances1 { +sealed abstract private[data] class IdTInstances0 extends IdTInstances1 { implicit def catsDataTraverseForIdT[F[_]](implicit F: Traverse[F]): Traverse[IdT[F, ?]] = new IdTTraverse[F] { implicit val F0: Traverse[F] = F } @@ -187,7 +194,7 @@ private[data] sealed abstract class IdTInstances0 extends IdTInstances1 { Eq.by[IdT[F, A], F[A]](_.value) } -private[data] sealed abstract class IdTInstances extends IdTInstances0 { +sealed abstract private[data] class IdTInstances extends IdTInstances0 { implicit def catsDataNonEmptyTraverseForIdT[F[_]](implicit F: NonEmptyTraverse[F]): NonEmptyTraverse[IdT[F, ?]] = new IdTNonEmptyTraverse[F] { implicit val F0: NonEmptyTraverse[F] = F } diff --git a/core/src/main/scala/cats/data/IndexedReaderWriterStateT.scala b/core/src/main/scala/cats/data/IndexedReaderWriterStateT.scala index c2df4efe87a..3a98820c05e 100644 --- a/core/src/main/scala/cats/data/IndexedReaderWriterStateT.scala +++ b/core/src/main/scala/cats/data/IndexedReaderWriterStateT.scala @@ -6,488 +6,543 @@ import cats.arrow.{Profunctor, Strong} import cats.syntax.either._ /** - * Represents a stateful computation in a context `F[_]`, from state `SA` to state `SB`, - * with an initial environment `E`, an accumulated log `L` and a result `A`. - * - * In other words, it is a pre-baked stack of `[[ReaderT]][F, E, A]`, `[[WriterT]][F, L, A]` - * and `[[IndexedStateT]][F, SA, SB, A]`. - */ -final class IndexedReaderWriterStateT[F[_], E, L, SA, SB, A](val runF: F[(E, SA) => F[(L, SB, A)]]) extends Serializable { - - /** - * Modify the initial state using `f`. - */ + * Represents a stateful computation in a context `F[_]`, from state `SA` to state `SB`, + * with an initial environment `E`, an accumulated log `L` and a result `A`. + * + * In other words, it is a pre-baked stack of `[[ReaderT]][F, E, A]`, `[[WriterT]][F, L, A]` + * and `[[IndexedStateT]][F, SA, SB, A]`. + */ +final class IndexedReaderWriterStateT[F[_], E, L, SA, SB, A](val runF: F[(E, SA) => F[(L, SB, A)]]) + extends Serializable { + + /** + * Modify the initial state using `f`. + */ def contramap[S0](f: S0 => SA)(implicit F: Functor[F]): IndexedReaderWriterStateT[F, E, L, S0, SB, A] = IndexedReaderWriterStateT.applyF { - F.map(runF) { rwsfa => - (e: E, s0: S0) => rwsfa(e, f(s0)) + F.map(runF) { rwsfa => (e: E, s0: S0) => + rwsfa(e, f(s0)) } } /** - * Modify the initial environment using `f`. - * - * {{{ - * scala> import cats.implicits._ - * scala> type Env = String - * scala> type GlobalEnv = (Int, Env) - * scala> type Log = List[String] - * scala> val xLocal: IndexedReaderWriterStateT[Option, Env, Log, Int, Int, Int] = IndexedReaderWriterStateT.get - * scala> val xGlobal: IndexedReaderWriterStateT[Option, GlobalEnv, Log, Int, Int, Int] = xLocal.local(_._2) - * scala> val globalEnv: GlobalEnv = (5, "env") - * scala> xGlobal.run(globalEnv, 5) - * res0: Option[(List[String], Int, Int)] = Some((List(),5,5)) - * }}} - */ + * Modify the initial environment using `f`. + * + * {{{ + * scala> import cats.implicits._ + * scala> type Env = String + * scala> type GlobalEnv = (Int, Env) + * scala> type Log = List[String] + * scala> val xLocal: IndexedReaderWriterStateT[Option, Env, Log, Int, Int, Int] = IndexedReaderWriterStateT.get + * scala> val xGlobal: IndexedReaderWriterStateT[Option, GlobalEnv, Log, Int, Int, Int] = xLocal.local(_._2) + * scala> val globalEnv: GlobalEnv = (5, "env") + * scala> xGlobal.run(globalEnv, 5) + * res0: Option[(List[String], Int, Int)] = Some((List(),5,5)) + * }}} + */ def local[EE](f: EE => E)(implicit F: Functor[F]): IndexedReaderWriterStateT[F, EE, L, SA, SB, A] = IndexedReaderWriterStateT.applyF { - F.map(runF) { rwsa => - (ee: EE, sa: SA) => rwsa(f(ee), sa) + F.map(runF) { rwsa => (ee: EE, sa: SA) => + rwsa(f(ee), sa) } } /** - * Modify the result of the computation using `f`. - */ + * Modify the result of the computation using `f`. + */ def map[B](f: A => B)(implicit F: Functor[F]): IndexedReaderWriterStateT[F, E, L, SA, SB, B] = - transform { (l, s, a) => (l, s, f(a)) } + transform { (l, s, a) => + (l, s, f(a)) + } /** - * Modify the context `F` using transformation `f`. - */ + * Modify the context `F` using transformation `f`. + */ def mapK[G[_]](f: F ~> G)(implicit F: Functor[F]): IndexedReaderWriterStateT[G, E, L, SA, SB, A] = - IndexedReaderWriterStateT.applyF( - f(F.map(runF)(rwsa => (e, sa) => f(rwsa(e, sa))))) + IndexedReaderWriterStateT.applyF(f(F.map(runF)(rwsa => (e, sa) => f(rwsa(e, sa))))) /** - * Modify the resulting state using `f` and the resulting value using `g`. - */ + * Modify the resulting state using `f` and the resulting value using `g`. + */ def bimap[SC, B](f: SB => SC, g: A => B)(implicit F: Functor[F]): IndexedReaderWriterStateT[F, E, L, SA, SC, B] = - transform { (l, s, a) => (l, f(s), g(a)) } + transform { (l, s, a) => + (l, f(s), g(a)) + } /** - * Modify the initial state using `f` and the resulting state using `g`. - */ + * Modify the initial state using `f` and the resulting state using `g`. + */ def dimap[S0, S1](f: S0 => SA)(g: SB => S1)(implicit F: Functor[F]): IndexedReaderWriterStateT[F, E, L, S0, S1, A] = contramap(f).modify(g) /** - * Modify the written log value using `f`. - */ + * Modify the written log value using `f`. + */ def mapWritten[LL](f: L => LL)(implicit F: Functor[F]): IndexedReaderWriterStateT[F, E, LL, SA, SB, A] = - transform { (l, s, a) => (f(l), s, a) } + transform { (l, s, a) => + (f(l), s, a) + } /** - * Modify the result of the computation by feeding it into `f`, threading the state - * through the resulting computation and combining the log values. - */ - def flatMap[SC, B](f: A => IndexedReaderWriterStateT[F, E, L, SB, SC, B])( - implicit F: FlatMap[F], L: Semigroup[L]): IndexedReaderWriterStateT[F, E, L, SA, SC, B] = + * Modify the result of the computation by feeding it into `f`, threading the state + * through the resulting computation and combining the log values. + */ + def flatMap[SC, B]( + f: A => IndexedReaderWriterStateT[F, E, L, SB, SC, B] + )(implicit F: FlatMap[F], L: Semigroup[L]): IndexedReaderWriterStateT[F, E, L, SA, SC, B] = IndexedReaderWriterStateT.applyF { - F.map(runF) { rwsfa => - (e: E, sa: SA) => - F.flatMap(rwsfa(e, sa)) { case (la, sb, a) => + F.map(runF) { rwsfa => (e: E, sa: SA) => + F.flatMap(rwsfa(e, sa)) { + case (la, sb, a) => F.flatMap(f(a).runF) { rwsfb => - F.map(rwsfb(e, sb)) { case (lb, sc, b) => - (L.combine(la, lb), sc, b) + F.map(rwsfb(e, sb)) { + case (lb, sc, b) => + (L.combine(la, lb), sc, b) } } - } + } } } /** - * Like [[map]], but allows the mapping function to return an effectful value. - */ + * Like [[map]], but allows the mapping function to return an effectful value. + */ def flatMapF[B](faf: A => F[B])(implicit F: FlatMap[F]): IndexedReaderWriterStateT[F, E, L, SA, SB, B] = IndexedReaderWriterStateT.applyF { - F.map(runF) { rwsfa => - (e: E, sa: SA) => - F.flatMap(rwsfa(e, sa)) { case (l, sb, a) => + F.map(runF) { rwsfa => (e: E, sa: SA) => + F.flatMap(rwsfa(e, sa)) { + case (l, sb, a) => F.map(faf(a))((l, sb, _)) - } + } } } /** - * Transform the resulting log, state and value using `f`. - */ - def transform[LL, SC, B](f: (L, SB, A) => (LL, SC, B))(implicit F: Functor[F]): IndexedReaderWriterStateT[F, E, LL, SA, SC, B] = + * Transform the resulting log, state and value using `f`. + */ + def transform[LL, SC, B]( + f: (L, SB, A) => (LL, SC, B) + )(implicit F: Functor[F]): IndexedReaderWriterStateT[F, E, LL, SA, SC, B] = IndexedReaderWriterStateT.applyF { - F.map(runF) { rwsfa => - (e: E, s: SA) => F.map(rwsfa(e, s)) { case (l, sb, a) => - val (ll, sc, b) = f(l, sb, a) - (ll, sc, b) + F.map(runF) { rwsfa => (e: E, s: SA) => + F.map(rwsfa(e, s)) { + case (l, sb, a) => + val (ll, sc, b) = f(l, sb, a) + (ll, sc, b) } } } /** - * Like [[transform]], but allows the context to change from `F` to `G`. - * - * {{{ - * scala> import cats.implicits._ - * scala> type ErrorOr[A] = Either[String, A] - * scala> type Env = String - * scala> type Log = List[String] - * scala> val xError: IndexedReaderWriterStateT[ErrorOr, Env, Log, Int, Int, Int] = IndexedReaderWriterStateT.get - * scala> val xOpt: IndexedReaderWriterStateT[Option, Env, Log, Int, Int, Int] = xError.transformF(_.toOption) - * scala> val input = 5 - * scala> xError.run("env", input) - * res0: ErrorOr[(Log, Int, Int)] = Right((List(),5,5)) - * scala> xOpt.run("env", 5) - * res1: Option[(Log, Int, Int)] = Some((List(),5,5)) - * }}} - */ - def transformF[G[_], LL, SC, B](f: F[(L, SB, A)] => G[(LL, SC, B)])( - implicit F: Monad[F], G: Applicative[G]): IndexedReaderWriterStateT[G, E, LL, SA, SC, B] = + * Like [[transform]], but allows the context to change from `F` to `G`. + * + * {{{ + * scala> import cats.implicits._ + * scala> type ErrorOr[A] = Either[String, A] + * scala> type Env = String + * scala> type Log = List[String] + * scala> val xError: IndexedReaderWriterStateT[ErrorOr, Env, Log, Int, Int, Int] = IndexedReaderWriterStateT.get + * scala> val xOpt: IndexedReaderWriterStateT[Option, Env, Log, Int, Int, Int] = xError.transformF(_.toOption) + * scala> val input = 5 + * scala> xError.run("env", input) + * res0: ErrorOr[(Log, Int, Int)] = Right((List(),5,5)) + * scala> xOpt.run("env", 5) + * res1: Option[(Log, Int, Int)] = Some((List(),5,5)) + * }}} + */ + def transformF[G[_], LL, SC, B]( + f: F[(L, SB, A)] => G[(LL, SC, B)] + )(implicit F: Monad[F], G: Applicative[G]): IndexedReaderWriterStateT[G, E, LL, SA, SC, B] = IndexedReaderWriterStateT.apply((e, s) => f(run(e, s))) /** - * Transform the state used. See [[StateT]] for more details. - * - * {{{ - * scala> import cats.implicits._ // needed for StateT.apply - * scala> type Env = String - * scala> type Log = List[String] - * scala> type S[SA, SB, A] = IndexedReaderWriterStateT[Option, Env, Log, SA, SB, A] - * scala> type GlobalEnv = (Int, String) - * scala> val x: S[Int, Int, Double] = IndexedReaderWriterStateT((env: Env, x: Int) => Option(("Addition" :: Nil, x + 1, x.toDouble))) - * scala> val xt: S[GlobalEnv, GlobalEnv, Double] = x.transformS[GlobalEnv](_._1, (t, i) => (i, t._2)) - * scala> val input = 5 - * scala> x.run("env", input) - * res0: Option[(Log, Int, Double)] = Some((List(Addition),6,5.0)) - * scala> xt.run("env", (input, "hello")) - * res1: Option[(Log, GlobalEnv, Double)] = Some((List(Addition),(6,hello),5.0)) - * }}} - */ + * Transform the state used. See [[StateT]] for more details. + * + * {{{ + * scala> import cats.implicits._ // needed for StateT.apply + * scala> type Env = String + * scala> type Log = List[String] + * scala> type S[SA, SB, A] = IndexedReaderWriterStateT[Option, Env, Log, SA, SB, A] + * scala> type GlobalEnv = (Int, String) + * scala> val x: S[Int, Int, Double] = IndexedReaderWriterStateT((env: Env, x: Int) => Option(("Addition" :: Nil, x + 1, x.toDouble))) + * scala> val xt: S[GlobalEnv, GlobalEnv, Double] = x.transformS[GlobalEnv](_._1, (t, i) => (i, t._2)) + * scala> val input = 5 + * scala> x.run("env", input) + * res0: Option[(Log, Int, Double)] = Some((List(Addition),6,5.0)) + * scala> xt.run("env", (input, "hello")) + * res1: Option[(Log, GlobalEnv, Double)] = Some((List(Addition),(6,hello),5.0)) + * }}} + */ def transformS[R](f: R => SA, g: (R, SB) => R)(implicit F: Functor[F]): IndexedReaderWriterStateT[F, E, L, R, R, A] = IndexedReaderWriterStateT.applyF { - F.map(runF) { rwsfa => - (e: E, r: R) => F.map(rwsfa(e, f(r))) { case (l, sb, a) => - (l, g(r, sb), a) + F.map(runF) { rwsfa => (e: E, r: R) => + F.map(rwsfa(e, f(r))) { + case (l, sb, a) => + (l, g(r, sb), a) } } } - /** - * Modify the resulting state. - */ + * Modify the resulting state. + */ def modify[SC](f: SB => SC)(implicit F: Functor[F]): IndexedReaderWriterStateT[F, E, L, SA, SC, A] = - transform { (l, sb, a) => (l, f(sb), a) } + transform { (l, sb, a) => + (l, f(sb), a) + } /** - * Inspect a value from the input state, without modifying the state. - */ + * Inspect a value from the input state, without modifying the state. + */ def inspect[B](f: SB => B)(implicit F: Functor[F]): IndexedReaderWriterStateT[F, E, L, SA, SB, B] = - transform { (l, sb, a) => (l, sb, f(sb)) } + transform { (l, sb, a) => + (l, sb, f(sb)) + } /** - * Get the input state, without modifying it. - */ + * Get the input state, without modifying it. + */ def get(implicit F: Functor[F]): IndexedReaderWriterStateT[F, E, L, SA, SB, SB] = inspect(identity) /** - * Add a value to the log. - */ + * Add a value to the log. + */ def tell(l: L)(implicit F: Functor[F], L: Semigroup[L]): IndexedReaderWriterStateT[F, E, L, SA, SB, A] = mapWritten(L.combine(_, l)) /** - * Retrieve the value written to the log. - */ + * Retrieve the value written to the log. + */ def written(implicit F: Functor[F]): IndexedReaderWriterStateT[F, E, L, SA, SB, L] = - transform { (l, sb, a) => (l, sb, l) } + transform { (l, sb, a) => + (l, sb, l) + } /** - * Clear the log. - */ + * Clear the log. + */ def reset(implicit F: Functor[F], L: Monoid[L]): IndexedReaderWriterStateT[F, E, L, SA, SB, A] = mapWritten(_ => L.empty) /** - * Run the computation using the provided initial environment and state. - */ + * Run the computation using the provided initial environment and state. + */ def run(env: E, initial: SA)(implicit F: Monad[F]): F[(L, SB, A)] = F.flatMap(runF)(_.apply(env, initial)) /** - * Run the computation using the provided environment and an empty state. - */ + * Run the computation using the provided environment and an empty state. + */ def runEmpty(env: E)(implicit F: Monad[F], SA: Monoid[SA]): F[(L, SB, A)] = run(env, SA.empty) /** - * Like [[run]], but discards the final state and log. - */ + * Like [[run]], but discards the final state and log. + */ def runA(env: E, initial: SA)(implicit F: Monad[F]): F[A] = F.map(run(env, initial))(_._3) /** - * Like [[run]], but discards the final value and log. - */ + * Like [[run]], but discards the final value and log. + */ def runS(env: E, initial: SA)(implicit F: Monad[F]): F[SB] = F.map(run(env, initial))(_._2) /** - * Like [[run]], but discards the final state and value. - */ + * Like [[run]], but discards the final state and value. + */ def runL(env: E, initial: SA)(implicit F: Monad[F]): F[L] = F.map(run(env, initial))(_._1) /** - * Like [[runEmpty]], but discards the final state and log. - */ + * Like [[runEmpty]], but discards the final state and log. + */ def runEmptyA(env: E)(implicit F: Monad[F], SA: Monoid[SA]): F[A] = runA(env, SA.empty) /** - * Like [[runEmpty]], but discards the final value and log. - */ + * Like [[runEmpty]], but discards the final value and log. + */ def runEmptyS(env: E)(implicit F: Monad[F], SA: Monoid[SA]): F[SB] = runS(env, SA.empty) /** - * Like [[runEmpty]], but discards the final state and value. - */ + * Like [[runEmpty]], but discards the final state and value. + */ def runEmptyL(env: E)(implicit F: Monad[F], SA: Monoid[SA]): F[L] = runL(env, SA.empty) } -private[data] sealed trait CommonIRWSTConstructors { +sealed private[data] trait CommonIRWSTConstructors { + /** - * Return `a` and an empty log without modifying the input state. - */ - def pure[F[_], E, L, S, A](a: A)(implicit F: Applicative[F], L: Monoid[L]): IndexedReaderWriterStateT[F, E, L, S, S, A] = + * Return `a` and an empty log without modifying the input state. + */ + def pure[F[_], E, L, S, A](a: A)(implicit F: Applicative[F], + L: Monoid[L]): IndexedReaderWriterStateT[F, E, L, S, S, A] = IndexedReaderWriterStateT((_, s) => F.pure((L.empty, s, a))) /** - * Return an effectful `a` and an empty log without modifying the input state. - */ - def liftF[F[_], E, L, S, A](fa: F[A])(implicit F: Applicative[F], L: Monoid[L]): IndexedReaderWriterStateT[F, E, L, S, S, A] = + * Return an effectful `a` and an empty log without modifying the input state. + */ + def liftF[F[_], E, L, S, A](fa: F[A])(implicit F: Applicative[F], + L: Monoid[L]): IndexedReaderWriterStateT[F, E, L, S, S, A] = IndexedReaderWriterStateT((_, s) => F.map(fa)((L.empty, s, _))) /** - * Same as [[liftF]], but expressed as a FunctionK for use with mapK - * {{{ - * scala> import cats._, data._, implicits._ - * scala> val a: OptionT[Eval, Int] = 1.pure[OptionT[Eval, ?]] - * scala> val b: OptionT[RWST[Eval, Boolean, List[String], String, ?], Int] = a.mapK(RWST.liftK) - * scala> b.value.runEmpty(true).value - * res0: (List[String], String, Option[Int]) = (List(),"",Some(1)) - * }}} - */ + * Same as [[liftF]], but expressed as a FunctionK for use with mapK + * {{{ + * scala> import cats._, data._, implicits._ + * scala> val a: OptionT[Eval, Int] = 1.pure[OptionT[Eval, ?]] + * scala> val b: OptionT[RWST[Eval, Boolean, List[String], String, ?], Int] = a.mapK(RWST.liftK) + * scala> b.value.runEmpty(true).value + * res0: (List[String], String, Option[Int]) = (List(),"",Some(1)) + * }}} + */ def liftK[F[_], E, L, S](implicit F: Applicative[F], L: Monoid[L]): F ~> IndexedReaderWriterStateT[F, E, L, S, S, ?] = λ[F ~> IndexedReaderWriterStateT[F, E, L, S, S, ?]](IndexedReaderWriterStateT.liftF(_)) @deprecated("Use liftF instead", "1.0.0-RC2") - def lift[F[_], E, L, S, A](fa: F[A])(implicit F: Applicative[F], L: Monoid[L]): IndexedReaderWriterStateT[F, E, L, S, S, A] = + def lift[F[_], E, L, S, A](fa: F[A])(implicit F: Applicative[F], + L: Monoid[L]): IndexedReaderWriterStateT[F, E, L, S, S, A] = IndexedReaderWriterStateT((_, s) => F.map(fa)((L.empty, s, _))) /** - * Inspect a value from the input state, without modifying the state. - */ - def inspect[F[_], E, L, S, A](f: S => A)(implicit F: Applicative[F], L: Monoid[L]): IndexedReaderWriterStateT[F, E, L, S, S, A] = + * Inspect a value from the input state, without modifying the state. + */ + def inspect[F[_], E, L, S, A](f: S => A)(implicit F: Applicative[F], + L: Monoid[L]): IndexedReaderWriterStateT[F, E, L, S, S, A] = IndexedReaderWriterStateT((_, s) => F.pure((L.empty, s, f(s)))) /** - * Like [[inspect]], but using an effectful function. - */ - def inspectF[F[_], E, L, S, A](f: S => F[A])(implicit F: Applicative[F], L: Monoid[L]): IndexedReaderWriterStateT[F, E, L, S, S, A] = + * Like [[inspect]], but using an effectful function. + */ + def inspectF[F[_], E, L, S, A](f: S => F[A])(implicit F: Applicative[F], + L: Monoid[L]): IndexedReaderWriterStateT[F, E, L, S, S, A] = IndexedReaderWriterStateT((_, s) => F.map(f(s))((L.empty, s, _))) /** - * Set the state to `s`. - */ - def set[F[_], E, L, S](s: S)(implicit F: Applicative[F], L: Monoid[L]): IndexedReaderWriterStateT[F, E, L, S, S, Unit] = + * Set the state to `s`. + */ + def set[F[_], E, L, S](s: S)(implicit F: Applicative[F], + L: Monoid[L]): IndexedReaderWriterStateT[F, E, L, S, S, Unit] = IndexedReaderWriterStateT((_, _) => F.pure((L.empty, s, ()))) /** - * Like [[set]], but using an effectful `S` value. - */ - def setF[F[_], E, L, S](fs: F[S])(implicit F: Applicative[F], L: Monoid[L]): IndexedReaderWriterStateT[F, E, L, S, S, Unit] = + * Like [[set]], but using an effectful `S` value. + */ + def setF[F[_], E, L, S](fs: F[S])(implicit F: Applicative[F], + L: Monoid[L]): IndexedReaderWriterStateT[F, E, L, S, S, Unit] = IndexedReaderWriterStateT((_, _) => F.map(fs)((L.empty, _, ()))) /** - * Get the provided environment, without modifying the input state. - */ + * Get the provided environment, without modifying the input state. + */ def ask[F[_], E, L, S](implicit F: Applicative[F], L: Monoid[L]): IndexedReaderWriterStateT[F, E, L, S, S, E] = IndexedReaderWriterStateT((e, s) => F.pure((L.empty, s, e))) /** - * Add a value to the log, without modifying the input state. - */ + * Add a value to the log, without modifying the input state. + */ def tell[F[_], E, L, S](l: L)(implicit F: Applicative[F]): IndexedReaderWriterStateT[F, E, L, S, S, Unit] = IndexedReaderWriterStateT((_, s) => F.pure((l, s, ()))) /** - * Like [[tell]], but using an effectful `L` value. - */ + * Like [[tell]], but using an effectful `L` value. + */ def tellF[F[_], E, L, S](fl: F[L])(implicit F: Applicative[F]): IndexedReaderWriterStateT[F, E, L, S, S, Unit] = IndexedReaderWriterStateT((_, s) => F.map(fl)((_, s, ()))) /** - * Return the input state without modifying it. - */ + * Return the input state without modifying it. + */ def get[F[_], E, L, S](implicit F: Applicative[F], L: Monoid[L]): IndexedReaderWriterStateT[F, E, L, S, S, S] = IndexedReaderWriterStateT((_, s) => F.pure((L.empty, s, s))) } object IndexedReaderWriterStateT extends IRWSTInstances with CommonIRWSTConstructors { + /** - * Construct a new computation using the provided function. - */ - def apply[F[_], E, L, SA, SB, A](runF: (E, SA) => F[(L, SB, A)])(implicit F: Applicative[F]): IndexedReaderWriterStateT[F, E, L, SA, SB, A] = + * Construct a new computation using the provided function. + */ + def apply[F[_], E, L, SA, SB, A]( + runF: (E, SA) => F[(L, SB, A)] + )(implicit F: Applicative[F]): IndexedReaderWriterStateT[F, E, L, SA, SB, A] = new IndexedReaderWriterStateT(F.pure(runF)) /** - * Like [[apply]], but using a function in a context `F`. - */ + * Like [[apply]], but using a function in a context `F`. + */ def applyF[F[_], E, L, SA, SB, A](runF: F[(E, SA) => F[(L, SB, A)]]): IndexedReaderWriterStateT[F, E, L, SA, SB, A] = new IndexedReaderWriterStateT(runF) /** - * Modify the input state using `f`. - */ - def modify[F[_], E, L, SA, SB](f: SA => SB)(implicit F: Applicative[F], L: Monoid[L]): IndexedReaderWriterStateT[F, E, L, SA, SB, Unit] = + * Modify the input state using `f`. + */ + def modify[F[_], E, L, SA, SB](f: SA => SB)(implicit F: Applicative[F], + L: Monoid[L]): IndexedReaderWriterStateT[F, E, L, SA, SB, Unit] = IndexedReaderWriterStateT((_, s) => F.pure((L.empty, f(s), ()))) /** - * Like [[modify]], but using an effectful function. - */ - def modifyF[F[_], E, L, SA, SB](f: SA => F[SB])(implicit F: Applicative[F], L: Monoid[L]): IndexedReaderWriterStateT[F, E, L, SA, SB, Unit] = + * Like [[modify]], but using an effectful function. + */ + def modifyF[F[_], E, L, SA, SB](f: SA => F[SB])(implicit F: Applicative[F], + L: Monoid[L]): IndexedReaderWriterStateT[F, E, L, SA, SB, Unit] = IndexedReaderWriterStateT((_, s) => F.map(f(s))((L.empty, _, ()))) } -private[data] abstract class RWSTFunctions extends CommonIRWSTConstructors { +abstract private[data] class RWSTFunctions extends CommonIRWSTConstructors { + /** - * Construct a new computation using the provided function. - */ - def apply[F[_], E, L, S, A](runF: (E, S) => F[(L, S, A)])(implicit F: Applicative[F]): ReaderWriterStateT[F, E, L, S, A] = + * Construct a new computation using the provided function. + */ + def apply[F[_], E, L, S, A]( + runF: (E, S) => F[(L, S, A)] + )(implicit F: Applicative[F]): ReaderWriterStateT[F, E, L, S, A] = new IndexedReaderWriterStateT(F.pure(runF)) /** - * Like [[apply]], but using a function in a context `F`. - */ + * Like [[apply]], but using a function in a context `F`. + */ def applyF[F[_], E, L, S, A](runF: F[(E, S) => F[(L, S, A)]]): ReaderWriterStateT[F, E, L, S, A] = new IndexedReaderWriterStateT(runF) /** - * Modify the input state using `f`. - */ + * Modify the input state using `f`. + */ def modify[F[_], E, L, S](f: S => S)(implicit F: Applicative[F], L: Monoid[L]): ReaderWriterStateT[F, E, L, S, Unit] = ReaderWriterStateT((_, s) => F.pure((L.empty, f(s), ()))) /** - * Like [[modify]], but using an effectful function. - */ - def modifyF[F[_], E, L, S](f: S => F[S])(implicit F: Applicative[F], L: Monoid[L]): ReaderWriterStateT[F, E, L, S, Unit] = + * Like [[modify]], but using an effectful function. + */ + def modifyF[F[_], E, L, S](f: S => F[S])(implicit F: Applicative[F], + L: Monoid[L]): ReaderWriterStateT[F, E, L, S, Unit] = ReaderWriterStateT((_, s) => F.map(f(s))((L.empty, _, ()))) } /** - * Convenience functions for ReaderWriterState. - */ -private[data] abstract class RWSFunctions { + * Convenience functions for ReaderWriterState. + */ +abstract private[data] class RWSFunctions { + /** - * Return `a` and an empty log without modifying the input state. - */ + * Return `a` and an empty log without modifying the input state. + */ def apply[E, L: Monoid, S, A](f: (E, S) => (L, S, A)): ReaderWriterState[E, L, S, A] = ReaderWriterStateT.applyF(Now((e, s) => Now(f(e, s)))) /** - * Return `a` and an empty log without modifying the input state. - */ + * Return `a` and an empty log without modifying the input state. + */ def pure[E, L: Monoid, S, A](a: A): ReaderWriterState[E, L, S, A] = ReaderWriterStateT.pure(a) /** - * Modify the input state using `f`. - */ + * Modify the input state using `f`. + */ def modify[E, L: Monoid, S](f: S => S): ReaderWriterState[E, L, S, Unit] = ReaderWriterStateT.modify(f) /** - * Inspect a value from the input state, without modifying the state. - */ + * Inspect a value from the input state, without modifying the state. + */ def inspect[E, L: Monoid, S, T](f: S => T): ReaderWriterState[E, L, S, T] = ReaderWriterStateT.inspect(f) /** - * Return the input state without modifying it. - */ + * Return the input state without modifying it. + */ def get[E, L: Monoid, S]: ReaderWriterState[E, L, S, S] = ReaderWriterStateT.get /** - * Set the state to `s`. - */ + * Set the state to `s`. + */ def set[E, L: Monoid, S](s: S): ReaderWriterState[E, L, S, Unit] = ReaderWriterStateT.set(s) /** - * Get the provided environment, without modifying the input state. - */ + * Get the provided environment, without modifying the input state. + */ def ask[E, L, S](implicit L: Monoid[L]): ReaderWriterState[E, L, S, E] = ReaderWriterStateT.ask /** - * Add a value to the log, without modifying the input state. - */ + * Add a value to the log, without modifying the input state. + */ def tell[E, L, S](l: L): ReaderWriterState[E, L, S, Unit] = ReaderWriterStateT.tell(l) } -private[data] sealed abstract class IRWSTInstances extends IRWSTInstances1 { +sealed abstract private[data] class IRWSTInstances extends IRWSTInstances1 { - implicit def catsDataStrongForIRWST[F[_], E, L, T](implicit F0: Monad[F]): Strong[IndexedReaderWriterStateT[F, E, L, ?, ?, T]] = + implicit def catsDataStrongForIRWST[F[_], E, L, T]( + implicit F0: Monad[F] + ): Strong[IndexedReaderWriterStateT[F, E, L, ?, ?, T]] = new IRWSTStrong[F, E, L, T] { implicit def F: Monad[F] = F0 } - implicit def catsDataBifunctorForIRWST[F[_], E, L, SA](implicit F0: Functor[F]): Bifunctor[IndexedReaderWriterStateT[F, E, L, SA, ?, ?]] = + implicit def catsDataBifunctorForIRWST[F[_], E, L, SA]( + implicit F0: Functor[F] + ): Bifunctor[IndexedReaderWriterStateT[F, E, L, SA, ?, ?]] = new IRWSTBifunctor[F, E, L, SA] { implicit def F: Functor[F] = F0 } - implicit def catsDataContravariantForIRWST[F[_], E, L, SB, T](implicit F0: Functor[F]): Contravariant[IndexedReaderWriterStateT[F, E, L, ?, SB, T]] = + implicit def catsDataContravariantForIRWST[F[_], E, L, SB, T]( + implicit F0: Functor[F] + ): Contravariant[IndexedReaderWriterStateT[F, E, L, ?, SB, T]] = new IRWSTContravariant[F, E, L, SB, T] { implicit def F: Functor[F] = F0 } - implicit def catsDataMonadErrorForIRWST[F[_], E, L, S, R](implicit F0: MonadError[F, R], L0: Monoid[L]): MonadError[IndexedReaderWriterStateT[F, E, L, S, S, ?], R] = + implicit def catsDataMonadErrorForIRWST[F[_], E, L, S, R]( + implicit F0: MonadError[F, R], + L0: Monoid[L] + ): MonadError[IndexedReaderWriterStateT[F, E, L, S, S, ?], R] = new RWSTMonadError[F, E, L, S, R] { implicit def F: MonadError[F, R] = F0 implicit def L: Monoid[L] = L0 } - implicit def catsDataDeferForIRWST[F[_], E, L, SA, SB](implicit F: Defer[F]): Defer[IndexedReaderWriterStateT[F, E, L, SA, SB, ?]] = + implicit def catsDataDeferForIRWST[F[_], E, L, SA, SB]( + implicit F: Defer[F] + ): Defer[IndexedReaderWriterStateT[F, E, L, SA, SB, ?]] = new Defer[IndexedReaderWriterStateT[F, E, L, SA, SB, ?]] { - def defer[A](fa: => IndexedReaderWriterStateT[F, E, L, SA, SB, A]): IndexedReaderWriterStateT[F, E, L, SA, SB, A] = + def defer[A]( + fa: => IndexedReaderWriterStateT[F, E, L, SA, SB, A] + ): IndexedReaderWriterStateT[F, E, L, SA, SB, A] = IndexedReaderWriterStateT.applyF(F.defer(fa.runF)) } } -private[data] sealed abstract class IRWSTInstances1 extends IRWSTInstances2 { - implicit def catsDataMonadForRWST[F[_], E, L, S](implicit F0: Monad[F], L0: Monoid[L]): Monad[ReaderWriterStateT[F, E, L, S, ?]] = +sealed abstract private[data] class IRWSTInstances1 extends IRWSTInstances2 { + implicit def catsDataMonadForRWST[F[_], E, L, S](implicit F0: Monad[F], + L0: Monoid[L]): Monad[ReaderWriterStateT[F, E, L, S, ?]] = new RWSTMonad[F, E, L, S] { implicit def F: Monad[F] = F0 implicit def L: Monoid[L] = L0 } - implicit def catsDataProfunctorForIRWST[F[_], E, L, T](implicit F0: Functor[F]): Profunctor[IndexedReaderWriterStateT[F, E, L, ?, ?, T]] = + implicit def catsDataProfunctorForIRWST[F[_], E, L, T]( + implicit F0: Functor[F] + ): Profunctor[IndexedReaderWriterStateT[F, E, L, ?, ?, T]] = new IRWSTProfunctor[F, E, L, T] { implicit def F: Functor[F] = F0 } } -private[data] sealed abstract class IRWSTInstances2 extends IRWSTInstances3 { - implicit def catsDataAlternativeForIRWST[F[_], E, L, S](implicit FM: Monad[F], FA: Alternative[F], - L0: Monoid[L]): Alternative[IndexedReaderWriterStateT[F, E, L, S, S, ?]] = +sealed abstract private[data] class IRWSTInstances2 extends IRWSTInstances3 { + implicit def catsDataAlternativeForIRWST[F[_], E, L, S]( + implicit FM: Monad[F], + FA: Alternative[F], + L0: Monoid[L] + ): Alternative[IndexedReaderWriterStateT[F, E, L, S, S, ?]] = new RWSTAlternative[F, E, L, S] { implicit def G: Alternative[F] = FA implicit def F: Monad[F] = FM @@ -495,94 +550,131 @@ private[data] sealed abstract class IRWSTInstances2 extends IRWSTInstances3 { } } -private[data] sealed abstract class IRWSTInstances3 { - implicit def catsDataSemigroupKForIRWST[F[_], E, L, SA, SB](implicit F0: Monad[F], - G0: SemigroupK[F]): SemigroupK[IndexedReaderWriterStateT[F, E, L, SA, SB, ?]] = +sealed abstract private[data] class IRWSTInstances3 { + implicit def catsDataSemigroupKForIRWST[F[_], E, L, SA, SB]( + implicit F0: Monad[F], + G0: SemigroupK[F] + ): SemigroupK[IndexedReaderWriterStateT[F, E, L, SA, SB, ?]] = new IRWSTSemigroupK[F, E, L, SA, SB] { implicit def F: Monad[F] = F0 implicit def G: SemigroupK[F] = G0 } - implicit def catsDataFunctorForIRWST[F[_], E, L, SA, SB](implicit F0: Functor[F]): Functor[IndexedReaderWriterStateT[F, E, L, SA, SB, ?]] = + implicit def catsDataFunctorForIRWST[F[_], E, L, SA, SB]( + implicit F0: Functor[F] + ): Functor[IndexedReaderWriterStateT[F, E, L, SA, SB, ?]] = new IRWSTFunctor[F, E, L, SA, SB] { implicit def F: Functor[F] = F0 } } -private[data] sealed abstract class IRWSTFunctor[F[_], E, L, SA, SB] extends Functor[IndexedReaderWriterStateT[F, E, L, SA, SB, ?]] { +sealed abstract private[data] class IRWSTFunctor[F[_], E, L, SA, SB] + extends Functor[IndexedReaderWriterStateT[F, E, L, SA, SB, ?]] { implicit def F: Functor[F] - override def map[A, B](fa: IndexedReaderWriterStateT[F, E, L, SA, SB, A])(f: A => B): IndexedReaderWriterStateT[F, E, L, SA, SB, B] = + override def map[A, B]( + fa: IndexedReaderWriterStateT[F, E, L, SA, SB, A] + )(f: A => B): IndexedReaderWriterStateT[F, E, L, SA, SB, B] = fa.map(f) } -private[data] sealed abstract class IRWSTContravariant[F[_], E, L, SB, T] extends Contravariant[IndexedReaderWriterStateT[F, E, L, ?, SB, T]] { +sealed abstract private[data] class IRWSTContravariant[F[_], E, L, SB, T] + extends Contravariant[IndexedReaderWriterStateT[F, E, L, ?, SB, T]] { implicit def F: Functor[F] - override def contramap[A, B](fa: IndexedReaderWriterStateT[F, E, L, A, SB, T])(f: B => A): IndexedReaderWriterStateT[F, E, L, B, SB, T] = + override def contramap[A, B]( + fa: IndexedReaderWriterStateT[F, E, L, A, SB, T] + )(f: B => A): IndexedReaderWriterStateT[F, E, L, B, SB, T] = fa.contramap(f) } -private[data] sealed abstract class IRWSTProfunctor[F[_], E, L, T] extends Profunctor[IndexedReaderWriterStateT[F, E, L, ?, ?, T]] { +sealed abstract private[data] class IRWSTProfunctor[F[_], E, L, T] + extends Profunctor[IndexedReaderWriterStateT[F, E, L, ?, ?, T]] { implicit def F: Functor[F] - override def dimap[A, B, C, D](fab: IndexedReaderWriterStateT[F, E, L, A, B, T])(f: C => A)(g: B => D): IndexedReaderWriterStateT[F, E, L, C, D, T] = + override def dimap[A, B, C, D]( + fab: IndexedReaderWriterStateT[F, E, L, A, B, T] + )(f: C => A)(g: B => D): IndexedReaderWriterStateT[F, E, L, C, D, T] = fab.dimap(f)(g) } -private[data] sealed abstract class IRWSTStrong[F[_], E, L, T] extends IRWSTProfunctor[F, E, L, T] with Strong[IndexedReaderWriterStateT[F, E, L, ?, ?, T]] { +sealed abstract private[data] class IRWSTStrong[F[_], E, L, T] + extends IRWSTProfunctor[F, E, L, T] + with Strong[IndexedReaderWriterStateT[F, E, L, ?, ?, T]] { implicit def F: Monad[F] - def first[A, B, C](fa: IndexedReaderWriterStateT[F, E, L, A, B, T]): IndexedReaderWriterStateT[F, E, L, (A, C), (B, C), T] = - IndexedReaderWriterStateT { case (e, (a, c)) => - F.map(fa.run(e, a)) { case (l, b, t) => - (l, (b, c), t) - } + def first[A, B, C]( + fa: IndexedReaderWriterStateT[F, E, L, A, B, T] + ): IndexedReaderWriterStateT[F, E, L, (A, C), (B, C), T] = + IndexedReaderWriterStateT { + case (e, (a, c)) => + F.map(fa.run(e, a)) { + case (l, b, t) => + (l, (b, c), t) + } } - def second[A, B, C](fa: IndexedReaderWriterStateT[F, E, L, A, B, T]): IndexedReaderWriterStateT[F, E, L, (C, A), (C, B), T] = + def second[A, B, C]( + fa: IndexedReaderWriterStateT[F, E, L, A, B, T] + ): IndexedReaderWriterStateT[F, E, L, (C, A), (C, B), T] = first(fa).dimap((_: (C, A)).swap)(_.swap) } -private[data] sealed abstract class IRWSTBifunctor[F[_], E, L, SA] extends Bifunctor[IndexedReaderWriterStateT[F, E, L, SA, ?, ?]] { +sealed abstract private[data] class IRWSTBifunctor[F[_], E, L, SA] + extends Bifunctor[IndexedReaderWriterStateT[F, E, L, SA, ?, ?]] { implicit def F: Functor[F] - override def bimap[A, B, C, D](fab: IndexedReaderWriterStateT[F, E, L, SA, A, B])(f: A => C, g: B => D): IndexedReaderWriterStateT[F, E, L, SA, C, D] = + override def bimap[A, B, C, D]( + fab: IndexedReaderWriterStateT[F, E, L, SA, A, B] + )(f: A => C, g: B => D): IndexedReaderWriterStateT[F, E, L, SA, C, D] = fab.bimap(f, g) } -private[data] sealed abstract class RWSTMonad[F[_], E, L, S] extends IRWSTFunctor[F, E, L, S, S] with Monad[ReaderWriterStateT[F, E, L, S, ?]] { +sealed abstract private[data] class RWSTMonad[F[_], E, L, S] + extends IRWSTFunctor[F, E, L, S, S] + with Monad[ReaderWriterStateT[F, E, L, S, ?]] { implicit def F: Monad[F] implicit def L: Monoid[L] def pure[A](a: A): ReaderWriterStateT[F, E, L, S, A] = ReaderWriterStateT.pure(a) - def flatMap[A, B](fa: ReaderWriterStateT[F, E, L, S, A])(f: A => ReaderWriterStateT[F, E, L, S, B]): ReaderWriterStateT[F, E, L, S, B] = + def flatMap[A, B]( + fa: ReaderWriterStateT[F, E, L, S, A] + )(f: A => ReaderWriterStateT[F, E, L, S, B]): ReaderWriterStateT[F, E, L, S, B] = fa.flatMap(f) - def tailRecM[A, B](initA: A)(f: A => ReaderWriterStateT[F, E, L, S, Either[A, B]]): ReaderWriterStateT[F, E, L, S, B] = + def tailRecM[A, B]( + initA: A + )(f: A => ReaderWriterStateT[F, E, L, S, Either[A, B]]): ReaderWriterStateT[F, E, L, S, B] = ReaderWriterStateT { (e, initS) => - F.tailRecM((L.empty, initS, initA)) { case (currL, currS, currA) => - F.map(f(currA).run(e, currS)) { case (nextL, nextS, ab) => - ab.bimap((L.combine(currL, nextL), nextS, _), (L.combine(currL, nextL), nextS, _)) - } + F.tailRecM((L.empty, initS, initA)) { + case (currL, currS, currA) => + F.map(f(currA).run(e, currS)) { + case (nextL, nextS, ab) => + ab.bimap((L.combine(currL, nextL), nextS, _), (L.combine(currL, nextL), nextS, _)) + } } } } -private[data] sealed abstract class IRWSTSemigroupK[F[_], E, L, SA, SB] extends IRWSTSemigroupK1[F, E, L, SA, SB] +sealed abstract private[data] class IRWSTSemigroupK[F[_], E, L, SA, SB] extends IRWSTSemigroupK1[F, E, L, SA, SB] -private[data] sealed abstract class RWSTAlternative[F[_], E, L, S] extends IRWSTFunctor[F, E, L, S, S] with RWSTAlternative1[F, E, L, S] +sealed abstract private[data] class RWSTAlternative[F[_], E, L, S] + extends IRWSTFunctor[F, E, L, S, S] + with RWSTAlternative1[F, E, L, S] -private[data] sealed abstract class RWSTMonadError[F[_], E, L, S, R] - extends RWSTMonad[F, E, L, S] with MonadError[ReaderWriterStateT[F, E, L, S, ?], R] { +sealed abstract private[data] class RWSTMonadError[F[_], E, L, S, R] + extends RWSTMonad[F, E, L, S] + with MonadError[ReaderWriterStateT[F, E, L, S, ?], R] { implicit def F: MonadError[F, R] def raiseError[A](r: R): ReaderWriterStateT[F, E, L, S, A] = ReaderWriterStateT.liftF(F.raiseError(r)) - def handleErrorWith[A](fa: ReaderWriterStateT[F, E, L, S, A])(f: R => ReaderWriterStateT[F, E, L, S, A]): ReaderWriterStateT[F, E, L, S, A] = + def handleErrorWith[A]( + fa: ReaderWriterStateT[F, E, L, S, A] + )(f: R => ReaderWriterStateT[F, E, L, S, A]): ReaderWriterStateT[F, E, L, S, A] = ReaderWriterStateT { (e, s) => F.handleErrorWith(fa.run(e, s))(r => f(r).run(e, s)) } @@ -593,13 +685,15 @@ private trait IRWSTSemigroupK1[F[_], E, L, SA, SB] extends SemigroupK[IndexedRea implicit def G: SemigroupK[F] def combineK[A](x: IndexedReaderWriterStateT[F, E, L, SA, SB, A], - y: IndexedReaderWriterStateT[F, E, L, SA, SB, A]): IndexedReaderWriterStateT[F, E, L, SA, SB, A] = + y: IndexedReaderWriterStateT[F, E, L, SA, SB, A]): IndexedReaderWriterStateT[F, E, L, SA, SB, A] = IndexedReaderWriterStateT { (e, sa) => G.combineK(x.run(e, sa), y.run(e, sa)) } } -private trait RWSTAlternative1[F[_], E, L, S] extends IRWSTSemigroupK1[F, E, L, S, S] with Alternative[ReaderWriterStateT[F, E, L, S, ?]] { +private trait RWSTAlternative1[F[_], E, L, S] + extends IRWSTSemigroupK1[F, E, L, S, S] + with Alternative[ReaderWriterStateT[F, E, L, S, ?]] { implicit def F: Monad[F] def G: Alternative[F] @@ -609,7 +703,9 @@ private trait RWSTAlternative1[F[_], E, L, S] extends IRWSTSemigroupK1[F, E, L, def pure[A](a: A): ReaderWriterStateT[F, E, L, S, A] = ReaderWriterStateT.pure[F, E, L, S, A](a) - def ap[A, B](ff: ReaderWriterStateT[F, E, L, S, A => B])(fa: ReaderWriterStateT[F, E, L, S, A]): ReaderWriterStateT[F, E, L, S, B] = + def ap[A, B]( + ff: ReaderWriterStateT[F, E, L, S, A => B] + )(fa: ReaderWriterStateT[F, E, L, S, A]): ReaderWriterStateT[F, E, L, S, B] = ff.flatMap(f => fa.map(f)(F))(F, L) } diff --git a/core/src/main/scala/cats/data/IndexedStateT.scala b/core/src/main/scala/cats/data/IndexedStateT.scala index 4a256cce838..f29def34ae0 100644 --- a/core/src/main/scala/cats/data/IndexedStateT.scala +++ b/core/src/main/scala/cats/data/IndexedStateT.scala @@ -6,25 +6,26 @@ import cats.arrow.{Profunctor, Strong} import cats.syntax.either._ /** - * - * `IndexedStateT[F, SA, SB, A]` is a stateful computation in a context `F` yielding - * a value of type `A`. The state transitions from a value of type `SA` to a value - * of type `SB`. - * - * Note that for the `SA != SB` case, this is an indexed monad. Indexed monads - * are monadic type constructors annotated by an additional type for effect - * tracking purposes. In this case, the annotation tracks the initial state and - * the resulting state. - * - * Given `IndexedStateT[F, S, S, A]`, this yields the `StateT[F, S, A]` monad. - */ + * + * `IndexedStateT[F, SA, SB, A]` is a stateful computation in a context `F` yielding + * a value of type `A`. The state transitions from a value of type `SA` to a value + * of type `SB`. + * + * Note that for the `SA != SB` case, this is an indexed monad. Indexed monads + * are monadic type constructors annotated by an additional type for effect + * tracking purposes. In this case, the annotation tracks the initial state and + * the resulting state. + * + * Given `IndexedStateT[F, S, S, A]`, this yields the `StateT[F, S, A]` monad. + */ final class IndexedStateT[F[_], SA, SB, A](val runF: F[SA => F[(SB, A)]]) extends Serializable { def flatMap[B, SC](fas: A => IndexedStateT[F, SB, SC, B])(implicit F: FlatMap[F]): IndexedStateT[F, SA, SC, B] = IndexedStateT.applyF(F.map(runF) { safsba => AndThen(safsba).andThen { fsba => - F.flatMap(fsba) { case (sb, a) => - fas(a).run(sb) + F.flatMap(fsba) { + case (sb, a) => + fas(a).run(sb) } } }) @@ -40,107 +41,108 @@ final class IndexedStateT[F[_], SA, SB, A](val runF: F[SA => F[(SB, A)]]) extend transform { case (s, a) => (s, f(a)) } /** - * Modify the context `F` using transformation `f`. - */ + * Modify the context `F` using transformation `f`. + */ def mapK[G[_]](f: F ~> G)(implicit F: Functor[F]): IndexedStateT[G, SA, SB, A] = - IndexedStateT.applyF( - f(F.map(runF)(_.andThen(fsa => f(fsa))))) + IndexedStateT.applyF(f(F.map(runF)(_.andThen(fsa => f(fsa))))) def contramap[S0](f: S0 => SA)(implicit F: Functor[F]): IndexedStateT[F, S0, SB, A] = IndexedStateT.applyF { - F.map(runF) { safsba => - (s0: S0) => safsba(f(s0)) + F.map(runF) { safsba => (s0: S0) => + safsba(f(s0)) } } def bimap[SC, B](f: SB => SC, g: A => B)(implicit F: Functor[F]): IndexedStateT[F, SA, SC, B] = - transform { (s, a) => (f(s), g(a)) } + transform { (s, a) => + (f(s), g(a)) + } def dimap[S0, S1](f: S0 => SA)(g: SB => S1)(implicit F: Functor[F]): IndexedStateT[F, S0, S1, A] = contramap(f).modify(g) /** - * Run with the provided initial state value - */ + * Run with the provided initial state value + */ def run(initial: SA)(implicit F: FlatMap[F]): F[(SB, A)] = F.flatMap(runF)(f => f(initial)) /** - * Run with the provided initial state value and return the final state - * (discarding the final value). - */ + * Run with the provided initial state value and return the final state + * (discarding the final value). + */ def runS(s: SA)(implicit F: FlatMap[F]): F[SB] = F.map(run(s))(_._1) /** - * Run with the provided initial state value and return the final value - * (discarding the final state). - */ + * Run with the provided initial state value and return the final value + * (discarding the final state). + */ def runA(s: SA)(implicit F: FlatMap[F]): F[A] = F.map(run(s))(_._2) /** - * Run with `S`'s empty monoid value as the initial state. - */ + * Run with `S`'s empty monoid value as the initial state. + */ def runEmpty(implicit S: Monoid[SA], F: FlatMap[F]): F[(SB, A)] = run(S.empty) /** - * Run with `S`'s empty monoid value as the initial state and return the final - * state (discarding the final value). - */ + * Run with `S`'s empty monoid value as the initial state and return the final + * state (discarding the final value). + */ def runEmptyS(implicit S: Monoid[SA], F: FlatMap[F]): F[SB] = runS(S.empty) /** - * Run with `S`'s empty monoid value as the initial state and return the final - * value (discarding the final state). - */ + * Run with `S`'s empty monoid value as the initial state and return the final + * value (discarding the final state). + */ def runEmptyA(implicit S: Monoid[SA], F: FlatMap[F]): F[A] = runA(S.empty) /** - * Like [[map]], but also allows the state (`S`) value to be modified. - */ + * Like [[map]], but also allows the state (`S`) value to be modified. + */ def transform[B, SC](f: (SB, A) => (SC, B))(implicit F: Functor[F]): IndexedStateT[F, SA, SC, B] = - IndexedStateT.applyF( - F.map(runF) { sfsa => - sfsa.andThen { fsa => - F.map(fsa) { case (s, a) => f(s, a) } - } - }) + IndexedStateT.applyF(F.map(runF) { sfsa => + sfsa.andThen { fsa => + F.map(fsa) { case (s, a) => f(s, a) } + } + }) /** - * Like [[transform]], but allows the context to change from `F` to `G`. - * - * {{{ - * scala> import cats.implicits._ - * scala> type ErrorOr[A] = Either[String, A] - * scala> val xError: IndexedStateT[ErrorOr, Int, Int, Int] = IndexedStateT.get - * scala> val xOpt: IndexedStateT[Option, Int, Int, Int] = xError.transformF(_.toOption) - * scala> val input = 5 - * scala> xError.run(input) - * res0: ErrorOr[(Int, Int)] = Right((5,5)) - * scala> xOpt.run(5) - * res1: Option[(Int, Int)] = Some((5,5)) - * }}} - */ - def transformF[G[_], B, SC](f: F[(SB, A)] => G[(SC, B)])(implicit F: FlatMap[F], G: Applicative[G]): IndexedStateT[G, SA, SC, B] = + * Like [[transform]], but allows the context to change from `F` to `G`. + * + * {{{ + * scala> import cats.implicits._ + * scala> type ErrorOr[A] = Either[String, A] + * scala> val xError: IndexedStateT[ErrorOr, Int, Int, Int] = IndexedStateT.get + * scala> val xOpt: IndexedStateT[Option, Int, Int, Int] = xError.transformF(_.toOption) + * scala> val input = 5 + * scala> xError.run(input) + * res0: ErrorOr[(Int, Int)] = Right((5,5)) + * scala> xOpt.run(5) + * res1: Option[(Int, Int)] = Some((5,5)) + * }}} + */ + def transformF[G[_], B, SC](f: F[(SB, A)] => G[(SC, B)])(implicit F: FlatMap[F], + G: Applicative[G]): IndexedStateT[G, SA, SC, B] = IndexedStateT(s => f(run(s))) /** - * Transform the state used. - * - * This is useful when you are working with many focused `StateT`s and want to pass in a - * global state containing the various states needed for each individual `StateT`. - * - * {{{ - * scala> import cats.implicits._ // needed for StateT.apply - * scala> type GlobalEnv = (Int, String) - * scala> val x: StateT[Option, Int, Double] = StateT((x: Int) => Option((x + 1, x.toDouble))) - * scala> val xt: StateT[Option, GlobalEnv, Double] = x.transformS[GlobalEnv](_._1, (t, i) => (i, t._2)) - * scala> val input = 5 - * scala> x.run(input) - * res0: Option[(Int, Double)] = Some((6,5.0)) - * scala> xt.run((input, "hello")) - * res1: Option[(GlobalEnv, Double)] = Some(((6,hello),5.0)) - * }}} - */ + * Transform the state used. + * + * This is useful when you are working with many focused `StateT`s and want to pass in a + * global state containing the various states needed for each individual `StateT`. + * + * {{{ + * scala> import cats.implicits._ // needed for StateT.apply + * scala> type GlobalEnv = (Int, String) + * scala> val x: StateT[Option, Int, Double] = StateT((x: Int) => Option((x + 1, x.toDouble))) + * scala> val xt: StateT[Option, GlobalEnv, Double] = x.transformS[GlobalEnv](_._1, (t, i) => (i, t._2)) + * scala> val input = 5 + * scala> x.run(input) + * res0: Option[(Int, Double)] = Some((6,5.0)) + * scala> xt.run((input, "hello")) + * res1: Option[(GlobalEnv, Double)] = Some(((6,hello),5.0)) + * }}} + */ def transformS[R](f: R => SA, g: (R, SB) => R)(implicit F: Functor[F]): IndexedStateT[F, R, R, A] = StateT.applyF(F.map(runF) { sfsa => { r: R => @@ -151,20 +153,20 @@ final class IndexedStateT[F[_], SA, SB, A](val runF: F[SA => F[(SB, A)]]) extend }) /** - * Modify the state (`S`) component. - */ + * Modify the state (`S`) component. + */ def modify[SC](f: SB => SC)(implicit F: Functor[F]): IndexedStateT[F, SA, SC, A] = transform((s, a) => (f(s), a)) /** - * Inspect a value from the input state, without modifying the state. - */ + * Inspect a value from the input state, without modifying the state. + */ def inspect[B](f: SB => B)(implicit F: Functor[F]): IndexedStateT[F, SA, SB, B] = transform((s, _) => (s, f(s))) /** - * Get the input state, without modifying the state. - */ + * Get the input state, without modifying the state. + */ def get(implicit F: Functor[F]): IndexedStateT[F, SA, SB, SB] = inspect(identity) } @@ -177,15 +179,15 @@ private[data] trait CommonStateTConstructors { IndexedStateT(s => F.map(fa)(a => (s, a))) /** - * Same as [[liftF]], but expressed as a FunctionK for use with mapK - * {{{ - * scala> import cats._, data._, implicits._ - * scala> val a: OptionT[Eval, Int] = 1.pure[OptionT[Eval, ?]] - * scala> val b: OptionT[StateT[Eval, String, ?], Int] = a.mapK(StateT.liftK) - * scala> b.value.runEmpty.value - * res0: (String, Option[Int]) = ("",Some(1)) - * }}} - */ + * Same as [[liftF]], but expressed as a FunctionK for use with mapK + * {{{ + * scala> import cats._, data._, implicits._ + * scala> val a: OptionT[Eval, Int] = 1.pure[OptionT[Eval, ?]] + * scala> val b: OptionT[StateT[Eval, String, ?], Int] = a.mapK(StateT.liftK) + * scala> b.value.runEmpty.value + * res0: (String, Option[Int]) = ("",Some(1)) + * }}} + */ def liftK[F[_], S](implicit F: Applicative[F]): F ~> IndexedStateT[F, S, S, ?] = λ[F ~> IndexedStateT[F, S, S, ?]](IndexedStateT.liftF(_)) @@ -228,7 +230,7 @@ private[data] trait CommonStateTConstructors0 extends CommonStateTConstructors { pure(A.empty) } -private[data] abstract class StateTFunctions extends CommonStateTConstructors { +abstract private[data] class StateTFunctions extends CommonStateTConstructors { def apply[F[_], S, A](f: S => F[(S, A)])(implicit F: Applicative[F]): StateT[F, S, A] = IndexedStateT(f) @@ -248,9 +250,11 @@ private[data] abstract class StateTFunctions extends CommonStateTConstructors { apply(_ => F.map(fs)(s => (s, ()))) } -private[data] sealed abstract class IndexedStateTInstances extends IndexedStateTInstances1 { - implicit def catsDataAlternativeForIndexedStateT[F[_], S](implicit FM: Monad[F], - FA: Alternative[F]): Alternative[IndexedStateT[F, S, S, ?]] with Monad[IndexedStateT[F, S, S, ?]] = +sealed abstract private[data] class IndexedStateTInstances extends IndexedStateTInstances1 { + implicit def catsDataAlternativeForIndexedStateT[F[_], S]( + implicit FM: Monad[F], + FA: Alternative[F] + ): Alternative[IndexedStateT[F, S, S, ?]] with Monad[IndexedStateT[F, S, S, ?]] = new IndexedStateTAlternative[F, S] { implicit def F = FM; implicit def G = FA } implicit def catsDataDeferForIndexedStateT[F[_], SA, SB](implicit F: Defer[F]): Defer[IndexedStateT[F, SA, SB, ?]] = @@ -260,48 +264,61 @@ private[data] sealed abstract class IndexedStateTInstances extends IndexedStateT } } -private[data] sealed abstract class IndexedStateTInstances1 extends IndexedStateTInstances2 { - implicit def catsDataMonadErrorForIndexedStateT[F[_], S, E](implicit F0: MonadError[F, E]): MonadError[IndexedStateT[F, S, S, ?], E] = +sealed abstract private[data] class IndexedStateTInstances1 extends IndexedStateTInstances2 { + implicit def catsDataMonadErrorForIndexedStateT[F[_], S, E]( + implicit F0: MonadError[F, E] + ): MonadError[IndexedStateT[F, S, S, ?], E] = new IndexedStateTMonadError[F, S, E] { implicit def F = F0 } - implicit def catsDataSemigroupKForIndexedStateT[F[_], SA, SB](implicit F0: Monad[F], G0: SemigroupK[F]): SemigroupK[IndexedStateT[F, SA, SB, ?]] = + implicit def catsDataSemigroupKForIndexedStateT[F[_], SA, SB]( + implicit F0: Monad[F], + G0: SemigroupK[F] + ): SemigroupK[IndexedStateT[F, SA, SB, ?]] = new IndexedStateTSemigroupK[F, SA, SB] { implicit def F = F0; implicit def G = G0 } } -private[data] sealed abstract class IndexedStateTInstances2 extends IndexedStateTInstances3 { +sealed abstract private[data] class IndexedStateTInstances2 extends IndexedStateTInstances3 { implicit def catsDataMonadForIndexedStateT[F[_], S](implicit F0: Monad[F]): Monad[IndexedStateT[F, S, S, ?]] = new IndexedStateTMonad[F, S] { implicit def F = F0 } } -private[data] sealed abstract class IndexedStateTInstances3 extends IndexedStateTInstances4 { - implicit def catsDataFunctorForIndexedStateT[F[_], SA, SB](implicit F0: Functor[F]): Functor[IndexedStateT[F, SA, SB, ?]] = +sealed abstract private[data] class IndexedStateTInstances3 extends IndexedStateTInstances4 { + implicit def catsDataFunctorForIndexedStateT[F[_], SA, SB]( + implicit F0: Functor[F] + ): Functor[IndexedStateT[F, SA, SB, ?]] = new IndexedStateTFunctor[F, SA, SB] { implicit def F = F0 } - implicit def catsDataContravariantForIndexedStateT[F[_], SB, V](implicit F0: Functor[F]): Contravariant[IndexedStateT[F, ?, SB, V]] = + implicit def catsDataContravariantForIndexedStateT[F[_], SB, V]( + implicit F0: Functor[F] + ): Contravariant[IndexedStateT[F, ?, SB, V]] = new IndexedStateTContravariant[F, SB, V] { implicit def F = F0 } - implicit def catsDataProfunctorForIndexedStateT[F[_], V](implicit F0: Functor[F]): Profunctor[IndexedStateT[F, ?, ?, V]] = + implicit def catsDataProfunctorForIndexedStateT[F[_], V]( + implicit F0: Functor[F] + ): Profunctor[IndexedStateT[F, ?, ?, V]] = new IndexedStateTProfunctor[F, V] { implicit def F = F0 } - implicit def catsDataBifunctorForIndexedStateT[F[_], SA](implicit F0: Functor[F]): Bifunctor[IndexedStateT[F, SA, ?, ?]] = + implicit def catsDataBifunctorForIndexedStateT[F[_], SA]( + implicit F0: Functor[F] + ): Bifunctor[IndexedStateT[F, SA, ?, ?]] = new IndexedStateTBifunctor[F, SA] { implicit def F = F0 } } -private[data] sealed abstract class IndexedStateTInstances4 { +sealed abstract private[data] class IndexedStateTInstances4 { implicit def catsDataStrongForIndexedStateT[F[_], V](implicit F0: Monad[F]): Strong[IndexedStateT[F, ?, ?, V]] = new IndexedStateTStrong[F, V] { 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 { +abstract private[data] class StateFunctions { def apply[S, A](f: S => (S, A)): State[S, A] = IndexedStateT.applyF(Now((s: S) => Now(f(s)))) /** - * Return `a` and maintain the input state. - */ + * Return `a` and maintain the input state. + */ def pure[S, A](a: A): State[S, A] = State(s => (s, a)) /** @@ -310,69 +327,76 @@ private[data] abstract class StateFunctions { def empty[S, A](implicit A: Monoid[A]): State[S, A] = pure(A.empty) /** - * Modify the input state and return Unit. - */ + * Modify the input state and return Unit. + */ def modify[S](f: S => S): State[S, Unit] = State(s => (f(s), ())) /** - * Inspect a value from the input state, without modifying the state. - */ + * Inspect a value from the input state, without modifying the state. + */ def inspect[S, T](f: S => T): State[S, T] = State(s => (s, f(s))) /** - * Return the input state without modifying it. - */ + * Return the input state without modifying it. + */ def get[S]: State[S, S] = inspect(identity) /** - * Set the state to `s` and return Unit. - */ + * Set the state to `s` and return Unit. + */ def set[S](s: S): State[S, Unit] = State(_ => (s, ())) } -private[data] sealed abstract class IndexedStateTFunctor[F[_], SA, SB] extends Functor[IndexedStateT[F, SA, SB, ?]] { +sealed abstract private[data] class IndexedStateTFunctor[F[_], SA, SB] extends Functor[IndexedStateT[F, SA, SB, ?]] { implicit def F: Functor[F] override def map[A, B](fa: IndexedStateT[F, SA, SB, A])(f: A => B): IndexedStateT[F, SA, SB, B] = fa.map(f) } -private[data] sealed abstract class IndexedStateTContravariant[F[_], SB, V] extends Contravariant[IndexedStateT[F, ?, SB, V]] { +sealed abstract private[data] class IndexedStateTContravariant[F[_], SB, V] + extends Contravariant[IndexedStateT[F, ?, SB, V]] { implicit def F: Functor[F] override def contramap[A, B](fa: IndexedStateT[F, A, SB, V])(f: B => A): IndexedStateT[F, B, SB, V] = fa.contramap(f) } -private[data] sealed abstract class IndexedStateTBifunctor[F[_], SA] extends Bifunctor[IndexedStateT[F, SA, ?, ?]] { +sealed abstract private[data] class IndexedStateTBifunctor[F[_], SA] extends Bifunctor[IndexedStateT[F, SA, ?, ?]] { implicit def F: Functor[F] def bimap[A, B, C, D](fab: IndexedStateT[F, SA, A, B])(f: A => C, g: B => D): IndexedStateT[F, SA, C, D] = fab.bimap(f, g) } -private[data] sealed abstract class IndexedStateTProfunctor[F[_], V] extends Profunctor[IndexedStateT[F, ?, ?, V]] { +sealed abstract private[data] class IndexedStateTProfunctor[F[_], V] extends Profunctor[IndexedStateT[F, ?, ?, V]] { implicit def F: Functor[F] def dimap[A, B, C, D](fab: IndexedStateT[F, A, B, V])(f: C => A)(g: B => D): IndexedStateT[F, C, D, V] = fab.dimap(f)(g) } -private[data] sealed abstract class IndexedStateTStrong[F[_], V] extends IndexedStateTProfunctor[F, V] with Strong[IndexedStateT[F, ?, ?, V]] { +sealed abstract private[data] class IndexedStateTStrong[F[_], V] + extends IndexedStateTProfunctor[F, V] + with Strong[IndexedStateT[F, ?, ?, V]] { implicit def F: Monad[F] def first[A, B, C](fa: IndexedStateT[F, A, B, V]): IndexedStateT[F, (A, C), (B, C), V] = - IndexedStateT { case (a, c) => - F.map(fa.run(a)) { case (b, v) => - ((b, c), v) - } + IndexedStateT { + case (a, c) => + F.map(fa.run(a)) { + case (b, v) => + ((b, c), v) + } } def second[A, B, C](fa: IndexedStateT[F, A, B, V]): IndexedStateT[F, (C, A), (C, B), V] = first(fa).dimap((_: (C, A)).swap)(_.swap) } -private[data] sealed abstract class IndexedStateTMonad[F[_], S] extends IndexedStateTFunctor[F, S, S] with Monad[IndexedStateT[F, S, S, ?]] { +sealed abstract private[data] class IndexedStateTMonad[F[_], S] + extends IndexedStateTFunctor[F, S, S] + with Monad[IndexedStateT[F, S, S, ?]] { implicit def F: Monad[F] def pure[A](a: A): IndexedStateT[F, S, S, A] = @@ -382,12 +406,16 @@ private[data] sealed abstract class IndexedStateTMonad[F[_], S] extends IndexedS fa.flatMap(f) def tailRecM[A, B](a: A)(f: A => IndexedStateT[F, S, S, Either[A, B]]): IndexedStateT[F, S, S, B] = - IndexedStateT[F, S, 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, _)) } - }) + IndexedStateT[F, S, 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, _)) } + } + ) } -private[data] sealed abstract class IndexedStateTSemigroupK[F[_], SA, SB] extends SemigroupK[IndexedStateT[F, SA, SB, ?]] { +sealed abstract private[data] class IndexedStateTSemigroupK[F[_], SA, SB] + extends SemigroupK[IndexedStateT[F, SA, SB, ?]] { implicit def F: Monad[F] implicit def G: SemigroupK[F] @@ -395,29 +423,39 @@ private[data] sealed abstract class IndexedStateTSemigroupK[F[_], SA, SB] extend IndexedStateT(s => G.combineK(x.run(s), y.run(s))) } -private[data] sealed abstract class IndexedStateTContravariantMonoidal[F[_], S] extends ContravariantMonoidal[IndexedStateT[F, S, S, ?]]{ +sealed abstract private[data] class IndexedStateTContravariantMonoidal[F[_], S] + extends ContravariantMonoidal[IndexedStateT[F, S, S, ?]] { implicit def F: ContravariantMonoidal[F] implicit def G: Applicative[F] - override def unit: IndexedStateT[F, S, S, Unit] = + override def unit: IndexedStateT[F, S, S, Unit] = IndexedStateT.applyF(G.pure((s: S) => F.trivial[(S, Unit)])) override def contramap[A, B](fa: IndexedStateT[F, S, S, A])(f: B => A): IndexedStateT[F, S, S, B] = - contramap2(fa, trivial)(((a: A) => (a, a)) compose f) + contramap2(fa, trivial)(((a: A) => (a, a)).compose(f)) - override def product[A, B](fa: IndexedStateT[F, S, S, A], fb: IndexedStateT[F, S, S, B]): IndexedStateT[F, S, S, (A, B)] = + override def product[A, B](fa: IndexedStateT[F, S, S, A], + fb: IndexedStateT[F, S, S, B]): IndexedStateT[F, S, S, (A, B)] = contramap2(fa, fb)(identity) - def contramap2[A, B, C](fb: IndexedStateT[F, S, S, B], fc: IndexedStateT[F, S, S, C])(f: A => (B, C)): IndexedStateT[F, S, S, A] = + def contramap2[A, B, C](fb: IndexedStateT[F, S, S, B], + fc: IndexedStateT[F, S, S, C])(f: A => (B, C)): IndexedStateT[F, S, S, A] = IndexedStateT.applyF( - G.pure((s: S) => - ContravariantMonoidal.contramap2(G.map(fb.runF)(_.apply(s)), G.map(fc.runF)(_.apply(s)))( - (tup: (S, A)) => f(tup._2) match { - case (b, c) => (G.pure((tup._1, b)), G.pure((tup._1, c))) - })(G, F))) + G.pure( + (s: S) => + ContravariantMonoidal.contramap2(G.map(fb.runF)(_.apply(s)), G.map(fc.runF)(_.apply(s)))( + (tup: (S, A)) => + f(tup._2) match { + case (b, c) => (G.pure((tup._1, b)), G.pure((tup._1, c))) + } + )(G, F) + ) + ) } -private[data] sealed abstract class IndexedStateTAlternative[F[_], S] extends IndexedStateTMonad[F, S] with Alternative[IndexedStateT[F, S, S, ?]] { +sealed abstract private[data] class IndexedStateTAlternative[F[_], S] + extends IndexedStateTMonad[F, S] + with Alternative[IndexedStateT[F, S, S, ?]] { def G: Alternative[F] def combineK[A](x: IndexedStateT[F, S, S, A], y: IndexedStateT[F, S, S, A]): IndexedStateT[F, S, S, A] = @@ -427,7 +465,8 @@ private[data] sealed abstract class IndexedStateTAlternative[F[_], S] extends In IndexedStateT.liftF[F, S, A](G.empty[A])(G) } -private[data] sealed abstract class IndexedStateTMonadError[F[_], S, E] extends IndexedStateTMonad[F, S] +sealed abstract private[data] class IndexedStateTMonadError[F[_], S, E] + extends IndexedStateTMonad[F, S] with MonadError[IndexedStateT[F, S, S, ?], E] { implicit def F: MonadError[F, E] diff --git a/core/src/main/scala/cats/data/Ior.scala b/core/src/main/scala/cats/data/Ior.scala index cc7e5a0152f..3f4e25c278b 100644 --- a/core/src/main/scala/cats/data/Ior.scala +++ b/core/src/main/scala/cats/data/Ior.scala @@ -8,26 +8,26 @@ import cats.data.Validated.{Invalid, Valid} import scala.annotation.tailrec /** Represents a right-biased disjunction that is either an `A`, or a `B`, or both an `A` and a `B`. - * - * An instance of `A [[Ior]] B` is one of: - * - `[[Ior.Left Left]][A]` - * - `[[Ior.Right Right]][B]` - * - `[[Ior.Both Both]][A, B]` - * - * `A [[Ior]] B` is similar to `scala.util.Either[A, B]`, except that it can represent the simultaneous presence of - * an `A` and a `B`. It is right-biased so methods such as `map` and `flatMap` operate on the - * `B` value. Some methods, like `flatMap`, handle the presence of two [[Ior.Both Both]] values using a - * `[[Semigroup]][A]`, while other methods, like [[toEither]], ignore the `A` value in a [[Ior.Both Both]]. - * - * `A [[Ior]] B` is isomorphic to `Either[Either[A, B], (A, B)]`, but provides methods biased toward `B` - * values, regardless of whether the `B` values appear in a [[Ior.Right Right]] or a [[Ior.Both Both]]. - * The isomorphic `scala.util.Either` form can be accessed via the [[unwrap]] method. - */ + * + * An instance of `A [[Ior]] B` is one of: + * - `[[Ior.Left Left]][A]` + * - `[[Ior.Right Right]][B]` + * - `[[Ior.Both Both]][A, B]` + * + * `A [[Ior]] B` is similar to `scala.util.Either[A, B]`, except that it can represent the simultaneous presence of + * an `A` and a `B`. It is right-biased so methods such as `map` and `flatMap` operate on the + * `B` value. Some methods, like `flatMap`, handle the presence of two [[Ior.Both Both]] values using a + * `[[Semigroup]][A]`, while other methods, like [[toEither]], ignore the `A` value in a [[Ior.Both Both]]. + * + * `A [[Ior]] B` is isomorphic to `Either[Either[A, B], (A, B)]`, but provides methods biased toward `B` + * values, regardless of whether the `B` values appear in a [[Ior.Right Right]] or a [[Ior.Both Both]]. + * The isomorphic `scala.util.Either` form can be accessed via the [[unwrap]] method. + */ sealed abstract class Ior[+A, +B] extends Product with Serializable { final def fold[C](fa: A => C, fb: B => C, fab: (A, B) => C): C = this match { - case Ior.Left(a) => fa(a) - case Ior.Right(b) => fb(b) + case Ior.Left(a) => fa(a) + case Ior.Right(b) => fb(b) case Ior.Both(a, b) => fab(a, b) } @@ -47,7 +47,8 @@ sealed abstract class Ior[+A, +B] extends Product with Serializable { final def onlyLeftOrRight: Option[Either[A, B]] = fold(a => Some(Left(a)), b => Some(Right(b)), (_, _) => None) final def onlyBoth: Option[(A, B)] = fold(_ => None, _ => None, (a, b) => Some((a, b))) final def pad: (Option[A], Option[B]) = fold(a => (Some(a), None), b => (None, Some(b)), (a, b) => (Some(a), Some(b))) - final def unwrap: Either[Either[A, B], (A, B)] = fold(a => Left(Left(a)), b => Left(Right(b)), (a, b) => Right((a, b))) + final def unwrap: Either[Either[A, B], (A, B)] = + fold(a => Left(Left(a)), b => Left(Right(b)), (a, b) => Right((a, b))) final def toIorNes[AA >: A](implicit O: Order[AA]): IorNes[AA, B] = leftMap(NonEmptySet.one(_)) final def toIorNec[AA >: A]: IorNec[AA, B] = leftMap(NonEmptyChain.one) @@ -63,9 +64,9 @@ sealed abstract class Ior[+A, +B] extends Product with Serializable { final def swap: B Ior A = fold(Ior.right, Ior.left, (a, b) => Ior.both(b, a)) - final def exists(p: B => Boolean): Boolean = right exists p - final def forall(p: B => Boolean): Boolean = right forall p - final def getOrElse[BB >: B](bb: => BB): BB = right getOrElse bb + final def exists(p: B => Boolean): Boolean = right.exists(p) + final def forall(p: B => Boolean): Boolean = right.forall(p) + final def getOrElse[BB >: B](bb: => BB): BB = right.getOrElse(bb) final def valueOr[BB >: B](f: A => BB)(implicit BB: Semigroup[BB]): BB = fold(f, identity, (a, b) => BB.combine(f(a), b)) @@ -77,12 +78,13 @@ sealed abstract class Ior[+A, +B] extends Product with Serializable { final def flatMap[AA >: A, D](f: B => AA Ior D)(implicit AA: Semigroup[AA]): AA Ior D = this match { case l @ Ior.Left(_) => l - case Ior.Right(b) => f(b) - case Ior.Both(a1, b) => f(b) match { - case Ior.Left(a2) => Ior.Left(AA.combine(a1, a2)) - case Ior.Right(b) => Ior.Both(a1, b) - case Ior.Both(a2, d) => Ior.Both(AA.combine(a1, a2), d) - } + case Ior.Right(b) => f(b) + case Ior.Both(a1, b) => + f(b) match { + case Ior.Left(a2) => Ior.Left(AA.combine(a1, a2)) + case Ior.Right(b) => Ior.Both(a1, b) + case Ior.Both(a2, d) => Ior.Both(AA.combine(a1, a2), d) + } } final def foreach(f: B => Unit): Unit = { @@ -91,8 +93,8 @@ sealed abstract class Ior[+A, +B] extends Product with Serializable { } final def traverse[F[_], AA >: A, D](g: B => F[D])(implicit F: Applicative[F]): F[AA Ior D] = this match { - case Ior.Left(a) => F.pure(Ior.left(a)) - case Ior.Right(b) => F.map(g(b))(Ior.right) + case Ior.Left(a) => F.pure(Ior.left(a)) + case Ior.Right(b) => F.map(g(b))(Ior.right) case Ior.Both(a, b) => F.map(g(b))(d => Ior.both(a, d)) } @@ -110,23 +112,27 @@ sealed abstract class Ior[+A, +B] extends Product with Serializable { fold(identity, ev, (_, b) => ev(b)) // scalastyle:off cyclomatic.complexity - final def combine[AA >: A, BB >: B](that: AA Ior BB)(implicit AA: Semigroup[AA], BB: Semigroup[BB]): AA Ior BB = this match { - case Ior.Left(a1) => that match { - case Ior.Left(a2) => Ior.Left(AA.combine(a1, a2)) - case Ior.Right(b2) => Ior.Both(a1, b2) - case Ior.Both(a2, b2) => Ior.Both(AA.combine(a1, a2), b2) - } - case Ior.Right(b1) => that match { - case Ior.Left(a2) => Ior.Both(a2, b1) - case Ior.Right(b2) => Ior.Right(BB.combine(b1, b2)) - case Ior.Both(a2, b2) => Ior.Both(a2, BB.combine(b1, b2)) - } - case Ior.Both(a1, b1) => that match { - case Ior.Left(a2) => Ior.Both(AA.combine(a1, a2), b1) - case Ior.Right(b2) => Ior.Both(a1, BB.combine(b1, b2)) - case Ior.Both(a2, b2) => Ior.Both(AA.combine(a1, a2), BB.combine(b1, b2)) + final def combine[AA >: A, BB >: B](that: AA Ior BB)(implicit AA: Semigroup[AA], BB: Semigroup[BB]): AA Ior BB = + this match { + case Ior.Left(a1) => + that match { + case Ior.Left(a2) => Ior.Left(AA.combine(a1, a2)) + case Ior.Right(b2) => Ior.Both(a1, b2) + case Ior.Both(a2, b2) => Ior.Both(AA.combine(a1, a2), b2) + } + case Ior.Right(b1) => + that match { + case Ior.Left(a2) => Ior.Both(a2, b1) + case Ior.Right(b2) => Ior.Right(BB.combine(b1, b2)) + case Ior.Both(a2, b2) => Ior.Both(a2, BB.combine(b1, b2)) + } + case Ior.Both(a1, b1) => + that match { + case Ior.Left(a2) => Ior.Both(AA.combine(a1, a2), b1) + case Ior.Right(b2) => Ior.Both(a1, BB.combine(b1, b2)) + case Ior.Both(a2, b2) => Ior.Both(AA.combine(a1, a2), BB.combine(b1, b2)) + } } - } // scalastyle:on cyclomatic.complexity final def ===[AA >: A, BB >: B](that: AA Ior BB)(implicit AA: Eq[AA], BB: Eq[BB]): Boolean = fold( @@ -148,28 +154,30 @@ object Ior extends IorInstances with IorFunctions with IorFunctions2 { final case class Both[+A, +B](a: A, b: B) extends (A Ior B) } -private[data] sealed abstract class IorInstances extends IorInstances0 { +sealed abstract private[data] class IorInstances extends IorInstances0 { implicit val catsBitraverseForIor: Bitraverse[Ior] = new Bitraverse[Ior] { - def bitraverse[G[_], A, B, C, D](fab: Ior[A, B])(f: A => G[C], g: B => G[D])(implicit G: Applicative[G]): G[Ior[C, D]] = + def bitraverse[G[_], A, B, C, D](fab: Ior[A, B])(f: A => G[C], + g: B => G[D])(implicit G: Applicative[G]): G[Ior[C, D]] = fab match { - case Ior.Left(a) => G.map(f(a))(Ior.Left(_)) - case Ior.Right(b) => G.map(g(b))(Ior.Right(_)) + case Ior.Left(a) => G.map(f(a))(Ior.Left(_)) + case Ior.Right(b) => G.map(g(b))(Ior.Right(_)) case Ior.Both(a, b) => G.map2(f(a), g(b))(Ior.Both(_, _)) } def bifoldLeft[A, B, C](fab: Ior[A, B], c: C)(f: (C, A) => C, g: (C, B) => C): C = fab match { - case Ior.Left(a) => f(c, a) - case Ior.Right(b) => g(c, b) + case Ior.Left(a) => f(c, a) + case Ior.Right(b) => g(c, b) case Ior.Both(a, b) => g(f(c, a), b) } - def bifoldRight[A, B, C](fab: Ior[A, B], c: Eval[C])(f: (A, Eval[C]) => Eval[C], g: (B, Eval[C]) => Eval[C]): Eval[C] = + def bifoldRight[A, B, C](fab: Ior[A, B], c: Eval[C])(f: (A, Eval[C]) => Eval[C], + g: (B, Eval[C]) => Eval[C]): Eval[C] = fab match { - case Ior.Left(a) => f(a, c) - case Ior.Right(b) => g(b, c) + case Ior.Left(a) => f(a, c) + case Ior.Right(b) => g(b, c) case Ior.Both(a, b) => g(b, f(a, c)) } } @@ -194,7 +202,7 @@ private[data] sealed abstract class IorInstances extends IorInstances0 { def handleErrorWith[B](fa: Ior[A, B])(f: (A) => Ior[A, B]): Ior[A, B] = fa match { case Ior.Left(e) => f(e) - case _ => fa + case _ => fa } def flatMap[B, C](fa: Ior[A, B])(f: B => Ior[A, C]): Ior[A, C] = fa.flatMap(f) @@ -202,21 +210,21 @@ private[data] sealed abstract class IorInstances extends IorInstances0 { override def map2Eval[B, C, Z](fa: Ior[A, B], fb: Eval[Ior[A, C]])(f: (B, C) => Z): Eval[Ior[A, Z]] = fa match { case l @ Ior.Left(_) => Eval.now(l) // no need to evaluate fb - case notLeft => fb.map(fb => map2(notLeft, fb)(f)) + case notLeft => fb.map(fb => map2(notLeft, fb)(f)) } def tailRecM[B, C](b: B)(fn: B => Ior[A, Either[B, C]]): A Ior C = { @tailrec def loop(v: Ior[A, Either[B, C]]): A Ior C = v match { - case Ior.Left(a) => Ior.left(a) - case Ior.Right(Right(c)) => Ior.right(c) + case Ior.Left(a) => Ior.left(a) + case Ior.Right(Right(c)) => Ior.right(c) case Ior.Both(a, Right(c)) => Ior.both(a, c) - case Ior.Right(Left(b)) => loop(fn(b)) + case Ior.Right(Left(b)) => loop(fn(b)) case Ior.Both(a, Left(b)) => fn(b) match { - case Ior.Left(aa) => Ior.left(Semigroup[A].combine(a, aa)) + case Ior.Left(aa) => Ior.left(Semigroup[A].combine(a, aa)) case Ior.Both(aa, x) => loop(Ior.both(Semigroup[A].combine(a, aa), x)) - case Ior.Right(x) => loop(Ior.both(a, x)) + case Ior.Right(x) => loop(Ior.both(a, x)) } } loop(fn(b)) @@ -234,45 +242,46 @@ private[data] sealed abstract class IorInstances extends IorInstances0 { } // scalastyle:off cyclomatic.complexity - implicit def catsDataParallelForIor[E] - (implicit E: Semigroup[E]): Parallel[Ior[E, ?], Ior[E, ?]] = new Parallel[Ior[E, ?], Ior[E, ?]] - { - - private[this] val identityK: Ior[E, ?] ~> Ior[E, ?] = FunctionK.id - - def parallel: Ior[E, ?] ~> Ior[E, ?] = identityK - def sequential: Ior[E, ?] ~> Ior[E, ?] = identityK - - val applicative: Applicative[Ior[E, ?]] = new Applicative[Ior[E, ?]] { - def pure[A](a: A): Ior[E, A] = Ior.right(a) - def ap[A, B](ff: Ior[E, A => B])(fa: Ior[E, A]): Ior[E, B] = - fa match { - case Ior.Right(a) => ff match { - case Ior.Right(f) => Ior.Right(f(a)) - case Ior.Both(e1, f) => Ior.Both(e1, f(a)) - case Ior.Left(e1) => Ior.Left(e1) + implicit def catsDataParallelForIor[E](implicit E: Semigroup[E]): Parallel[Ior[E, ?], Ior[E, ?]] = + new Parallel[Ior[E, ?], Ior[E, ?]] { + + private[this] val identityK: Ior[E, ?] ~> Ior[E, ?] = FunctionK.id + + def parallel: Ior[E, ?] ~> Ior[E, ?] = identityK + def sequential: Ior[E, ?] ~> Ior[E, ?] = identityK + + val applicative: Applicative[Ior[E, ?]] = new Applicative[Ior[E, ?]] { + def pure[A](a: A): Ior[E, A] = Ior.right(a) + def ap[A, B](ff: Ior[E, A => B])(fa: Ior[E, A]): Ior[E, B] = + fa match { + case Ior.Right(a) => + ff match { + case Ior.Right(f) => Ior.Right(f(a)) + case Ior.Both(e1, f) => Ior.Both(e1, f(a)) + case Ior.Left(e1) => Ior.Left(e1) + } + case Ior.Both(e1, a) => + ff match { + case Ior.Right(f) => Ior.Both(e1, f(a)) + case Ior.Both(e2, f) => Ior.Both(E.combine(e2, e1), f(a)) + case Ior.Left(e2) => Ior.Left(E.combine(e2, e1)) + } + case Ior.Left(e1) => + ff match { + case Ior.Right(f) => Ior.Left(e1) + case Ior.Both(e2, f) => Ior.Left(E.combine(e2, e1)) + case Ior.Left(e2) => Ior.Left(E.combine(e2, e1)) + } } - case Ior.Both(e1, a) => ff match { - case Ior.Right(f) => Ior.Both(e1, f(a)) - case Ior.Both(e2, f) => Ior.Both(E.combine(e2, e1), f(a)) - case Ior.Left(e2) => Ior.Left(E.combine(e2, e1)) - } - case Ior.Left(e1) => ff match { - case Ior.Right(f) => Ior.Left(e1) - case Ior.Both(e2, f) => Ior.Left(E.combine(e2, e1)) - case Ior.Left(e2) => Ior.Left(E.combine(e2, e1)) - } - } - } + } - lazy val monad: Monad[Ior[E, ?]] = Monad[Ior[E, ?]] - } + lazy val monad: Monad[Ior[E, ?]] = Monad[Ior[E, ?]] + } // scalastyle:on cyclomatic.complexity - } -private[data] sealed abstract class IorInstances0 { +sealed abstract private[data] class IorInstances0 { implicit def catsDataTraverseFunctorForIor[A]: Traverse[A Ior ?] = new Traverse[A Ior ?] { def traverse[F[_]: Applicative, B, C](fa: A Ior B)(f: B => F[C]): F[A Ior C] = @@ -296,7 +305,7 @@ private[data] sealed abstract class IorInstances0 { } } -private[data] sealed trait IorFunctions { +sealed private[data] trait IorFunctions { def left[A, B](a: A): A Ior B = Ior.Left(a) def right[A, B](b: B): A Ior B = Ior.Right(b) def both[A, B](a: A, b: B): A Ior B = Ior.Both(a, b) @@ -304,62 +313,64 @@ private[data] sealed trait IorFunctions { def bothNel[A, B](a: A, b: B): IorNel[A, B] = both(NonEmptyList.one(a), b) /** - * Create an `Ior` from two Options if at least one of them is defined. - * - * @param oa an element (optional) for the left side of the `Ior` - * @param ob an element (optional) for the right side of the `Ior` - * - * @return `None` if both `oa` and `ob` are `None`. Otherwise `Some` wrapping - * an [[Ior.Left]], [[Ior.Right]], or [[Ior.Both]] if `oa`, `ob`, or both are - * defined (respectively). - * - * Example: - * {{{ - * scala> Ior.fromOptions(Option.empty[String], Option.empty[Int]) - * res0: Option[Ior[String, Int]] = None - * scala> Ior.fromOptions(Option.empty[String], Some(42)) - * res1: Option[Ior[String, Int]] = Some(Right(42)) - * scala> Ior.fromOptions(Some("Error"), Option.empty[Int]) - * res2: Option[Ior[String, Int]] = Some(Left(Error)) - * scala> Ior.fromOptions(Some("Warning"), Some(42)) - * res3: Option[Ior[String, Int]] = Some(Both(Warning,42)) - * }}} - */ + * Create an `Ior` from two Options if at least one of them is defined. + * + * @param oa an element (optional) for the left side of the `Ior` + * @param ob an element (optional) for the right side of the `Ior` + * + * @return `None` if both `oa` and `ob` are `None`. Otherwise `Some` wrapping + * an [[Ior.Left]], [[Ior.Right]], or [[Ior.Both]] if `oa`, `ob`, or both are + * defined (respectively). + * + * Example: + * {{{ + * scala> Ior.fromOptions(Option.empty[String], Option.empty[Int]) + * res0: Option[Ior[String, Int]] = None + * scala> Ior.fromOptions(Option.empty[String], Some(42)) + * res1: Option[Ior[String, Int]] = Some(Right(42)) + * scala> Ior.fromOptions(Some("Error"), Option.empty[Int]) + * res2: Option[Ior[String, Int]] = Some(Left(Error)) + * scala> Ior.fromOptions(Some("Warning"), Some(42)) + * res3: Option[Ior[String, Int]] = Some(Both(Warning,42)) + * }}} + */ def fromOptions[A, B](oa: Option[A], ob: Option[B]): Option[A Ior B] = oa match { - case Some(a) => ob match { - case Some(b) => Some(Ior.Both(a, b)) - case None => Some(Ior.Left(a)) - } - case None => ob match { - case Some(b) => Some(Ior.Right(b)) - case None => None - } + case Some(a) => + ob match { + case Some(b) => Some(Ior.Both(a, b)) + case None => Some(Ior.Left(a)) + } + case None => + ob match { + case Some(b) => Some(Ior.Right(b)) + case None => None + } } /** - * Create an `Ior` from an `Either`. - * @param eab an `Either` from which the `Ior` should be created - * - * @return [[Ior.Left]] if the `Either` was a `Left`, - * or [[Ior.Right]] if the `Either` was a `Right` - * - * Example: - * {{{ - * scala> Ior.fromEither(Left(1)) - * res0: Ior[Int, Nothing] = Left(1) - * scala> Ior.fromEither(Right('1')) - * res1: Ior[Nothing, Char] = Right(1) - * }}} - */ + * Create an `Ior` from an `Either`. + * @param eab an `Either` from which the `Ior` should be created + * + * @return [[Ior.Left]] if the `Either` was a `Left`, + * or [[Ior.Right]] if the `Either` was a `Right` + * + * Example: + * {{{ + * scala> Ior.fromEither(Left(1)) + * res0: Ior[Int, Nothing] = Left(1) + * scala> Ior.fromEither(Right('1')) + * res1: Ior[Nothing, Char] = Right(1) + * }}} + */ def fromEither[A, B](eab: Either[A, B]): A Ior B = eab match { - case Left(a) => left(a) + case Left(a) => left(a) case Right(b) => right(b) } } -private[data] sealed trait IorFunctions2{ +sealed private[data] trait IorFunctions2 { def leftNec[A, B](a: A): IorNec[A, B] = Ior.left(NonEmptyChain.one(a)) def bothNec[A, B](a: A, b: B): IorNec[A, B] = Ior.both(NonEmptyChain.one(a), b) } diff --git a/core/src/main/scala/cats/data/IorT.scala b/core/src/main/scala/cats/data/IorT.scala index 7afbff8d2de..c73801db20d 100644 --- a/core/src/main/scala/cats/data/IorT.scala +++ b/core/src/main/scala/cats/data/IorT.scala @@ -7,7 +7,8 @@ import cats.syntax.option._ final case class IorT[F[_], A, B](value: F[Ior[A, B]]) { - def fold[C](fa: A => C, fb: B => C, fab: (A, B) => C)(implicit F: Functor[F]): F[C] = F.map(value)(_.fold(fa, fb, fab)) + def fold[C](fa: A => C, fb: B => C, fab: (A, B) => C)(implicit F: Functor[F]): F[C] = + F.map(value)(_.fold(fa, fb, fab)) def isLeft(implicit F: Functor[F]): F[Boolean] = F.map(value)(_.isLeft) @@ -21,8 +22,8 @@ final case class IorT[F[_], A, B](value: F[Ior[A, B]]) { def getOrElseF[BB >: B](default: => F[BB])(implicit F: Monad[F]): F[BB] = F.flatMap(value) { - case Ior.Left(_) => default - case Ior.Right(b) => F.pure(b) + case Ior.Left(_) => default + case Ior.Right(b) => F.pure(b) case Ior.Both(_, b) => F.pure(b) } @@ -61,20 +62,21 @@ final case class IorT[F[_], A, B](value: F[Ior[A, B]]) { def leftFlatMap[BB >: B, C](f: A => IorT[F, C, BB])(implicit F: Monad[F], BB: Semigroup[BB]): IorT[F, C, BB] = IorT(F.flatMap(value) { - case Ior.Left(a) => f(a).value + case Ior.Left(a) => f(a).value case r @ Ior.Right(_) => F.pure(r.asInstanceOf[Ior[C, BB]]) - case Ior.Both(a, b) => F.map(f(a).value) { - case Ior.Left(c) => Ior.Both(c, b) - case Ior.Right(b1) => Ior.Right(BB.combine(b, b1)) - case Ior.Both(c, b1) => Ior.Both(c, BB.combine(b, b1)) - } + case Ior.Both(a, b) => + F.map(f(a).value) { + case Ior.Left(c) => Ior.Both(c, b) + case Ior.Right(b1) => Ior.Right(BB.combine(b, b1)) + case Ior.Both(c, b1) => Ior.Both(c, BB.combine(b, b1)) + } }) def leftSemiflatMap[C](f: A => F[C])(implicit F: Monad[F]): IorT[F, C, B] = IorT(F.flatMap(value) { - case Ior.Left(a) => F.map(f(a))(Ior.Left(_)) + case Ior.Left(a) => F.map(f(a))(Ior.Left(_)) case r @ Ior.Right(_) => F.pure(r.asInstanceOf[Ior[C, B]]) - case Ior.Both(a, b) => F.map(f(a))(Ior.Both(_, b)) + case Ior.Both(a, b) => F.map(f(a))(Ior.Both(_, b)) }) def transform[C, D](f: Ior[A, B] => Ior[C, D])(implicit F: Functor[F]): IorT[F, C, D] = IorT(F.map(value)(f)) @@ -85,16 +87,17 @@ final case class IorT[F[_], A, B](value: F[Ior[A, B]]) { def flatMap[AA >: A, D](f: B => IorT[F, AA, D])(implicit F: Monad[F], AA: Semigroup[AA]): IorT[F, AA, D] = IorT(F.flatMap(value) { case l @ Ior.Left(_) => F.pure(l.asInstanceOf[Ior[AA, D]]) - case Ior.Right(b) => f(b).value - case Ior.Both(a, b) => F.map(f(b).value) { - case Ior.Left(a1) => Ior.Left(AA.combine(a, a1)) - case Ior.Right(d) => Ior.Both(a, d) - case Ior.Both(a1, d) => Ior.Both(AA.combine(a, a1), d) - } + case Ior.Right(b) => f(b).value + case Ior.Both(a, b) => + F.map(f(b).value) { + case Ior.Left(a1) => Ior.Left(AA.combine(a, a1)) + case Ior.Right(d) => Ior.Both(a, d) + case Ior.Both(a1, d) => Ior.Both(AA.combine(a, a1), d) + } }) def flatMapF[AA >: A, D](f: B => F[Ior[AA, D]])(implicit F: Monad[F], AA: Semigroup[AA]): IorT[F, AA, D] = - flatMap(f andThen IorT.apply) + flatMap(f.andThen(IorT.apply)) def subflatMap[AA >: A, D](f: B => Ior[AA, D])(implicit F: Functor[F], AA: Semigroup[AA]): IorT[F, AA, D] = IorT(F.map(value)(_.flatMap(f))) @@ -102,8 +105,8 @@ final case class IorT[F[_], A, B](value: F[Ior[A, B]]) { def semiflatMap[D](f: B => F[D])(implicit F: Monad[F]): IorT[F, A, D] = IorT(F.flatMap(value) { case l @ Ior.Left(_) => F.pure(l.asInstanceOf[Ior[A, D]]) - case Ior.Right(b) => F.map(f(b))(Ior.right) - case Ior.Both(a, b) => F.map(f(b))(Ior.both(a, _)) + case Ior.Right(b) => F.map(f(b))(Ior.right) + case Ior.Both(a, b) => F.map(f(b))(Ior.both(a, _)) }) def traverse[G[_], D](f: B => G[D])(implicit traverseF: Traverse[F], applicativeG: Applicative[G]): G[IorT[F, A, D]] = @@ -119,287 +122,287 @@ final case class IorT[F[_], A, B](value: F[Ior[A, B]]) { eq.eqv(value, that.value) def combine(that: IorT[F, A, B])(implicit F: Apply[F], A: Semigroup[A], B: Semigroup[B]): IorT[F, A, B] = - IorT(F.map2(this.value, that.value)(_ combine _)) + IorT(F.map2(this.value, that.value)(_.combine(_))) } object IorT extends IorTInstances { /** - * Uses the [[http://typelevel.org/cats/guidelines.html#partially-applied-type-params Partially Applied Type Params technique]] for ergonomics. - */ - private[data] final class LeftPartiallyApplied[B](val dummy: Boolean = true) extends AnyVal { + * Uses the [[http://typelevel.org/cats/guidelines.html#partially-applied-type-params Partially Applied Type Params technique]] for ergonomics. + */ + final private[data] class LeftPartiallyApplied[B](val dummy: Boolean = true) extends AnyVal { def apply[F[_], A](fa: F[A])(implicit F: Functor[F]): IorT[F, A, B] = IorT(F.map(fa)(Ior.left)) } /** - * Creates a left version of `IorT[F, A, B]` from a `F[A]` - * {{{ - * scala> import cats.data.IorT - * scala> import cats.implicits._ - * scala> IorT.left[Int](Option("err")) - * res0: cats.data.IorT[Option,String,Int] = IorT(Some(Left(err))) - * }}} - */ + * Creates a left version of `IorT[F, A, B]` from a `F[A]` + * {{{ + * scala> import cats.data.IorT + * scala> import cats.implicits._ + * scala> IorT.left[Int](Option("err")) + * res0: cats.data.IorT[Option,String,Int] = IorT(Some(Left(err))) + * }}} + */ final def left[B]: LeftPartiallyApplied[B] = new LeftPartiallyApplied[B] /** - * Uses the [[http://typelevel.org/cats/guidelines.html#partially-applied-type-params Partially Applied Type Params technique]] for ergonomics. - */ - private[data] final class LeftTPartiallyApplied[F[_], B](val dummy: Boolean = true) extends AnyVal { + * Uses the [[http://typelevel.org/cats/guidelines.html#partially-applied-type-params Partially Applied Type Params technique]] for ergonomics. + */ + final private[data] class LeftTPartiallyApplied[F[_], B](val dummy: Boolean = true) extends AnyVal { def apply[A](a: A)(implicit F: Applicative[F]): IorT[F, A, B] = IorT(F.pure(Ior.left(a))) } /** - * Creates a left version of `IorT[F, A, B]` from a `A` - * {{{ - * scala> import cats.data.IorT - * scala> import cats.implicits._ - * scala> IorT.leftT[Option, Int]("err") - * res0: cats.data.IorT[Option,String,Int] = IorT(Some(Left(err))) - - * }}} - */ + * Creates a left version of `IorT[F, A, B]` from a `A` + * {{{ + * scala> import cats.data.IorT + * scala> import cats.implicits._ + * scala> IorT.leftT[Option, Int]("err") + * res0: cats.data.IorT[Option,String,Int] = IorT(Some(Left(err))) + + * }}} + */ final def leftT[F[_], B]: LeftTPartiallyApplied[F, B] = new LeftTPartiallyApplied[F, B] /** - * Uses the [[http://typelevel.org/cats/guidelines.html#partially-applied-type-params Partially Applied Type Params technique]] for ergonomics. - */ - private[data] final class RightPartiallyApplied[A](val dummy: Boolean = true) extends AnyVal { + * Uses the [[http://typelevel.org/cats/guidelines.html#partially-applied-type-params Partially Applied Type Params technique]] for ergonomics. + */ + final private[data] class RightPartiallyApplied[A](val dummy: Boolean = true) extends AnyVal { def apply[F[_], B](fb: F[B])(implicit F: Functor[F]): IorT[F, A, B] = IorT(F.map(fb)(Ior.right)) } /** - * Creates a right version of `IorT[F, A, B]` from a `F[B]` - * {{{ - * scala> import cats.data.IorT - * scala> import cats.implicits._ - * scala> IorT.right[String](Option(3)) - * res0: cats.data.IorT[Option,String,Int] = IorT(Some(Right(3))) - * }}} - */ + * Creates a right version of `IorT[F, A, B]` from a `F[B]` + * {{{ + * scala> import cats.data.IorT + * scala> import cats.implicits._ + * scala> IorT.right[String](Option(3)) + * res0: cats.data.IorT[Option,String,Int] = IorT(Some(Right(3))) + * }}} + */ final def right[A]: RightPartiallyApplied[A] = new RightPartiallyApplied[A] /** - * Alias for [[pure]] - * {{{ - * scala> import cats.data.IorT - * scala> import cats.implicits._ - * scala> IorT.rightT[Option, String](3) - * res0: cats.data.IorT[Option,String,Int] = IorT(Some(Right(3))) - * }}} - */ + * Alias for [[pure]] + * {{{ + * scala> import cats.data.IorT + * scala> import cats.implicits._ + * scala> IorT.rightT[Option, String](3) + * res0: cats.data.IorT[Option,String,Int] = IorT(Some(Right(3))) + * }}} + */ final def rightT[F[_], A]: PurePartiallyApplied[F, A] = pure /** - * Creates a both version of `IorT[F, A, B]` from a `F[A]` and a `F[B]` - * {{{ - * scala> import cats.data.IorT - * scala> import cats.implicits._ - * scala> IorT.both(Option("err"), Option(3)) - * res0: cats.data.IorT[Option,String,Int] = IorT(Some(Both(err,3))) - * }}} - */ + * Creates a both version of `IorT[F, A, B]` from a `F[A]` and a `F[B]` + * {{{ + * scala> import cats.data.IorT + * scala> import cats.implicits._ + * scala> IorT.both(Option("err"), Option(3)) + * res0: cats.data.IorT[Option,String,Int] = IorT(Some(Both(err,3))) + * }}} + */ final def both[F[_], A, B](fa: F[A], fb: F[B])(implicit F: Apply[F]): IorT[F, A, B] = IorT(F.map2(fa, fb)((a, b) => Ior.Both(a, b))) /** - * Uses the [[http://typelevel.org/cats/guidelines.html#partially-applied-type-params Partially Applied Type Params technique]] for ergonomics. - */ - private[data] final class BothTPartiallyApplied[F[_]](val dummy: Boolean = true) extends AnyVal { + * Uses the [[http://typelevel.org/cats/guidelines.html#partially-applied-type-params Partially Applied Type Params technique]] for ergonomics. + */ + final private[data] class BothTPartiallyApplied[F[_]](val dummy: Boolean = true) extends AnyVal { def apply[A, B](a: A, b: B)(implicit F: Applicative[F]): IorT[F, A, B] = IorT(F.pure(Ior.Both(a, b))) } /** - * Creates a both version of `IorT[F, A, B]` from a `A` and a `B` - * {{{ - * scala> import cats.data.IorT - * scala> import cats.implicits._ - * scala> IorT.bothT[Option]("err", 3) - * res0: cats.data.IorT[Option,String,Int] = IorT(Some(Both(err,3))) - * }}} - */ + * Creates a both version of `IorT[F, A, B]` from a `A` and a `B` + * {{{ + * scala> import cats.data.IorT + * scala> import cats.implicits._ + * scala> IorT.bothT[Option]("err", 3) + * res0: cats.data.IorT[Option,String,Int] = IorT(Some(Both(err,3))) + * }}} + */ final def bothT[F[_]]: BothTPartiallyApplied[F] = new BothTPartiallyApplied[F] /** - * Uses the [[http://typelevel.org/cats/guidelines.html#partially-applied-type-params Partially Applied Type Params technique]] for ergonomics. - */ - private[data] final class PurePartiallyApplied[F[_], A](val dummy: Boolean = true) extends AnyVal { + * Uses the [[http://typelevel.org/cats/guidelines.html#partially-applied-type-params Partially Applied Type Params technique]] for ergonomics. + */ + final private[data] class PurePartiallyApplied[F[_], A](val dummy: Boolean = true) extends AnyVal { def apply[B](b: B)(implicit F: Applicative[F]): IorT[F, A, B] = IorT(F.pure(Ior.right(b))) } /** - * Creates a right version of `IorT[F, A, B]` from a `B` - * {{{ - * scala> import cats.data.IorT - * scala> import cats.implicits._ - * scala> IorT.pure[Option, String](3) - * res0: cats.data.IorT[Option,String,Int] = IorT(Some(Right(3))) - * }}} - */ + * Creates a right version of `IorT[F, A, B]` from a `B` + * {{{ + * scala> import cats.data.IorT + * scala> import cats.implicits._ + * scala> IorT.pure[Option, String](3) + * res0: cats.data.IorT[Option,String,Int] = IorT(Some(Right(3))) + * }}} + */ final def pure[F[_], A]: PurePartiallyApplied[F, A] = new PurePartiallyApplied[F, A] /** - * Alias for [[right]] - * {{{ - * scala> import cats.data.IorT - * scala> import cats.implicits._ - * scala> val o: Option[Int] = Some(3) - * scala> val n: Option[Int] = None - * scala> IorT.liftF(o) - * res0: cats.data.IorT[Option,Nothing,Int] = IorT(Some(Right(3))) - * scala> IorT.liftF(n) - * res1: cats.data.IorT[Option,Nothing,Int] = IorT(None) - * }}} - */ + * Alias for [[right]] + * {{{ + * scala> import cats.data.IorT + * scala> import cats.implicits._ + * scala> val o: Option[Int] = Some(3) + * scala> val n: Option[Int] = None + * scala> IorT.liftF(o) + * res0: cats.data.IorT[Option,Nothing,Int] = IorT(Some(Right(3))) + * scala> IorT.liftF(n) + * res1: cats.data.IorT[Option,Nothing,Int] = IorT(None) + * }}} + */ final def liftF[F[_], A, B](fb: F[B])(implicit F: Applicative[F]): IorT[F, A, B] = right(fb) /** - * Same as [[liftF]], but expressed as a FunctionK for use with [[IorT.mapK]] - * {{{ - * scala> import cats._, data._, implicits._ - * scala> val a: OptionT[Eval, Int] = 1.pure[OptionT[Eval, ?]] - * scala> val b: OptionT[IorT[Eval, String, ?], Int] = a.mapK(IorT.liftK) - * scala> b.value.value.value - * res0: cats.data.Ior[String,Option[Int]] = Right(Some(1)) - * }}} - */ + * Same as [[liftF]], but expressed as a FunctionK for use with [[IorT.mapK]] + * {{{ + * scala> import cats._, data._, implicits._ + * scala> val a: OptionT[Eval, Int] = 1.pure[OptionT[Eval, ?]] + * scala> val b: OptionT[IorT[Eval, String, ?], Int] = a.mapK(IorT.liftK) + * scala> b.value.value.value + * res0: cats.data.Ior[String,Option[Int]] = Right(Some(1)) + * }}} + */ final def liftK[F[_], A](implicit F: Functor[F]): F ~> IorT[F, A, ?] = new (F ~> IorT[F, A, ?]) { def apply[B](fb: F[B]): IorT[F, A, B] = right(fb) } /** - * Uses the [[http://typelevel.org/cats/guidelines.html#partially-applied-type-params Partially Applied Type Params technique]] for ergonomics. - */ - private[data] final class FromIorPartiallyApplied[F[_]](val dummy: Boolean = true) extends AnyVal { + * Uses the [[http://typelevel.org/cats/guidelines.html#partially-applied-type-params Partially Applied Type Params technique]] for ergonomics. + */ + final private[data] class FromIorPartiallyApplied[F[_]](val dummy: Boolean = true) extends AnyVal { def apply[A, B](ior: Ior[A, B])(implicit F: Applicative[F]): IorT[F, A, B] = IorT(F.pure(ior)) } /** - * Transforms an `Ior` into an `IorT`, lifted into the specified `Applicative`. - * {{{ - * scala> import cats.data.{IorT, Ior} - * scala> import cats.implicits._ - * scala> val i: Ior[String, Int] = Ior.both("warning", 3) - * scala> IorT.fromIor[Option](i) - * res0: cats.data.IorT[Option,String,Int] = IorT(Some(Both(warning,3))) - * }}} - */ + * Transforms an `Ior` into an `IorT`, lifted into the specified `Applicative`. + * {{{ + * scala> import cats.data.{IorT, Ior} + * scala> import cats.implicits._ + * scala> val i: Ior[String, Int] = Ior.both("warning", 3) + * scala> IorT.fromIor[Option](i) + * res0: cats.data.IorT[Option,String,Int] = IorT(Some(Both(warning,3))) + * }}} + */ final def fromIor[F[_]]: FromIorPartiallyApplied[F] = new FromIorPartiallyApplied[F] /** - * Uses the [[http://typelevel.org/cats/guidelines.html#partially-applied-type-params Partially Applied Type Params technique]] for ergonomics. - */ - private[data] final class FromEitherPartiallyApplied[F[_]](val dummy: Boolean = true) extends AnyVal { + * Uses the [[http://typelevel.org/cats/guidelines.html#partially-applied-type-params Partially Applied Type Params technique]] for ergonomics. + */ + final private[data] class FromEitherPartiallyApplied[F[_]](val dummy: Boolean = true) extends AnyVal { def apply[E, A](either: Either[E, A])(implicit F: Applicative[F]): IorT[F, E, A] = IorT(F.pure(either.toIor)) } /** - * Transforms an `Either` into an `IorT`, lifted into the specified `Applicative`. - * {{{ - * scala> import cats.data.IorT - * scala> import cats.implicits._ - * scala> val e: Either[String, Int] = Either.right(3) - * scala> IorT.fromEither[Option](e) - * res0: cats.data.IorT[Option,String,Int] = IorT(Some(Right(3))) - * }}} - */ + * Transforms an `Either` into an `IorT`, lifted into the specified `Applicative`. + * {{{ + * scala> import cats.data.IorT + * scala> import cats.implicits._ + * scala> val e: Either[String, Int] = Either.right(3) + * scala> IorT.fromEither[Option](e) + * res0: cats.data.IorT[Option,String,Int] = IorT(Some(Right(3))) + * }}} + */ final def fromEither[F[_]]: FromEitherPartiallyApplied[F] = new FromEitherPartiallyApplied[F] /** - * Transforms an `F[Either]` into an `IorT`. - * {{{ - * scala> import cats.data.IorT - * scala> import cats.implicits._ - * scala> val e: Either[String, Int] = Either.right(3) - * scala> IorT.fromEitherF(Option(e)) - * res0: cats.data.IorT[Option,String,Int] = IorT(Some(Right(3))) - * }}} - */ + * Transforms an `F[Either]` into an `IorT`. + * {{{ + * scala> import cats.data.IorT + * scala> import cats.implicits._ + * scala> val e: Either[String, Int] = Either.right(3) + * scala> IorT.fromEitherF(Option(e)) + * res0: cats.data.IorT[Option,String,Int] = IorT(Some(Right(3))) + * }}} + */ final def fromEitherF[F[_], E, A](feither: F[Either[E, A]])(implicit F: Functor[F]): IorT[F, E, A] = IorT(F.map(feither)(_.toIor)) /** - * Uses the [[http://typelevel.org/cats/guidelines.html#partially-applied-type-params Partially Applied Type Params technique]] for ergonomics. - */ - private[data] final class FromOptionPartiallyApplied[F[_]](val dummy: Boolean = true) extends AnyVal { + * Uses the [[http://typelevel.org/cats/guidelines.html#partially-applied-type-params Partially Applied Type Params technique]] for ergonomics. + */ + final private[data] class FromOptionPartiallyApplied[F[_]](val dummy: Boolean = true) extends AnyVal { def apply[E, A](option: Option[A], ifNone: => E)(implicit F: Applicative[F]): IorT[F, E, A] = IorT(F.pure(option.toRightIor(ifNone))) } /** - * Transforms an `Option` into an `IorT`, lifted into the specified `Applicative` and using - * the second argument if the `Option` is a `None`. - * {{{ - * scala> import cats.data.IorT - * scala> import cats.implicits._ - * scala> val o: Option[Int] = None - * scala> IorT.fromOption[List](o, "Answer not known.") - * res0: cats.data.IorT[List,String,Int] = IorT(List(Left(Answer not known.))) - * scala> IorT.fromOption[List](Some(42), "Answer not known.") - * res1: cats.data.IorT[List,String,Int] = IorT(List(Right(42))) - * }}} - */ + * Transforms an `Option` into an `IorT`, lifted into the specified `Applicative` and using + * the second argument if the `Option` is a `None`. + * {{{ + * scala> import cats.data.IorT + * scala> import cats.implicits._ + * scala> val o: Option[Int] = None + * scala> IorT.fromOption[List](o, "Answer not known.") + * res0: cats.data.IorT[List,String,Int] = IorT(List(Left(Answer not known.))) + * scala> IorT.fromOption[List](Some(42), "Answer not known.") + * res1: cats.data.IorT[List,String,Int] = IorT(List(Right(42))) + * }}} + */ final def fromOption[F[_]]: FromOptionPartiallyApplied[F] = new FromOptionPartiallyApplied[F] /** - * Transforms an `F[Option]` into an `IorT`, using the second argument if the `Option` is a `None`. - * {{{ - * scala> import cats.data.IorT - * scala> import cats.implicits._ - * scala> val o: Option[Int] = None - * scala> IorT.fromOptionF(List(o), "Answer not known.") - * res0: cats.data.IorT[List,String,Int] = IorT(List(Left(Answer not known.))) - * scala> IorT.fromOptionF(List(Option(42)), "Answer not known.") - * res1: cats.data.IorT[List,String,Int] = IorT(List(Right(42))) - * }}} - */ + * Transforms an `F[Option]` into an `IorT`, using the second argument if the `Option` is a `None`. + * {{{ + * scala> import cats.data.IorT + * scala> import cats.implicits._ + * scala> val o: Option[Int] = None + * scala> IorT.fromOptionF(List(o), "Answer not known.") + * res0: cats.data.IorT[List,String,Int] = IorT(List(Left(Answer not known.))) + * scala> IorT.fromOptionF(List(Option(42)), "Answer not known.") + * res1: cats.data.IorT[List,String,Int] = IorT(List(Right(42))) + * }}} + */ final def fromOptionF[F[_], E, A](foption: F[Option[A]], ifNone: => E)(implicit F: Functor[F]): IorT[F, E, A] = IorT(F.map(foption)(_.toRightIor(ifNone))) /** - * Uses the [[http://typelevel.org/cats/guidelines.html#partially-applied-type-params Partially Applied Type Params technique]] for ergonomics. - */ - private[data] final class CondPartiallyApplied[F[_]](val dummy: Boolean = true) extends AnyVal { + * Uses the [[http://typelevel.org/cats/guidelines.html#partially-applied-type-params Partially Applied Type Params technique]] for ergonomics. + */ + final private[data] class CondPartiallyApplied[F[_]](val dummy: Boolean = true) extends AnyVal { def apply[A, B](test: Boolean, right: => B, left: => A)(implicit F: Applicative[F]): IorT[F, A, B] = IorT(F.pure(if (test) Ior.right(right) else Ior.left(left))) } /** - * If the condition is satisfied, return the given `B` in `Ior.Right`, otherwise, return the given - * `A` in `Ior.Left`, lifted into the specified `Applicative`. - * {{{ - * scala> import cats.data.IorT - * scala> import cats.implicits._ - * scala> val userInput = "hello world" - * scala> IorT.cond[Option]( - * | userInput.forall(_.isDigit) && userInput.size == 10, - * | userInput, - * | "The input does not look like a phone number") - * res0: cats.data.IorT[Option,String,String] = IorT(Some(Left(The input does not look like a phone number))) - * }}} - */ + * If the condition is satisfied, return the given `B` in `Ior.Right`, otherwise, return the given + * `A` in `Ior.Left`, lifted into the specified `Applicative`. + * {{{ + * scala> import cats.data.IorT + * scala> import cats.implicits._ + * scala> val userInput = "hello world" + * scala> IorT.cond[Option]( + * | userInput.forall(_.isDigit) && userInput.size == 10, + * | userInput, + * | "The input does not look like a phone number") + * res0: cats.data.IorT[Option,String,String] = IorT(Some(Left(The input does not look like a phone number))) + * }}} + */ final def cond[F[_]]: CondPartiallyApplied[F] = new CondPartiallyApplied[F] /** - * If the condition is satisfied, return the value of `IorT.right` on `F[B]`, otherwise, return the - * value of `IorT.left` on `F[A]`. - * {{{ - * scala> import cats.data.IorT - * scala> import cats.implicits._ - * scala> val userInput = "hello world" - * scala> IorT.condF[Option, String, String]( - * | userInput.forall(_.isDigit) && userInput.size == 10, - * | Some(userInput), - * | None) - * res0: cats.data.IorT[Option,String,String] = IorT(None) - * }}} - */ + * If the condition is satisfied, return the value of `IorT.right` on `F[B]`, otherwise, return the + * value of `IorT.left` on `F[A]`. + * {{{ + * scala> import cats.data.IorT + * scala> import cats.implicits._ + * scala> val userInput = "hello world" + * scala> IorT.condF[Option, String, String]( + * | userInput.forall(_.isDigit) && userInput.size == 10, + * | Some(userInput), + * | None) + * res0: cats.data.IorT[Option,String,String] = IorT(None) + * }}} + */ final def condF[F[_], A, B](test: Boolean, right: => F[B], left: => F[A])(implicit F: Functor[F]): IorT[F, A, B] = IorT(if (test) F.map(right)(Ior.right) else F.map(left)(Ior.left)) } -private[data] abstract class IorTInstances extends IorTInstances1 { +abstract private[data] class IorTInstances extends IorTInstances1 { implicit def catsDataShowForIorT[F[_], A, B](implicit sh: Show[F[Ior[A, B]]]): Show[IorT[F, A, B]] = Contravariant[Show].contramap(sh)(_.value) @@ -415,29 +418,30 @@ private[data] abstract class IorTInstances extends IorTInstances1 { implicit def catsDataMonoidForIorT[F[_], A, B](implicit F: Monoid[F[Ior[A, B]]]): Monoid[IorT[F, A, B]] = new IorTMonoid[F, A, B] { val F0: Monoid[F[Ior[A, B]]] = F } - implicit def catsDataParallelForIorTWithParallelEffect[M[_], F[_], E] - (implicit P: Parallel[M, F], E: Semigroup[E]) - : Parallel[IorT[M, E, ?], IorT[F, E, ?]] { type Dummy } - = new Parallel[IorT[M, E, ?], IorT[F, E, ?]] { - type Dummy // fix to make this one more specific than the catsDataParallelForIorTWithSequentialEffect, see https://github.com/typelevel/cats/pull/2335#issuecomment-408249775 + implicit def catsDataParallelForIorTWithParallelEffect[M[_], F[_], E]( + implicit P: Parallel[M, F], + E: Semigroup[E] + ): Parallel[IorT[M, E, ?], IorT[F, E, ?]] { type Dummy } = new Parallel[IorT[M, E, ?], IorT[F, E, ?]] { + type Dummy // fix to make this one more specific than the catsDataParallelForIorTWithSequentialEffect, see https://github.com/typelevel/cats/pull/2335#issuecomment-408249775 - val parallel: IorT[M, E, ?] ~> IorT[F, E, ?] = λ[IorT[M, E, ?] ~> IorT[F, E, ?]](fm => IorT(P.parallel(fm.value))) - val sequential: IorT[F, E, ?] ~> IorT[M, E, ?] = λ[IorT[F, E, ?] ~> IorT[M, E, ?]](ff => IorT(P.sequential(ff.value))) + val parallel: IorT[M, E, ?] ~> IorT[F, E, ?] = λ[IorT[M, E, ?] ~> IorT[F, E, ?]](fm => IorT(P.parallel(fm.value))) + val sequential: IorT[F, E, ?] ~> IorT[M, E, ?] = + λ[IorT[F, E, ?] ~> IorT[M, E, ?]](ff => IorT(P.sequential(ff.value))) - private[this] val FA: Applicative[F] = P.applicative - private[this] val IorA: Applicative[Ior[E, ?]] = Parallel[Ior[E, ?], Ior[E, ?]].applicative + private[this] val FA: Applicative[F] = P.applicative + private[this] val IorA: Applicative[Ior[E, ?]] = Parallel[Ior[E, ?], Ior[E, ?]].applicative - val applicative: Applicative[IorT[F, E, ?]] = new Applicative[IorT[F, E, ?]] { - def pure[A](a: A): IorT[F, E, A] = IorT.pure(a)(FA) - def ap[A, B](ff: IorT[F, E, A => B])(fa: IorT[F, E, A]): IorT[F, E, B] = - IorT(FA.map2(ff.value, fa.value)((f, a) => IorA.ap(f)(a))) - } + val applicative: Applicative[IorT[F, E, ?]] = new Applicative[IorT[F, E, ?]] { + def pure[A](a: A): IorT[F, E, A] = IorT.pure(a)(FA) + def ap[A, B](ff: IorT[F, E, A => B])(fa: IorT[F, E, A]): IorT[F, E, B] = + IorT(FA.map2(ff.value, fa.value)((f, a) => IorA.ap(f)(a))) + } - lazy val monad: Monad[IorT[M, E, ?]] = { - implicit def underlyingMonadM: Monad[M] = P.monad - Monad[IorT[M, E, ?]] - } + lazy val monad: Monad[IorT[M, E, ?]] = { + implicit def underlyingMonadM: Monad[M] = P.monad + Monad[IorT[M, E, ?]] } + } implicit def catsDataDeferForIor[F[_], E](implicit F: Defer[F]): Defer[IorT[F, E, ?]] = new Defer[IorT[F, E, ?]] { @@ -446,7 +450,7 @@ private[data] abstract class IorTInstances extends IorTInstances1 { } } -private[data] abstract class IorTInstances1 extends IorTInstances2 { +abstract private[data] class IorTInstances1 extends IorTInstances2 { implicit def catsDataSemigroupForIorT[F[_], A, B](implicit F: Semigroup[F[Ior[A, B]]]): Semigroup[IorT[F, A, B]] = new IorTSemigroup[F, A, B] { val F0: Semigroup[F[Ior[A, B]]] = F } @@ -459,8 +463,10 @@ private[data] abstract class IorTInstances1 extends IorTInstances2 { val F0: Monad[F] = F } - implicit def catsDataParallelForIorTWithSequentialEffect[F[_], E] - (implicit F: Monad[F], E: Semigroup[E]): Parallel[IorT[F, E, ?], IorT[F, E, ?]] = new Parallel[IorT[F, E, ?], IorT[F, E, ?]] { + implicit def catsDataParallelForIorTWithSequentialEffect[F[_], E]( + implicit F: Monad[F], + E: Semigroup[E] + ): Parallel[IorT[F, E, ?], IorT[F, E, ?]] = new Parallel[IorT[F, E, ?], IorT[F, E, ?]] { private[this] val identityK: IorT[F, E, ?] ~> IorT[F, E, ?] = FunctionK.id private[this] val underlyingParallel: Parallel[Ior[E, ?], Ior[E, ?]] = Parallel[Ior[E, ?], Ior[E, ?]] @@ -479,8 +485,9 @@ private[data] abstract class IorTInstances1 extends IorTInstances2 { } -private[data] abstract class IorTInstances2 extends IorTInstances3 { - implicit def catsDataMonadErrorFForIorT[F[_], A, E](implicit FE: MonadError[F, E], A: Semigroup[A]): MonadError[IorT[F, A, ?], E] = +abstract private[data] class IorTInstances2 extends IorTInstances3 { + implicit def catsDataMonadErrorFForIorT[F[_], A, E](implicit FE: MonadError[F, E], + A: Semigroup[A]): MonadError[IorT[F, A, ?], E] = new IorTMonadErrorF[F, A, E] { val A0: Semigroup[A] = A val F0: MonadError[F, E] = FE @@ -490,55 +497,56 @@ private[data] abstract class IorTInstances2 extends IorTInstances3 { new IorTEq[F, A, B] { val F0: Eq[F[Ior[A, B]]] = F } } -private[data] abstract class IorTInstances3 { +abstract private[data] class IorTInstances3 { implicit def catsDataFunctorForIorT[F[_], A](implicit F: Functor[F]): Functor[IorT[F, A, ?]] = new IorTFunctor[F, A] { val F0: Functor[F] = F } } -private[data] sealed trait IorTFunctor[F[_], A] extends Functor[IorT[F, A, ?]] { +sealed private[data] trait IorTFunctor[F[_], A] extends Functor[IorT[F, A, ?]] { implicit def F0: Functor[F] override def map[B, D](iort: IorT[F, A, B])(f: B => D): IorT[F, A, D] = iort.map(f) } -private[data] sealed trait IorTEq[F[_], A, B] extends Eq[IorT[F, A, B]] { +sealed private[data] trait IorTEq[F[_], A, B] extends Eq[IorT[F, A, B]] { implicit def F0: Eq[F[Ior[A, B]]] override def eqv(x: IorT[F, A, B], y: IorT[F, A, B]): Boolean = x === y } -private[data] sealed trait IorTMonad[F[_], A] extends Monad[IorT[F, A, ?]] with IorTFunctor[F, A] { +sealed private[data] trait IorTMonad[F[_], A] extends Monad[IorT[F, A, ?]] with IorTFunctor[F, A] { implicit def A0: Semigroup[A] - override implicit def F0: Monad[F] + implicit override def F0: Monad[F] override def pure[B](b: B): IorT[F, A, B] = IorT.pure(b) override def flatMap[B, D](iort: IorT[F, A, B])(f: B => IorT[F, A, D]): IorT[F, A, D] = iort.flatMap(f) override def tailRecM[B, D](b: B)(f: B => IorT[F, A, Either[B, D]]): IorT[F, A, D] = - IorT(F0.tailRecM(Tuple2[B, Option[A]](b, None)) { case (b0, optionA) => - F0.map(f(b0).value) { - case Ior.Left(aa) => Right(Ior.Left(Semigroup.maybeCombine(optionA, aa))) - case Ior.Right(Left(b1)) => Left(b1 -> optionA) - case Ior.Right(Right(d)) => Right(optionA.fold(Ior.right[A, D](d))(Ior.both(_, d))) - case Ior.Both(aa, Right(d)) => Right(Ior.both(Semigroup.maybeCombine(optionA, aa), d)) - case Ior.Both(aa, Left(b1)) => Left(b1 -> Some(Semigroup.maybeCombine(optionA, aa))) - } + IorT(F0.tailRecM(Tuple2[B, Option[A]](b, None)) { + case (b0, optionA) => + F0.map(f(b0).value) { + case Ior.Left(aa) => Right(Ior.Left(Semigroup.maybeCombine(optionA, aa))) + case Ior.Right(Left(b1)) => Left(b1 -> optionA) + case Ior.Right(Right(d)) => Right(optionA.fold(Ior.right[A, D](d))(Ior.both(_, d))) + case Ior.Both(aa, Right(d)) => Right(Ior.both(Semigroup.maybeCombine(optionA, aa), d)) + case Ior.Both(aa, Left(b1)) => Left(b1 -> Some(Semigroup.maybeCombine(optionA, aa))) + } }) } -private[data] sealed trait IorTMonadError[F[_], A] extends MonadError[IorT[F, A, ?], A] with IorTMonad[F, A] { +sealed private[data] trait IorTMonadError[F[_], A] extends MonadError[IorT[F, A, ?], A] with IorTMonad[F, A] { override def raiseError[B](a: A): IorT[F, A, B] = IorT(F0.pure(Ior.left(a))) override def handleErrorWith[B](iort: IorT[F, A, B])(f: A => IorT[F, A, B]): IorT[F, A, B] = IorT(F0.flatMap(iort.value) { - case Ior.Left(a) => f(a).value - case r @ (Ior.Right(_) | Ior.Both(_, _)) => F0.pure(r) + case Ior.Left(a) => f(a).value + case r @ (Ior.Right(_) | Ior.Both(_, _)) => F0.pure(r) }) } -private[data] sealed trait IorTMonadErrorF[F[_], A, E] extends MonadError[IorT[F, A, ?], E] with IorTMonad[F, A] { - override implicit def F0: MonadError[F, E] +sealed private[data] trait IorTMonadErrorF[F[_], A, E] extends MonadError[IorT[F, A, ?], E] with IorTMonad[F, A] { + implicit override def F0: MonadError[F, E] override def raiseError[B](e: E): IorT[F, A, B] = IorT(F0.raiseError(e)) @@ -546,29 +554,30 @@ private[data] sealed trait IorTMonadErrorF[F[_], A, E] extends MonadError[IorT[F IorT(F0.handleErrorWith(iort.value)(f(_).value)) } -private[data] sealed trait IorTSemigroup[F[_], A, B] extends Semigroup[IorT[F, A, B]] { +sealed private[data] trait IorTSemigroup[F[_], A, B] extends Semigroup[IorT[F, A, B]] { implicit def F0: Semigroup[F[Ior[A, B]]] override def combine(x: IorT[F, A, B], y: IorT[F, A, B]): IorT[F, A, B] = IorT(F0.combine(x.value, y.value)) } -private[data] sealed trait IorTMonoid[F[_], A, B] extends Monoid[IorT[F, A, B]] with IorTSemigroup[F, A, B] { - override implicit def F0: Monoid[F[Ior[A, B]]] +sealed private[data] trait IorTMonoid[F[_], A, B] extends Monoid[IorT[F, A, B]] with IorTSemigroup[F, A, B] { + implicit override def F0: Monoid[F[Ior[A, B]]] override def empty: IorT[F, A, B] = IorT(F0.empty) } -private[data] sealed trait IorTFoldable[F[_], A] extends Foldable[IorT[F, A, ?]] { +sealed private[data] trait IorTFoldable[F[_], A] extends Foldable[IorT[F, A, ?]] { implicit def F0: Foldable[F] override def foldLeft[B, C](iort: IorT[F, A, B], c: C)(f: (C, B) => C): C = iort.foldLeft(c)(f) - override def foldRight[B, C](iort: IorT[F, A, B], lc: Eval[C])(f: (B, Eval[C]) => Eval[C]): Eval[C] = iort.foldRight(lc)(f) + override def foldRight[B, C](iort: IorT[F, A, B], lc: Eval[C])(f: (B, Eval[C]) => Eval[C]): Eval[C] = + iort.foldRight(lc)(f) } -private[data] sealed trait IorTTraverse[F[_], A] extends Traverse[IorT[F, A, ?]] with IorTFoldable[F, A] { - override implicit def F0: Traverse[F] +sealed private[data] trait IorTTraverse[F[_], A] extends Traverse[IorT[F, A, ?]] with IorTFoldable[F, A] { + implicit override def F0: Traverse[F] - override def traverse[G[_] : Applicative, B, D](iort: IorT[F, A, B])(f: B => G[D]): G[IorT[F, A, D]] = iort.traverse(f) + override def traverse[G[_]: Applicative, B, D](iort: IorT[F, A, B])(f: B => G[D]): G[IorT[F, A, D]] = iort.traverse(f) } diff --git a/core/src/main/scala/cats/data/Kleisli.scala b/core/src/main/scala/cats/data/Kleisli.scala index 3de50bf77c0..4d937a1c3a6 100644 --- a/core/src/main/scala/cats/data/Kleisli.scala +++ b/core/src/main/scala/cats/data/Kleisli.scala @@ -5,8 +5,8 @@ import cats.{Contravariant, Id} import cats.arrow._ /** - * Represents a function `A => F[B]`. - */ + * Represents a function `A => F[B]`. + */ final case class Kleisli[F[_], A, B](run: A => F[B]) { self => def ap[C](f: Kleisli[F, A, B => C])(implicit F: Apply[F]): Kleisli[F, A, C] = @@ -19,13 +19,13 @@ final case class Kleisli[F[_], A, B](run: A => F[B]) { self => Kleisli(a => F.map(run(a))(f)) def mapF[N[_], C](f: F[B] => N[C]): Kleisli[N, A, C] = - Kleisli(run andThen f) + Kleisli(run.andThen(f)) /** - * Modify the context `F` using transformation `f`. - */ + * Modify the context `F` using transformation `f`. + */ def mapK[G[_]](f: F ~> G): Kleisli[G, A, B] = - Kleisli[G, A, B](run andThen f.apply) + Kleisli[G, A, B](run.andThen(f.apply)) def flatMap[C](f: B => Kleisli[F, A, C])(implicit F: FlatMap[F]): Kleisli[F, A, C] = Kleisli.shift(a => F.flatMap[B, C](run(a))((b: B) => f(b).run(a))) @@ -37,13 +37,13 @@ final case class Kleisli[F[_], A, B](run: A => F[B]) { self => Kleisli.shift(a => F.flatMap(run(a))(f)) def andThen[C](k: Kleisli[F, B, C])(implicit F: FlatMap[F]): Kleisli[F, A, C] = - this andThen k.run + this.andThen(k.run) def compose[Z](f: Z => F[A])(implicit F: FlatMap[F]): Kleisli[F, Z, B] = Kleisli.shift((z: Z) => F.flatMap(f(z))(run)) def compose[Z](k: Kleisli[F, Z, A])(implicit F: FlatMap[F]): Kleisli[F, Z, B] = - this compose k.run + this.compose(k.run) def traverse[G[_]](f: G[A])(implicit F: Applicative[F], G: Traverse[G]): F[G[B]] = G.traverse(f)(run) @@ -62,10 +62,10 @@ final case class Kleisli[F[_], A, B](run: A => F[B]) { self => Kleisli(a => F.pure(run(a))) def first[C](implicit F: Functor[F]): Kleisli[F, (A, C), (B, C)] = - Kleisli{ case (a, c) => F.fproduct(run(a))(_ => c)} + Kleisli { case (a, c) => F.fproduct(run(a))(_ => c) } def second[C](implicit F: Functor[F]): Kleisli[F, (C, A), (C, B)] = - Kleisli{ case (c, a) => F.map(run(a))(c -> _)} + Kleisli { case (c, a) => F.map(run(a))(c -> _) } /** Discard computed B and yield the input value. */ def tap(implicit F: Functor[F]): Kleisli[F, A, A] = @@ -84,50 +84,48 @@ final case class Kleisli[F[_], A, B](run: A => F[B]) { self => } object Kleisli extends KleisliInstances with KleisliFunctions with KleisliExplicitInstances { - /** - * Internal API — shifts the execution of `run` in the `F` context. - * - * Used to build Kleisli values for `F[_]` data types that implement `Monad`, - * in which case it is safer to trigger the `F[_]` context earlier. - * - * The requirement is for `FlatMap` as this will get used in operations - * that invoke `F.flatMap` (e.g. in `Kleisli#flatMap`). However we are - * doing discrimination based on inheritance and if we detect an - * `Applicative`, then we use it to trigger the `F[_]` context earlier. - * - * Triggering the `F[_]` context earlier is important to avoid stack - * safety issues for `F` monads that have a stack safe `flatMap` - * implementation. For example `Eval` or `IO`. Without this the `Monad` - * instance is stack unsafe, even if the underlying `F` is stack safe - * in `flatMap`. - */ - private[data] def shift[F[_], A, B](run: A => F[B]) - (implicit F: FlatMap[F]): Kleisli[F, A, B] = { + /** + * Internal API — shifts the execution of `run` in the `F` context. + * + * Used to build Kleisli values for `F[_]` data types that implement `Monad`, + * in which case it is safer to trigger the `F[_]` context earlier. + * + * The requirement is for `FlatMap` as this will get used in operations + * that invoke `F.flatMap` (e.g. in `Kleisli#flatMap`). However we are + * doing discrimination based on inheritance and if we detect an + * `Applicative`, then we use it to trigger the `F[_]` context earlier. + * + * Triggering the `F[_]` context earlier is important to avoid stack + * safety issues for `F` monads that have a stack safe `flatMap` + * implementation. For example `Eval` or `IO`. Without this the `Monad` + * instance is stack unsafe, even if the underlying `F` is stack safe + * in `flatMap`. + */ + private[data] def shift[F[_], A, B](run: A => F[B])(implicit F: FlatMap[F]): Kleisli[F, A, B] = F match { case ap: Applicative[F] @unchecked => Kleisli(r => F.flatMap(ap.pure(r))(run)) case _ => Kleisli(run) } - } } -private[data] sealed trait KleisliFunctions { +sealed private[data] trait KleisliFunctions { def liftF[F[_], A, B](x: F[B]): Kleisli[F, A, B] = Kleisli(_ => x) /** - * Same as [[liftF]], but expressed as a FunctionK for use with mapK - * {{{ - * scala> import cats._, data._, implicits._ - * scala> val a: OptionT[Eval, Int] = 1.pure[OptionT[Eval, ?]] - * scala> val b: OptionT[Kleisli[Eval, String, ?], Int] = a.mapK(Kleisli.liftK) - * scala> b.value.run("").value - * res0: Option[Int] = Some(1) - * }}} - */ + * Same as [[liftF]], but expressed as a FunctionK for use with mapK + * {{{ + * scala> import cats._, data._, implicits._ + * scala> val a: OptionT[Eval, Int] = 1.pure[OptionT[Eval, ?]] + * scala> val b: OptionT[Kleisli[Eval, String, ?], Int] = a.mapK(Kleisli.liftK) + * scala> b.value.run("").value + * res0: Option[Int] = Some(1) + * }}} + */ def liftK[F[_], A]: F ~> Kleisli[F, A, ?] = λ[F ~> Kleisli[F, A, ?]](Kleisli.liftF(_)) @@ -142,20 +140,19 @@ private[data] sealed trait KleisliFunctions { Kleisli(F.pure) def local[M[_], A, R](f: R => R)(fa: Kleisli[M, R, A]): Kleisli[M, R, A] = - Kleisli(f andThen fa.run) + Kleisli(f.andThen(fa.run)) } -private[data] sealed trait KleisliExplicitInstances { +sealed private[data] trait KleisliExplicitInstances { def endoSemigroupK[F[_]](implicit FM: FlatMap[F]): SemigroupK[λ[α => Kleisli[F, α, α]]] = Compose[Kleisli[F, ?, ?]].algebraK - def endoMonoidK[F[_]](implicit M: Monad[F]): MonoidK[λ[α => Kleisli[F, α, α]]] = Category[Kleisli[F, ?, ?]].algebraK } -private[data] sealed abstract class KleisliInstances extends KleisliInstances0 { +sealed abstract private[data] class KleisliInstances extends KleisliInstances0 { implicit def catsDataMonadForKleisliId[A]: CommutativeMonad[Kleisli[Id, A, ?]] = catsDataCommutativeMonadForKleisli[Id, A] @@ -166,28 +163,36 @@ private[data] sealed abstract class KleisliInstances extends KleisliInstances0 { new Defer[Kleisli[F, A, ?]] { def defer[B](fa: => Kleisli[F, A, B]): Kleisli[F, A, B] = { lazy val cacheFa = fa - Kleisli[F, A, B] { a => F.defer(cacheFa.run(a)) } + Kleisli[F, A, B] { a => + F.defer(cacheFa.run(a)) + } } } } -private[data] sealed abstract class KleisliInstances0 extends KleisliInstances0_5 { +sealed abstract private[data] class KleisliInstances0 extends KleisliInstances0_5 { - implicit def catsDataCommutativeArrowForKleisli[F[_]](implicit M: CommutativeMonad[F]): CommutativeArrow[Kleisli[F, ?, ?]] with ArrowChoice[Kleisli[F, ?, ?]] = - new KleisliCommutativeArrow[F] {def F: CommutativeMonad[F] = M } + implicit def catsDataCommutativeArrowForKleisli[F[_]]( + implicit M: CommutativeMonad[F] + ): CommutativeArrow[Kleisli[F, ?, ?]] with ArrowChoice[Kleisli[F, ?, ?]] = + new KleisliCommutativeArrow[F] { def F: CommutativeMonad[F] = M } - implicit def catsDataCommutativeMonadForKleisli[F[_], A](implicit F0: CommutativeMonad[F]): CommutativeMonad[Kleisli[F, A, ?]] = + implicit def catsDataCommutativeMonadForKleisli[F[_], A]( + implicit F0: CommutativeMonad[F] + ): CommutativeMonad[Kleisli[F, A, ?]] = new KleisliMonad[F, A] with CommutativeMonad[Kleisli[F, A, ?]] { implicit def F: Monad[F] = F0 } } -private[data] sealed abstract class KleisliInstances0_5 extends KleisliInstances1 { +sealed abstract private[data] class KleisliInstances0_5 extends KleisliInstances1 { implicit def catsDataMonoidForKleisli[F[_], A, B](implicit FB0: Monoid[F[B]]): Monoid[Kleisli[F, A, B]] = new KleisliMonoid[F, A, B] { def FB: Monoid[F[B]] = FB0 } - implicit def catsDataMonadErrorForKleisli[F[_], A, E](implicit ME: MonadError[F, E]): MonadError[Kleisli[F, A, ?], E] = + implicit def catsDataMonadErrorForKleisli[F[_], A, E]( + implicit ME: MonadError[F, E] + ): MonadError[Kleisli[F, A, ?], E] = new KleisliMonadError[F, A, E] { def F: MonadError[F, E] = ME } implicit def catsDataArrowChoiceForKleisli[F[_]](implicit M: Monad[F]): ArrowChoice[Kleisli[F, ?, ?]] = @@ -195,42 +200,44 @@ private[data] sealed abstract class KleisliInstances0_5 extends KleisliInstances def F: Monad[F] = M } - implicit def catsDataContravariantMonoidalForKleisli[F[_], A](implicit F0: ContravariantMonoidal[F]): ContravariantMonoidal[Kleisli[F, A, ?]] = - new KleisliContravariantMonoidal[F, A] { def F: ContravariantMonoidal[F] = F0 } + implicit def catsDataContravariantMonoidalForKleisli[F[_], A]( + implicit F0: ContravariantMonoidal[F] + ): ContravariantMonoidal[Kleisli[F, A, ?]] = + new KleisliContravariantMonoidal[F, A] { def F: ContravariantMonoidal[F] = F0 } /** - * Witness for: Kleisli[M, E, A] <-> (E, R) => A - * if M is Representable - */ - implicit def catsDataRepresentableForKleisli[M[_], R, E](implicit + * Witness for: Kleisli[M, E, A] <-> (E, R) => A + * if M is Representable + */ + implicit def catsDataRepresentableForKleisli[M[_], R, E]( + implicit R: Representable.Aux[M, R], - FK: Functor[Kleisli[M, E, ?]]): Representable.Aux[Kleisli[M, E, ?], (E, R)] = new Representable[Kleisli[M, E, ?]] { + FK: Functor[Kleisli[M, E, ?]] + ): Representable.Aux[Kleisli[M, E, ?], (E, R)] = new Representable[Kleisli[M, E, ?]] { - override type Representation = (E, R) + override type Representation = (E, R) - override val F: Functor[Kleisli[M, E, ?]] = FK + override val F: Functor[Kleisli[M, E, ?]] = FK - def index[A](f: Kleisli[M, E, A]): Representation => A = { - case (e, r) => R.index(f.run(e))(r) - } + def index[A](f: Kleisli[M, E, A]): Representation => A = { + case (e, r) => R.index(f.run(e))(r) + } - def tabulate[A](f: Representation => A): Kleisli[M, E, A] = { - def curry[X, Y, Z](f: (X, Y) => Z): X => Y => Z = x => y => f(x, y) + def tabulate[A](f: Representation => A): Kleisli[M, E, A] = { + def curry[X, Y, Z](f: (X, Y) => Z): X => Y => Z = x => y => f(x, y) - Kleisli[M, E, A](curry(Function.untupled(f)) andThen R.tabulate) - } + Kleisli[M, E, A](curry(Function.untupled(f)).andThen(R.tabulate)) } + } } -private[data] sealed abstract class KleisliInstances1 extends KleisliInstances2 { +sealed abstract private[data] class KleisliInstances1 extends KleisliInstances2 { implicit def catsDataMonadForKleisli[F[_], A](implicit M: Monad[F]): Monad[Kleisli[F, A, ?]] = new KleisliMonad[F, A] { def F: Monad[F] = M } - - - - implicit def catsDataParallelForKleisli[F[_], M[_], A] - (implicit P: Parallel[M, F]): Parallel[Kleisli[M, A, ?], Kleisli[F, A, ?]] = new Parallel[Kleisli[M, A, ?], Kleisli[F, A, ?]]{ + implicit def catsDataParallelForKleisli[F[_], M[_], A]( + implicit P: Parallel[M, F] + ): Parallel[Kleisli[M, A, ?], Kleisli[F, A, ?]] = new Parallel[Kleisli[M, A, ?], Kleisli[F, A, ?]] { implicit val appF = P.applicative implicit val monadM = P.monad def applicative: Applicative[Kleisli[F, A, ?]] = catsDataApplicativeForKleisli @@ -250,16 +257,18 @@ private[data] sealed abstract class KleisliInstances1 extends KleisliInstances2 } } -private[data] sealed abstract class KleisliInstances2 extends KleisliInstances3 { +sealed abstract private[data] class KleisliInstances2 extends KleisliInstances3 { implicit def catsDataAlternativeForKleisli[F[_], A](implicit F0: Alternative[F]): Alternative[Kleisli[F, A, ?]] = new KleisliAlternative[F, A] { def F: Alternative[F] = F0 } } -private[data] sealed abstract class KleisliInstances3 extends KleisliInstances4 { +sealed abstract private[data] class KleisliInstances3 extends KleisliInstances4 { implicit def catsDataMonoidKForKleisli[F[_], A](implicit F0: MonoidK[F]): MonoidK[Kleisli[F, A, ?]] = new KleisliMonoidK[F, A] { def F: MonoidK[F] = F0 } - implicit def catsDataCommutativeFlatMapForKleisli[F[_], A](implicit F0: CommutativeFlatMap[F]): CommutativeFlatMap[Kleisli[F, A, ?]] = + implicit def catsDataCommutativeFlatMapForKleisli[F[_], A]( + implicit F0: CommutativeFlatMap[F] + ): CommutativeFlatMap[Kleisli[F, A, ?]] = new KleisliFlatMap[F, A] with CommutativeFlatMap[Kleisli[F, A, ?]] { val F: CommutativeFlatMap[F] = F0 } implicit def catsDataChoiceForKleisli[F[_]](implicit M: Monad[F]): Choice[Kleisli[F, ?, ?]] = @@ -278,11 +287,13 @@ private[data] sealed abstract class KleisliInstances3 extends KleisliInstances4 new KleisliSemigroup[F, A, B] { def FB: Semigroup[F[B]] = FB0 } } -private[data] sealed abstract class KleisliInstances4 extends KleisliInstances5 { +sealed abstract private[data] class KleisliInstances4 extends KleisliInstances5 { implicit def catsDataSemigroupKForKleisli[F[_], A](implicit F0: SemigroupK[F]): SemigroupK[Kleisli[F, A, ?]] = new KleisliSemigroupK[F, A] { def F: SemigroupK[F] = F0 } - implicit def catsDataApplicativeErrorForKleisli[F[_], E, A](implicit F0: ApplicativeError[F, E]): ApplicativeError[Kleisli[F, A, ?], E] = + implicit def catsDataApplicativeErrorForKleisli[F[_], E, A]( + implicit F0: ApplicativeError[F, E] + ): ApplicativeError[Kleisli[F, A, ?], E] = new KleisliApplicativeError[F, A, E] { def F: ApplicativeError[F, E] = F0 } implicit def catsDataFlatMapForKleisli[F[_], A](implicit FM: FlatMap[F]): FlatMap[Kleisli[F, A, ?]] = @@ -290,46 +301,52 @@ private[data] sealed abstract class KleisliInstances4 extends KleisliInstances5 } -private[data] sealed abstract class KleisliInstances5 extends KleisliInstances6 { +sealed abstract private[data] class KleisliInstances5 extends KleisliInstances6 { implicit def catsDataApplicativeForKleisli[F[_], A](implicit A: Applicative[F]): Applicative[Kleisli[F, A, ?]] = new KleisliApplicative[F, A] { def F: Applicative[F] = A } } -private[data] sealed abstract class KleisliInstances6 extends KleisliInstances7 { +sealed abstract private[data] class KleisliInstances6 extends KleisliInstances7 { implicit def catsDataApplyForKleisli[F[_], A](implicit A: Apply[F]): Apply[Kleisli[F, A, ?]] = new KleisliApply[F, A] { def F: Apply[F] = A } } -private[data] sealed abstract class KleisliInstances7 extends KleisliInstances8 { +sealed abstract private[data] class KleisliInstances7 extends KleisliInstances8 { implicit def catsDataDistributiveForKleisli[F[_], R](implicit F0: Distributive[F]): Distributive[Kleisli[F, R, ?]] = new KleisliDistributive[F, R] with KleisliFunctor[F, R] { implicit def F: Distributive[F] = F0 } } -private[data] sealed abstract class KleisliInstances8 { +sealed abstract private[data] class KleisliInstances8 { implicit def catsDataFunctorForKleisli[F[_], A](implicit F0: Functor[F]): Functor[Kleisli[F, A, ?]] = new KleisliFunctor[F, A] { def F: Functor[F] = F0 } } -private[data] trait KleisliCommutativeArrow[F[_]] extends CommutativeArrow[Kleisli[F, ?, ?]] with KleisliArrowChoice[F] { +private[data] trait KleisliCommutativeArrow[F[_]] + extends CommutativeArrow[Kleisli[F, ?, ?]] + with KleisliArrowChoice[F] { implicit def F: CommutativeMonad[F] } -private[data] trait KleisliArrowChoice[F[_]] extends ArrowChoice[Kleisli[F, ?, ?]] with KleisliCategory[F] with KleisliStrong[F] { +private[data] trait KleisliArrowChoice[F[_]] + extends ArrowChoice[Kleisli[F, ?, ?]] + with KleisliCategory[F] + with KleisliStrong[F] { implicit def F: Monad[F] def lift[A, B](f: A => B): Kleisli[F, A, B] = Kleisli(a => F.pure(f(a))) override def split[A, B, C, D](f: Kleisli[F, A, B], g: Kleisli[F, C, D]): Kleisli[F, (A, C), (B, D)] = - Kleisli{ case (a, c) => F.flatMap(f.run(a))(b => F.map(g.run(c))(d => (b, d))) } + Kleisli { case (a, c) => F.flatMap(f.run(a))(b => F.map(g.run(c))(d => (b, d))) } def choose[A, B, C, D](f: Kleisli[F, A, C])(g: Kleisli[F, B, D]): Kleisli[F, Either[A, B], Either[C, D]] = Kleisli( (fe: Either[A, B]) => fe match { - case Left(a) => F.map(f(a))(Left.apply _) + case Left(a) => F.map(f(a))(Left.apply _) case Right(b) => F.map(g(b))(Right.apply _) - }) + } + ) } private[data] trait KleisliStrong[F[_]] extends Strong[Kleisli[F, ?, ?]] { @@ -382,24 +399,27 @@ private[data] trait KleisliMonoid[F[_], A, B] extends Monoid[Kleisli[F, A, B]] w override def empty: Kleisli[F, A, B] = Kleisli[F, A, B](_ => FB.empty) } -private[data] sealed trait KleisliSemigroupK[F[_], A] extends SemigroupK[Kleisli[F, A, ?]] { +sealed private[data] trait KleisliSemigroupK[F[_], A] extends SemigroupK[Kleisli[F, A, ?]] { implicit def F: SemigroupK[F] override def combineK[B](x: Kleisli[F, A, B], y: Kleisli[F, A, B]): Kleisli[F, A, B] = Kleisli(a => F.combineK(x.run(a), y.run(a))) } -private[data] sealed trait KleisliMonoidK[F[_], A] extends MonoidK[Kleisli[F, A, ?]] with KleisliSemigroupK[F, A] { +sealed private[data] trait KleisliMonoidK[F[_], A] extends MonoidK[Kleisli[F, A, ?]] with KleisliSemigroupK[F, A] { implicit def F: MonoidK[F] override def empty[B]: Kleisli[F, A, B] = Kleisli.liftF(F.empty[B]) } -private[data] trait KleisliAlternative[F[_], A] extends Alternative[Kleisli[F, A, ?]] with KleisliApplicative[F, A] with KleisliMonoidK[F, A] { +private[data] trait KleisliAlternative[F[_], A] + extends Alternative[Kleisli[F, A, ?]] + with KleisliApplicative[F, A] + with KleisliMonoidK[F, A] { implicit def F: Alternative[F] } -private[data] sealed trait KleisliContravariantMonoidal[F[_], D] extends ContravariantMonoidal[Kleisli[F, D, ?]] { +sealed private[data] trait KleisliContravariantMonoidal[F[_], D] extends ContravariantMonoidal[Kleisli[F, D, ?]] { implicit def F: ContravariantMonoidal[F] override def unit: Kleisli[F, D, Unit] = Kleisli(Function.const(F.unit)) @@ -411,11 +431,16 @@ private[data] sealed trait KleisliContravariantMonoidal[F[_], D] extends Contrav Kleisli(d => F.product(fa.run(d), fb.run(d))) } -private[data] trait KleisliMonadError[F[_], A, E] extends MonadError[Kleisli[F, A, ?], E] with KleisliApplicativeError[F, A, E] with KleisliMonad[F, A] { +private[data] trait KleisliMonadError[F[_], A, E] + extends MonadError[Kleisli[F, A, ?], E] + with KleisliApplicativeError[F, A, E] + with KleisliMonad[F, A] { def F: MonadError[F, E] } -private[data] trait KleisliApplicativeError[F[_], A, E] extends ApplicativeError[Kleisli[F, A, ?], E] with KleisliApplicative[F, A] { +private[data] trait KleisliApplicativeError[F[_], A, E] + extends ApplicativeError[Kleisli[F, A, ?], E] + with KleisliApplicative[F, A] { type K[T] = Kleisli[F, A, T] implicit def F: ApplicativeError[F, E] @@ -427,7 +452,10 @@ private[data] trait KleisliApplicativeError[F[_], A, E] extends ApplicativeError } } -private[data] trait KleisliMonad[F[_], A] extends Monad[Kleisli[F, A, ?]] with KleisliFlatMap[F, A] with KleisliApplicative[F, A] { +private[data] trait KleisliMonad[F[_], A] + extends Monad[Kleisli[F, A, ?]] + with KleisliFlatMap[F, A] + with KleisliApplicative[F, A] { implicit def F: Monad[F] } @@ -438,7 +466,9 @@ private[data] trait KleisliFlatMap[F[_], A] extends FlatMap[Kleisli[F, A, ?]] wi fa.flatMap(f) def tailRecM[B, C](b: B)(f: B => Kleisli[F, A, Either[B, C]]): Kleisli[F, A, C] = - Kleisli[F, A, C]({ a => F.tailRecM(b) { f(_).run(a) } }) + Kleisli[F, A, C]({ a => + F.tailRecM(b) { f(_).run(a) } + }) } private[data] trait KleisliApplicative[F[_], A] extends Applicative[Kleisli[F, A, ?]] with KleisliApply[F, A] { @@ -469,8 +499,7 @@ private trait KleisliDistributive[F[_], R] extends Distributive[Kleisli[F, R, ?] implicit def F: Distributive[F] override def distribute[G[_]: Functor, A, B](a: G[A])(f: A => Kleisli[F, R, B]): Kleisli[F, R, G[B]] = - Kleisli(r => F.distribute(a)(f(_) run r)) - + Kleisli(r => F.distribute(a)(f(_).run(r))) def map[A, B](fa: Kleisli[F, R, A])(f: A => B): Kleisli[F, R, B] = fa.map(f) } diff --git a/core/src/main/scala/cats/data/Nested.scala b/core/src/main/scala/cats/data/Nested.scala index e780bd6aa79..38f81dd898a 100644 --- a/core/src/main/scala/cats/data/Nested.scala +++ b/core/src/main/scala/cats/data/Nested.scala @@ -1,32 +1,31 @@ package cats package data - /** Similar to [[cats.data.Tuple2K]], but for nested composition. - * - * For instance, since both `List` and `Option` have a `Functor`, then so does - * `List[Option[_]]`. This is represented by this data type via the instantiation - * `Nested[List, Option, ?]`. - * - * {{{ - * scala> import cats.Functor - * scala> import cats.data.Nested - * scala> import cats.implicits._ - * scala> val listOption: List[Option[Int]] = List(Some(1), None) - * scala> val f: Int => String = i => (i * 2).toString - * scala> Functor[List].map(listOption)(opt => opt.map(f)) - * res0: List[Option[String]] = List(Some(2), None) - * scala> val nested: Nested[List, Option, Int] = Nested(listOption) - * scala> val result: Nested[List, Option, String] = Functor[Nested[List, Option, ?]].map(nested)(f) - * scala> result.value - * res1: List[Option[String]] = List(Some(2), None) - * }}} - */ + * + * For instance, since both `List` and `Option` have a `Functor`, then so does + * `List[Option[_]]`. This is represented by this data type via the instantiation + * `Nested[List, Option, ?]`. + * + * {{{ + * scala> import cats.Functor + * scala> import cats.data.Nested + * scala> import cats.implicits._ + * scala> val listOption: List[Option[Int]] = List(Some(1), None) + * scala> val f: Int => String = i => (i * 2).toString + * scala> Functor[List].map(listOption)(opt => opt.map(f)) + * res0: List[Option[String]] = List(Some(2), None) + * scala> val nested: Nested[List, Option, Int] = Nested(listOption) + * scala> val result: Nested[List, Option, String] = Functor[Nested[List, Option, ?]].map(nested)(f) + * scala> result.value + * res1: List[Option[String]] = List(Some(2), None) + * }}} + */ final case class Nested[F[_], G[_], A](value: F[G[A]]) { /** - * Modify the context `F` using transformation `f`. - */ + * Modify the context `F` using transformation `f`. + */ def mapK[H[_]](f: F ~> H): Nested[H, G, A] = Nested(f(value)) @@ -34,16 +33,18 @@ final case class Nested[F[_], G[_], A](value: F[G[A]]) { object Nested extends NestedInstances -private[data] sealed abstract class NestedInstances extends NestedInstances0 { +sealed abstract private[data] class NestedInstances extends NestedInstances0 { implicit def catsDataEqForNested[F[_], G[_], A](implicit FGA: Eq[F[G[A]]]): Eq[Nested[F, G, A]] = Eq.by[Nested[F, G, A], F[G[A]]](_.value) - implicit def catsDataNonEmptyTraverseForNested[F[_]: NonEmptyTraverse, G[_]: NonEmptyTraverse]: NonEmptyTraverse[Nested[F, G, ?]] = + implicit def catsDataNonEmptyTraverseForNested[F[_]: NonEmptyTraverse, G[_]: NonEmptyTraverse] + : NonEmptyTraverse[Nested[F, G, ?]] = new NestedNonEmptyTraverse[F, G] { val FG: NonEmptyTraverse[λ[α => F[G[α]]]] = NonEmptyTraverse[F].compose[G] } - implicit def catsDataContravariantMonoidalForApplicativeForNested[F[_]: Applicative, G[_]: ContravariantMonoidal]: ContravariantMonoidal[Nested[F, G, ?]] = + implicit def catsDataContravariantMonoidalForApplicativeForNested[F[_]: Applicative, G[_]: ContravariantMonoidal] + : ContravariantMonoidal[Nested[F, G, ?]] = new NestedContravariantMonoidal[F, G] with NestedContravariant[F, G] { val FG: ContravariantMonoidal[λ[α => F[G[α]]]] = Applicative[F].composeContravariantMonoidal[G] } @@ -54,64 +55,70 @@ private[data] sealed abstract class NestedInstances extends NestedInstances0 { Nested(F.defer(fa.value)) } - implicit def catsDataTraverseFilterForNested[F[_], G[_]](implicit F0: Traverse[F], G0: TraverseFilter[G]): TraverseFilter[Nested[F, G, ?]] = + implicit def catsDataTraverseFilterForNested[F[_], G[_]](implicit F0: Traverse[F], + G0: TraverseFilter[G]): TraverseFilter[Nested[F, G, ?]] = new NestedTraverseFilter[F, G] { implicit val F: Traverse[F] = F0 implicit val G: TraverseFilter[G] = G0 } } -private[data] sealed abstract class NestedInstances0 extends NestedInstances1 { +sealed abstract private[data] class NestedInstances0 extends NestedInstances1 { implicit def catsDataTraverseForNested[F[_]: Traverse, G[_]: Traverse]: Traverse[Nested[F, G, ?]] = new NestedTraverse[F, G] { val FG: Traverse[λ[α => F[G[α]]]] = Traverse[F].compose[G] } - implicit def catsDataFunctorFilterForNested[F[_], G[_]](implicit F0: Functor[F], G0: FunctorFilter[G]): FunctorFilter[Nested[F, G, ?]] = + implicit def catsDataFunctorFilterForNested[F[_], G[_]](implicit F0: Functor[F], + G0: FunctorFilter[G]): FunctorFilter[Nested[F, G, ?]] = new NestedFunctorFilter[F, G] { implicit val F: Functor[F] = F0 implicit val G: FunctorFilter[G] = G0 } } -private[data] sealed abstract class NestedInstances1 extends NestedInstances2 { +sealed abstract private[data] class NestedInstances1 extends NestedInstances2 { implicit def catsDataReducibleForNested[F[_]: Reducible, G[_]: Reducible]: Reducible[Nested[F, G, ?]] = new NestedReducible[F, G] { val FG: Reducible[λ[α => F[G[α]]]] = Reducible[F].compose[G] } - implicit def catsDataFunctorForContravariantForNested[F[_]: Contravariant, G[_]: Contravariant]: Functor[Nested[F, G, ?]] = + implicit def catsDataFunctorForContravariantForNested[F[_]: Contravariant, G[_]: Contravariant] + : Functor[Nested[F, G, ?]] = new NestedFunctor[F, G] { val FG: Functor[λ[α => F[G[α]]]] = Contravariant[F].compose[G] } } -private[data] sealed abstract class NestedInstances2 extends NestedInstances3 { +sealed abstract private[data] class NestedInstances2 extends NestedInstances3 { implicit def catsDataFoldableForNested[F[_]: Foldable, G[_]: Foldable]: Foldable[Nested[F, G, ?]] = new NestedFoldable[F, G] { val FG: Foldable[λ[α => F[G[α]]]] = Foldable[F].compose[G] } - implicit def catsDataContravariantForCovariantNested[F[_]: Contravariant, G[_]: Functor]: Contravariant[Nested[F, G, ?]] = + implicit def catsDataContravariantForCovariantNested[F[_]: Contravariant, G[_]: Functor] + : Contravariant[Nested[F, G, ?]] = new NestedContravariant[F, G] { val FG: Contravariant[λ[α => F[G[α]]]] = Contravariant[F].composeFunctor[G] } } -private[data] sealed abstract class NestedInstances3 extends NestedInstances4 { +sealed abstract private[data] class NestedInstances3 extends NestedInstances4 { implicit def catsDataAlternativeForNested[F[_]: Alternative, G[_]: Applicative]: Alternative[Nested[F, G, ?]] = new NestedAlternative[F, G] { val FG: Alternative[λ[α => F[G[α]]]] = Alternative[F].compose[G] } - implicit def catsDataContravariantForContravariantNested[F[_]: Functor, G[_]: Contravariant]: Contravariant[Nested[F, G, ?]] = + implicit def catsDataContravariantForContravariantNested[F[_]: Functor, G[_]: Contravariant] + : Contravariant[Nested[F, G, ?]] = new NestedContravariant[F, G] { val FG: Contravariant[λ[α => F[G[α]]]] = Functor[F].composeContravariant[G] } } -private[data] sealed abstract class NestedInstances4 extends NestedInstances5 { - implicit def catsDataApplicativeErrorForNested[F[_]: ApplicativeError[?[_], E], G[_]: Applicative, E]: ApplicativeError[Nested[F, G, ?], E] = +sealed abstract private[data] class NestedInstances4 extends NestedInstances5 { + implicit def catsDataApplicativeErrorForNested[F[_]: ApplicativeError[?[_], E], G[_]: Applicative, E] + : ApplicativeError[Nested[F, G, ?], E] = new NestedApplicativeError[F, G, E] { val G: Applicative[G] = Applicative[G] @@ -120,8 +127,9 @@ private[data] sealed abstract class NestedInstances4 extends NestedInstances5 { } -private[data] sealed abstract class NestedInstances5 extends NestedInstances6 { - implicit def catsDataCommutativeApplicativeForNestedContravariant[F[_]: CommutativeApplicative, G[_]: CommutativeApplicative]: CommutativeApplicative[Nested[F, G, ?]] = +sealed abstract private[data] class NestedInstances5 extends NestedInstances6 { + implicit def catsDataCommutativeApplicativeForNestedContravariant[F[_]: CommutativeApplicative, G[_]: CommutativeApplicative] + : CommutativeApplicative[Nested[F, G, ?]] = new NestedApplicative[F, G] with CommutativeApplicative[Nested[F, G, ?]] { val FG: Applicative[λ[α => F[G[α]]]] = Applicative[F].compose[G] } @@ -132,8 +140,9 @@ private[data] sealed abstract class NestedInstances5 extends NestedInstances6 { } } -private[data] sealed abstract class NestedInstances6 extends NestedInstances7 { - implicit def catsDataCommutativeApplyForNestedContravariant[F[_]: CommutativeApply, G[_]: CommutativeApply]: CommutativeApply[Nested[F, G, ?]] = +sealed abstract private[data] class NestedInstances6 extends NestedInstances7 { + implicit def catsDataCommutativeApplyForNestedContravariant[F[_]: CommutativeApply, G[_]: CommutativeApply] + : CommutativeApply[Nested[F, G, ?]] = new NestedApply[F, G] with CommutativeApply[Nested[F, G, ?]] { val FG: Apply[λ[α => F[G[α]]]] = Apply[F].compose[G] } @@ -144,14 +153,14 @@ private[data] sealed abstract class NestedInstances6 extends NestedInstances7 { } } -private[data] sealed abstract class NestedInstances7 extends NestedInstances8 { +sealed abstract private[data] class NestedInstances7 extends NestedInstances8 { implicit def catsDataApplicativeForNested[F[_]: Applicative, G[_]: Applicative]: Applicative[Nested[F, G, ?]] = new NestedApplicative[F, G] { val FG: Applicative[λ[α => F[G[α]]]] = Applicative[F].compose[G] } } -private[data] sealed abstract class NestedInstances8 extends NestedInstances9 { +sealed abstract private[data] class NestedInstances8 extends NestedInstances9 { implicit def catsDataApplyForNested[F[_]: Apply, G[_]: Apply]: Apply[Nested[F, G, ?]] = new NestedApply[F, G] { val FG: Apply[λ[α => F[G[α]]]] = Apply[F].compose[G] @@ -163,36 +172,38 @@ private[data] sealed abstract class NestedInstances8 extends NestedInstances9 { } } -private[data] sealed abstract class NestedInstances9 extends NestedInstances10 { - implicit def catsDataInvariantSemigroupalApplyForNested[F[_]: InvariantSemigroupal, G[_]: Apply]: InvariantSemigroupal[Nested[F, G, ?]] = +sealed abstract private[data] class NestedInstances9 extends NestedInstances10 { + implicit def catsDataInvariantSemigroupalApplyForNested[F[_]: InvariantSemigroupal, G[_]: Apply] + : InvariantSemigroupal[Nested[F, G, ?]] = new NestedInvariantSemigroupalApply[F, G] { val FG: InvariantSemigroupal[λ[α => F[G[α]]]] = InvariantSemigroupal[F].composeApply[G] } } -private[data] sealed abstract class NestedInstances10 extends NestedInstances11 { +sealed abstract private[data] class NestedInstances10 extends NestedInstances11 { implicit def catsDataFunctorForNested[F[_]: Functor, G[_]: Functor]: Functor[Nested[F, G, ?]] = new NestedFunctor[F, G] { val FG: Functor[λ[α => F[G[α]]]] = Functor[F].compose[G] } } -private[data] sealed abstract class NestedInstances11 extends NestedInstances12 { +sealed abstract private[data] class NestedInstances11 extends NestedInstances12 { implicit def catsDataInvariantForNested[F[_]: Invariant, G[_]: Invariant]: Invariant[Nested[F, G, ?]] = new NestedInvariant[F, G] { val FG: Invariant[λ[α => F[G[α]]]] = Invariant[F].compose[G] } } -private[data] sealed abstract class NestedInstances12 extends NestedInstances13 { +sealed abstract private[data] class NestedInstances12 extends NestedInstances13 { implicit def catsDataInvariantForCovariantNested[F[_]: Invariant, G[_]: Functor]: Invariant[Nested[F, G, ?]] = new NestedInvariant[F, G] { val FG: Invariant[λ[α => F[G[α]]]] = Invariant[F].composeFunctor[G] } } -private[data] sealed abstract class NestedInstances13 { - implicit def catsDataInvariantForNestedContravariant[F[_]: Invariant, G[_]: Contravariant]: Invariant[Nested[F, G, ?]] = +sealed abstract private[data] class NestedInstances13 { + implicit def catsDataInvariantForNestedContravariant[F[_]: Invariant, G[_]: Contravariant] + : Invariant[Nested[F, G, ?]] = new NestedInvariant[F, G] { val FG: Invariant[λ[α => F[G[α]]]] = Invariant[F].composeContravariant[G] } @@ -228,7 +239,9 @@ private[data] trait NestedApplicative[F[_], G[_]] extends Applicative[Nested[F, def pure[A](x: A): Nested[F, G, A] = Nested(FG.pure(x)) } -private[data] abstract class NestedApplicativeError[F[_], G[_], E] extends ApplicativeError[Nested[F, G, ?], E] with NestedApplicative[F, G] { +abstract private[data] class NestedApplicativeError[F[_], G[_], E] + extends ApplicativeError[Nested[F, G, ?], E] + with NestedApplicative[F, G] { def G: Applicative[G] def AEF: ApplicativeError[F, E] @@ -237,7 +250,7 @@ private[data] abstract class NestedApplicativeError[F[_], G[_], E] extends Appli def raiseError[A](e: E): Nested[F, G, A] = Nested(AEF.map(AEF.raiseError(e))(G.pure)) def handleErrorWith[A](fa: Nested[F, G, A])(f: E => Nested[F, G, A]): Nested[F, G, A] = - Nested(AEF.handleErrorWith(fa.value)(f andThen (_.value))) + Nested(AEF.handleErrorWith(fa.value)(f.andThen(_.value))) } @@ -253,7 +266,10 @@ private[data] trait NestedMonoidK[F[_], G[_]] extends MonoidK[Nested[F, G, ?]] w def empty[A]: Nested[F, G, A] = Nested(FG.empty[A]) } -private[data] trait NestedAlternative[F[_], G[_]] extends Alternative[Nested[F, G, ?]] with NestedApplicative[F, G] with NestedMonoidK[F, G] { +private[data] trait NestedAlternative[F[_], G[_]] + extends Alternative[Nested[F, G, ?]] + with NestedApplicative[F, G] + with NestedMonoidK[F, G] { def FG: Alternative[λ[α => F[G[α]]]] } @@ -267,7 +283,10 @@ private[data] trait NestedFoldable[F[_], G[_]] extends Foldable[Nested[F, G, ?]] FG.foldRight(fga.value, lb)(f) } -private[data] trait NestedTraverse[F[_], G[_]] extends Traverse[Nested[F, G, ?]] with NestedFoldable[F, G] with NestedFunctor[F, G] { +private[data] trait NestedTraverse[F[_], G[_]] + extends Traverse[Nested[F, G, ?]] + with NestedFoldable[F, G] + with NestedFunctor[F, G] { def FG: Traverse[λ[α => F[G[α]]]] override def traverse[H[_]: Applicative, A, B](fga: Nested[F, G, A])(f: A => H[B]): H[Nested[F, G, B]] = @@ -278,7 +297,9 @@ private[data] trait NestedDistributive[F[_], G[_]] extends Distributive[Nested[F def FG: Distributive[λ[α => F[G[α]]]] def distribute[H[_]: Functor, A, B](ha: H[A])(f: A => Nested[F, G, B]): Nested[F, G, H[B]] = - Nested(FG.distribute(ha) { a => f(a).value }) + Nested(FG.distribute(ha) { a => + f(a).value + }) } private[data] trait NestedReducible[F[_], G[_]] extends Reducible[Nested[F, G, ?]] with NestedFoldable[F, G] { @@ -291,7 +312,10 @@ private[data] trait NestedReducible[F[_], G[_]] extends Reducible[Nested[F, G, ? FG.reduceRightTo(fga.value)(f)(g) } -private[data] trait NestedNonEmptyTraverse[F[_], G[_]] extends NonEmptyTraverse[Nested[F, G, ?]] with NestedTraverse[F, G] with NestedReducible[F, G] { +private[data] trait NestedNonEmptyTraverse[F[_], G[_]] + extends NonEmptyTraverse[Nested[F, G, ?]] + with NestedTraverse[F, G] + with NestedReducible[F, G] { def FG: NonEmptyTraverse[λ[α => F[G[α]]]] override def nonEmptyTraverse[H[_]: Apply, A, B](fga: Nested[F, G, A])(f: A => H[B]): H[Nested[F, G, B]] = @@ -327,7 +351,7 @@ private[data] trait NestedInvariantSemigroupalApply[F[_], G[_]] extends Invarian Nested(FG.product(fa.value, fb.value)) } -private[data] abstract class NestedFunctorFilter[F[_], G[_]] extends FunctorFilter[Nested[F, G, ?]] { +abstract private[data] class NestedFunctorFilter[F[_], G[_]] extends FunctorFilter[Nested[F, G, ?]] { implicit val F: Functor[F] implicit val G: FunctorFilter[G] @@ -347,23 +371,22 @@ private[data] abstract class NestedFunctorFilter[F[_], G[_]] extends FunctorFilt Nested[F, G, A](F.map(fa.value)(G.filter(_)(f))) } -private[data] abstract class NestedTraverseFilter[F[_], G[_]] - extends NestedFunctorFilter[F, G] with TraverseFilter[Nested[F, G, ?]] { - implicit val F: Traverse[F] +abstract private[data] class NestedTraverseFilter[F[_], G[_]] + extends NestedFunctorFilter[F, G] + with TraverseFilter[Nested[F, G, ?]] { + implicit val F: Traverse[F] - implicit val G: TraverseFilter[G] + implicit val G: TraverseFilter[G] - def traverse: Traverse[Nested[F, G, ?]] = Nested.catsDataTraverseForNested(F, G.traverse) + def traverse: Traverse[Nested[F, G, ?]] = Nested.catsDataTraverseForNested(F, G.traverse) - override def filterA[H[_], A] - (fa: Nested[F, G, A]) - (f: A => H[Boolean]) - (implicit H: Applicative[H]): H[Nested[F, G, A]] = - H.map(F.traverse(fa.value)(G.filterA[H, A](_)(f)))(Nested[F, G, A]) + override def filterA[H[_], A]( + fa: Nested[F, G, A] + )(f: A => H[Boolean])(implicit H: Applicative[H]): H[Nested[F, G, A]] = + H.map(F.traverse(fa.value)(G.filterA[H, A](_)(f)))(Nested[F, G, A]) - def traverseFilter[H[_], A, B] - (fga: Nested[F, G, A]) - (f: A => H[Option[B]]) - (implicit H: Applicative[H]): H[Nested[F, G, B]] = - H.map(F.traverse[H, G[A], G[B]](fga.value)(ga => G.traverseFilter(ga)(f)))(Nested[F, G, B]) + def traverseFilter[H[_], A, B]( + fga: Nested[F, G, A] + )(f: A => H[Option[B]])(implicit H: Applicative[H]): H[Nested[F, G, B]] = + H.map(F.traverse[H, G[A], G[B]](fga.value)(ga => G.traverseFilter(ga)(f)))(Nested[F, G, B]) } diff --git a/core/src/main/scala/cats/data/NonEmptyChain.scala b/core/src/main/scala/cats/data/NonEmptyChain.scala index 63011a0f504..f63a37dcf8a 100644 --- a/core/src/main/scala/cats/data/NonEmptyChain.scala +++ b/core/src/main/scala/cats/data/NonEmptyChain.scala @@ -25,7 +25,6 @@ import scala.annotation.tailrec import scala.collection.immutable._ import scala.collection.mutable.ListBuffer - private[data] object NonEmptyChainImpl extends NonEmptyChainInstances { private[data] type Base @@ -69,213 +68,208 @@ private[data] object NonEmptyChainImpl extends NonEmptyChainInstances { new NonEmptyChainOps(value) } - class NonEmptyChainOps[A](val value: NonEmptyChain[A]) extends AnyVal { /** - * Converts this chain to a `Chain` - */ + * Converts this chain to a `Chain` + */ final def toChain: Chain[A] = NonEmptyChainImpl.unwrap(value) /** - * Returns a new NonEmptyChain consisting of `a` followed by this. O(1) runtime. - */ + * Returns a new NonEmptyChain consisting of `a` followed by this. O(1) runtime. + */ final def prepend[A2 >: A](a: A2): NonEmptyChain[A2] = create(toChain.prepend(a)) /** - * Alias for [[prepend]]. - */ + * Alias for [[prepend]]. + */ final def +:[A2 >: A](a: A2): NonEmptyChain[A2] = prepend(a) /** - * Returns a new Chain consisting of this followed by `a`. O(1) runtime. - */ + * Returns a new Chain consisting of this followed by `a`. O(1) runtime. + */ final def append[A2 >: A](a: A2): NonEmptyChain[A2] = create(toChain.append(a)) /** - * Alias for [[append]]. - */ + * Alias for [[append]]. + */ final def :+[A2 >: A](a: A2): NonEmptyChain[A2] = append(a) /** - * Concatenates this with `c` in O(1) runtime. - * {{{ - * scala> import cats.data.NonEmptyChain - * scala> val nec = NonEmptyChain(1, 2, 4, 5) - * scala> nec ++ NonEmptyChain(7, 8) - * res0: cats.data.NonEmptyChain[Int] = Chain(1, 2, 4, 5, 7, 8) - * }}} - */ + * Concatenates this with `c` in O(1) runtime. + * {{{ + * scala> import cats.data.NonEmptyChain + * scala> val nec = NonEmptyChain(1, 2, 4, 5) + * scala> nec ++ NonEmptyChain(7, 8) + * res0: cats.data.NonEmptyChain[Int] = Chain(1, 2, 4, 5, 7, 8) + * }}} + */ final def concat[A2 >: A](c: NonEmptyChain[A2]): NonEmptyChain[A2] = create(toChain ++ c.toChain) - /** - * Alias for concat - */ + * Alias for concat + */ final def ++[A2 >: A](c: NonEmptyChain[A2]): NonEmptyChain[A2] = concat(c) /** - * Appends the given chain in O(1) runtime. - */ + * Appends the given chain in O(1) runtime. + */ final def appendChain[A2 >: A](c: Chain[A2]): NonEmptyChain[A2] = if (c.isEmpty) value else create(toChain ++ c) /** - * Alias for `appendChain` - * {{{ - * scala> import cats.data.NonEmptyChain - * scala> val nec = NonEmptyChain(1, 2, 4, 5) - * scala> nec :++ Chain(3, 6, 9) - * res0: cats.data.NonEmptyChain[Int] = Chain(1, 2, 4, 5, 3, 6, 9) - * }}} - */ + * Alias for `appendChain` + * {{{ + * scala> import cats.data.NonEmptyChain + * scala> val nec = NonEmptyChain(1, 2, 4, 5) + * scala> nec :++ Chain(3, 6, 9) + * res0: cats.data.NonEmptyChain[Int] = Chain(1, 2, 4, 5, 3, 6, 9) + * }}} + */ final def :++[A2 >: A](c: Chain[A2]): NonEmptyChain[A2] = appendChain(c) /** - * Prepends the given chain in O(1) runtime. - */ + * Prepends the given chain in O(1) runtime. + */ final def prependChain[A2 >: A](c: Chain[A2]): NonEmptyChain[A2] = if (c.isEmpty) value else create(c ++ toChain) /** - * Alias for `prependChain` - * {{{ - * scala> import cats.data.NonEmptyChain - * scala> val nec = NonEmptyChain(4, 5, 6) - * scala> Chain(1, 2, 3) ++: nec - * res0: cats.data.NonEmptyChain[Int] = Chain(1, 2, 3, 4, 5, 6) - * }}} - */ + * Alias for `prependChain` + * {{{ + * scala> import cats.data.NonEmptyChain + * scala> val nec = NonEmptyChain(4, 5, 6) + * scala> Chain(1, 2, 3) ++: nec + * res0: cats.data.NonEmptyChain[Int] = Chain(1, 2, 3, 4, 5, 6) + * }}} + */ final def ++:[A2 >: A](c: Chain[A2]): NonEmptyChain[A2] = prependChain(c) - /** - * Yields to Some(a, Chain[A]) with `a` removed where `f` holds for the first time, - * otherwise yields None, if `a` was not found - * Traverses only until `a` is found. - */ + * Yields to Some(a, Chain[A]) with `a` removed where `f` holds for the first time, + * otherwise yields None, if `a` was not found + * Traverses only until `a` is found. + */ final def deleteFirst(f: A => Boolean): Option[(A, Chain[A])] = toChain.deleteFirst(f) - /** - * Converts this chain to a `NonEmptyList`. - * {{{ - * scala> import cats.data.NonEmptyChain - * scala> val nec = NonEmptyChain(1, 2, 3, 4, 5) - * scala> nec.toNonEmptyList - * res0: cats.data.NonEmptyList[Int] = NonEmptyList(1, 2, 3, 4, 5) - * }}} - */ + * Converts this chain to a `NonEmptyList`. + * {{{ + * scala> import cats.data.NonEmptyChain + * scala> val nec = NonEmptyChain(1, 2, 3, 4, 5) + * scala> nec.toNonEmptyList + * res0: cats.data.NonEmptyList[Int] = NonEmptyList(1, 2, 3, 4, 5) + * }}} + */ final def toNonEmptyList: NonEmptyList[A] = NonEmptyList.fromListUnsafe(toChain.toList) /** - * Converts this chain to a `NonEmptyVector`. - * {{{ - * scala> import cats.data.NonEmptyChain - * scala> val nec = NonEmptyChain(1, 2, 3, 4, 5) - * scala> nec.toNonEmptyVector - * res0: cats.data.NonEmptyVector[Int] = NonEmptyVector(1, 2, 3, 4, 5) - * }}} - */ + * Converts this chain to a `NonEmptyVector`. + * {{{ + * scala> import cats.data.NonEmptyChain + * scala> val nec = NonEmptyChain(1, 2, 3, 4, 5) + * scala> nec.toNonEmptyVector + * res0: cats.data.NonEmptyVector[Int] = NonEmptyVector(1, 2, 3, 4, 5) + * }}} + */ final def toNonEmptyVector: NonEmptyVector[A] = NonEmptyVector.fromVectorUnsafe(toChain.toVector) /** - * Returns the head and tail of this NonEmptyChain. Amortized O(1). - */ + * Returns the head and tail of this NonEmptyChain. Amortized O(1). + */ final def uncons: (A, Chain[A]) = toChain.uncons.get /** - * Returns the first element of this chain. - */ + * Returns the first element of this chain. + */ final def head: A = uncons._1 /** - * Returns all but the first element of this chain. - */ + * Returns all but the first element of this chain. + */ final def tail: Chain[A] = uncons._2 /** - * Tests if some element is contained in this chain. - * {{{ - * scala> import cats.data.NonEmptyChain - * scala> import cats.implicits._ - * scala> val nec = NonEmptyChain(4, 5, 6) - * scala> nec.contains(5) - * res0: Boolean = true - * }}} - */ + * Tests if some element is contained in this chain. + * {{{ + * scala> import cats.data.NonEmptyChain + * scala> import cats.implicits._ + * scala> val nec = NonEmptyChain(4, 5, 6) + * scala> nec.contains(5) + * res0: Boolean = true + * }}} + */ final def contains(a: A)(implicit A: Eq[A]): Boolean = toChain.contains(a) /** - * Tests whether a predicate holds for all elements of this chain. - */ + * Tests whether a predicate holds for all elements of this chain. + */ final def forall(p: A ⇒ Boolean): Boolean = toChain.forall(p) /** - * Tests whether a predicate holds for at least one element of this chain. - */ + * Tests whether a predicate holds for at least one element of this chain. + */ final def exists(f: A ⇒ Boolean): Boolean = toChain.exists(f) /** - * Returns the first value that matches the given predicate. - */ + * Returns the first value that matches the given predicate. + */ final def find(f: A ⇒ Boolean): Option[A] = toChain.find(f) /** - * Returns a new `Chain` containing all elements where the result of `pf` is final defined. - * {{{ - * scala> import cats.data.NonEmptyChain - * scala> import cats.implicits._ - * scala> val nec = NonEmptyChain(4, 5, 6).map(n => if (n % 2 == 0) Some(n) else None) - * scala> nec.collect { case Some(n) => n } - * res0: cats.data.Chain[Int] = Chain(4, 6) - * }}} - */ + * Returns a new `Chain` containing all elements where the result of `pf` is final defined. + * {{{ + * scala> import cats.data.NonEmptyChain + * scala> import cats.implicits._ + * scala> val nec = NonEmptyChain(4, 5, 6).map(n => if (n % 2 == 0) Some(n) else None) + * scala> nec.collect { case Some(n) => n } + * res0: cats.data.Chain[Int] = Chain(4, 6) + * }}} + */ final def collect[B](pf: PartialFunction[A, B]): Chain[B] = toChain.collect(pf) /** - * Filters all elements of this chain that do not satisfy the given predicate. - */ + * Filters all elements of this chain that do not satisfy the given predicate. + */ final def filter(p: A ⇒ Boolean): Chain[A] = toChain.filter(p) /** - * Filters all elements of this chain that satisfy the given predicate. - */ + * Filters all elements of this chain that satisfy the given predicate. + */ final def filterNot(p: A ⇒ Boolean): Chain[A] = filter(t => !p(t)) - /** - * Left-associative fold using f. - */ + * Left-associative fold using f. + */ final def foldLeft[B](b: B)(f: (B, A) => B): B = toChain.foldLeft(b)(f) /** - * Right-associative fold using f. - */ + * Right-associative fold using f. + */ final def foldRight[B](z: B)(f: (A, B) => B): B = toChain.foldRight(z)(f) /** - * Left-associative reduce using f. - * {{{ - * scala> import cats.data.NonEmptyChain - * scala> val nec = NonEmptyChain(4, 5, 6) - * scala> nec.reduceLeft(_ + _) - * res0: Int = 15 - * }}} - */ + * Left-associative reduce using f. + * {{{ + * scala> import cats.data.NonEmptyChain + * scala> val nec = NonEmptyChain(4, 5, 6) + * scala> nec.reduceLeft(_ + _) + * res0: Int = 15 + * }}} + */ final def reduceLeft(f: (A, A) => A): A = { val iter = toChain.iterator var result = iter.next @@ -284,15 +278,15 @@ class NonEmptyChainOps[A](val value: NonEmptyChain[A]) extends AnyVal { } /** - * Apply `f` to the "initial element" of this chain and lazily combine it - * with every other value using the given function `g`. - * {{{ - * scala> import cats.data.NonEmptyChain - * scala> val nec = NonEmptyChain(4, 5, 6) - * scala> nec.reduceLeftTo(_.toString)((acc, cur) => acc + cur.toString) - * res0: String = 456 - * }}} - */ + * Apply `f` to the "initial element" of this chain and lazily combine it + * with every other value using the given function `g`. + * {{{ + * scala> import cats.data.NonEmptyChain + * scala> val nec = NonEmptyChain(4, 5, 6) + * scala> nec.reduceLeftTo(_.toString)((acc, cur) => acc + cur.toString) + * res0: String = 456 + * }}} + */ final def reduceLeftTo[B](f: A => B)(g: (B, A) => B): B = { val iter = toChain.iterator var result = f(iter.next) @@ -301,14 +295,14 @@ class NonEmptyChainOps[A](val value: NonEmptyChain[A]) extends AnyVal { } /** - * Right-associative reduce using f. - * {{{ - * scala> import cats.data.NonEmptyChain - * scala> val nec = NonEmptyChain(4, 5, 6) - * scala> nec.reduceRight(_ + _) - * res0: Int = 15 - * }}} - */ + * Right-associative reduce using f. + * {{{ + * scala> import cats.data.NonEmptyChain + * scala> val nec = NonEmptyChain(4, 5, 6) + * scala> nec.reduceRight(_ + _) + * res0: Int = 15 + * }}} + */ final def reduceRight(f: (A, A) => A): A = { val iter = toChain.reverseIterator var result = iter.next @@ -317,15 +311,15 @@ class NonEmptyChainOps[A](val value: NonEmptyChain[A]) extends AnyVal { } /** - * Apply `f` to the "initial element" of this chain and lazily combine it - * with every other value using the given function `g`. - * {{{ - * scala> import cats.data.NonEmptyChain - * scala> val nec = NonEmptyChain(4, 5, 6) - * scala> nec.reduceLeftTo(_.toString)((cur, acc) => acc + cur.toString) - * res0: String = 654 - * }}} - */ + * Apply `f` to the "initial element" of this chain and lazily combine it + * with every other value using the given function `g`. + * {{{ + * scala> import cats.data.NonEmptyChain + * scala> val nec = NonEmptyChain(4, 5, 6) + * scala> nec.reduceLeftTo(_.toString)((cur, acc) => acc + cur.toString) + * res0: String = 654 + * }}} + */ final def reduceRightTo[B](f: A => B)(g: (A, B) => B): B = { val iter = toChain.reverseIterator var result = f(iter.next) @@ -334,43 +328,40 @@ class NonEmptyChainOps[A](val value: NonEmptyChain[A]) extends AnyVal { } /** - * Reduce using the Semigroup of A - */ - final def reduce[AA >: A](implicit S: Semigroup[AA]): AA = { + * Reduce using the Semigroup of A + */ + final def reduce[AA >: A](implicit S: Semigroup[AA]): AA = S.combineAllOption(iterator).get - } /** - * Applies the supplied function to each element and returns a new NonEmptyChain from the concatenated results - */ - final def flatMap[B](f: A => NonEmptyChain[B]): NonEmptyChain[B] = { - create(toChain.flatMap(f andThen (_.toChain))) - } - + * Applies the supplied function to each element and returns a new NonEmptyChain from the concatenated results + */ + final def flatMap[B](f: A => NonEmptyChain[B]): NonEmptyChain[B] = + create(toChain.flatMap(f.andThen(_.toChain))) /** - * Returns the number of elements in this chain. - */ + * Returns the number of elements in this chain. + */ final def length: Long = toChain.size /** - * Zips this `NonEmptyChain` with another `NonEmptyChain` and applies a function for each pair of elements. - * - * {{{ - * scala> import cats.data.NonEmptyChain - * scala> val as = NonEmptyChain(1, 2, 3) - * scala> val bs = NonEmptyChain("A", "B", "C") - * scala> as.zipWith(bs)(_ + _) - * res0: cats.data.NonEmptyChain[String] = Chain(1A, 2B, 3C) - * }}} - */ + * Zips this `NonEmptyChain` with another `NonEmptyChain` and applies a function for each pair of elements. + * + * {{{ + * scala> import cats.data.NonEmptyChain + * scala> val as = NonEmptyChain(1, 2, 3) + * scala> val bs = NonEmptyChain("A", "B", "C") + * scala> as.zipWith(bs)(_ + _) + * res0: cats.data.NonEmptyChain[String] = Chain(1A, 2B, 3C) + * }}} + */ final def zipWith[B, C](b: NonEmptyChain[B])(f: (A, B) => C): NonEmptyChain[C] = create(toChain.zipWith(b.toChain)(f)) /** - * Groups elements inside this `NonEmptyChain` according to the `Order` - * of the keys produced by the given mapping function. - */ + * Groups elements inside this `NonEmptyChain` according to the `Order` + * of the keys produced by the given mapping function. + */ final def groupBy[B](f: A => B)(implicit B: Order[B]): NonEmptyMap[B, NonEmptyChain[A]] = toChain.groupBy(f).asInstanceOf[NonEmptyMap[B, NonEmptyChain[A]]] @@ -383,10 +374,9 @@ class NonEmptyChainOps[A](val value: NonEmptyChain[A]) extends AnyVal { create(toChain.reverse) } -private[data] sealed abstract class NonEmptyChainInstances extends NonEmptyChainInstances1 { - implicit val catsDataInstancesForNonEmptyChain: SemigroupK[NonEmptyChain] - with NonEmptyTraverse[NonEmptyChain] - with Bimonad[NonEmptyChain] = +sealed abstract private[data] class NonEmptyChainInstances extends NonEmptyChainInstances1 { + implicit val catsDataInstancesForNonEmptyChain + : SemigroupK[NonEmptyChain] with NonEmptyTraverse[NonEmptyChain] with Bimonad[NonEmptyChain] = new SemigroupK[NonEmptyChain] with NonEmptyTraverse[NonEmptyChain] with Bimonad[NonEmptyChain] { def combineK[A](a: NonEmptyChain[A], b: NonEmptyChain[A]): NonEmptyChain[A] = @@ -406,18 +396,21 @@ private[data] sealed abstract class NonEmptyChainInstances extends NonEmptyChain @tailrec def go(as: Chain[A], res: ListBuffer[B]): Chain[B] = as.uncons match { case Some((h, t)) => go(t, res += f(NonEmptyChain.fromChainPrepend(h, t))) - case None => Chain.fromSeq(res.result()) + case None => Chain.fromSeq(res.result()) } NonEmptyChain.fromChainPrepend(f(fa), go(fa.tail, ListBuffer.empty)) } def nonEmptyTraverse[G[_]: Apply, A, B](fa: NonEmptyChain[A])(f: A => G[B]): G[NonEmptyChain[B]] = - Foldable[Chain].reduceRightToOption[A, G[Chain[B]]](fa.tail)(a => Apply[G].map(f(a))(Chain.one)) { (a, lglb) => - Apply[G].map2Eval(f(a), lglb)(_ +: _) - }.map { - case None => Apply[G].map(f(fa.head))(NonEmptyChain.one) - case Some(gtail) => Apply[G].map2(f(fa.head), gtail)((h, t) => create(Chain.one(h) ++ t)) - }.value + Foldable[Chain] + .reduceRightToOption[A, G[Chain[B]]](fa.tail)(a => Apply[G].map(f(a))(Chain.one)) { (a, lglb) => + Apply[G].map2Eval(f(a), lglb)(_ +: _) + } + .map { + case None => Apply[G].map(f(fa.head))(NonEmptyChain.one) + case Some(gtail) => Apply[G].map2(f(fa.head), gtail)((h, t) => create(Chain.one(h) ++ t)) + } + .value override def map[A, B](fa: NonEmptyChain[A])(f: A => B): NonEmptyChain[B] = create(fa.toChain.map(f)) @@ -475,14 +468,14 @@ private[data] sealed abstract class NonEmptyChainInstances extends NonEmptyChain } } -private[data] sealed abstract class NonEmptyChainInstances1 extends NonEmptyChainInstances2 { +sealed abstract private[data] class NonEmptyChainInstances1 extends NonEmptyChainInstances2 { implicit def catsDataPartialOrderForNonEmptyChain[A: PartialOrder]: PartialOrder[NonEmptyChain[A]] = PartialOrder.by[NonEmptyChain[A], Chain[A]](_.toChain) } -private[data] sealed abstract class NonEmptyChainInstances2 { +sealed abstract private[data] class NonEmptyChainInstances2 { implicit def catsDataEqForNonEmptyChain[A: Eq]: Eq[NonEmptyChain[A]] = - new Eq[NonEmptyChain[A]]{ + new Eq[NonEmptyChain[A]] { def eqv(x: NonEmptyChain[A], y: NonEmptyChain[A]): Boolean = x.toChain === y.toChain } } diff --git a/core/src/main/scala/cats/data/NonEmptyList.scala b/core/src/main/scala/cats/data/NonEmptyList.scala index 15315d7f383..83f130c9f88 100644 --- a/core/src/main/scala/cats/data/NonEmptyList.scala +++ b/core/src/main/scala/cats/data/NonEmptyList.scala @@ -5,73 +5,73 @@ import cats.data.NonEmptyList.ZipNonEmptyList import cats.instances.list._ import cats.syntax.order._ import scala.annotation.tailrec -import scala.collection.immutable.{ SortedMap, TreeMap, TreeSet } +import scala.collection.immutable.{SortedMap, TreeMap, TreeSet} import scala.collection.mutable import scala.collection.mutable.ListBuffer /** - * A data type which represents a non empty list of A, with - * single element (head) and optional structure (tail). - */ + * A data type which represents a non empty list of A, with + * single element (head) and optional structure (tail). + */ final case class NonEmptyList[+A](head: A, tail: List[A]) { /** - * Return the head and tail into a single list - * {{{ - * scala> import cats.data.NonEmptyList - * scala> val nel = NonEmptyList.of(1, 2, 3, 4, 5) - * scala> nel.toList - * res0: scala.collection.immutable.List[Int] = List(1, 2, 3, 4, 5) - * }}} - */ + * Return the head and tail into a single list + * {{{ + * scala> import cats.data.NonEmptyList + * scala> val nel = NonEmptyList.of(1, 2, 3, 4, 5) + * scala> nel.toList + * res0: scala.collection.immutable.List[Int] = List(1, 2, 3, 4, 5) + * }}} + */ def toList: List[A] = head :: tail /** - * Selects the last element - * {{{ - * scala> import cats.data.NonEmptyList - * scala> val nel = NonEmptyList.of(1, 2, 3, 4, 5) - * scala> nel.last - * res0: Int = 5 - * }}} - */ + * Selects the last element + * {{{ + * scala> import cats.data.NonEmptyList + * scala> val nel = NonEmptyList.of(1, 2, 3, 4, 5) + * scala> nel.last + * res0: Int = 5 + * }}} + */ def last: A = tail.lastOption match { case None => head case Some(a) => a } /** - * Selects all elements except the last - * - * {{{ - * scala> import cats.data.NonEmptyList - * scala> val nel = NonEmptyList.of(1, 2, 3, 4, 5) - * scala> nel.init - * res0: scala.collection.immutable.List[Int] = List(1, 2, 3, 4) - * }}} - */ + * Selects all elements except the last + * + * {{{ + * scala> import cats.data.NonEmptyList + * scala> val nel = NonEmptyList.of(1, 2, 3, 4, 5) + * scala> nel.init + * res0: scala.collection.immutable.List[Int] = List(1, 2, 3, 4) + * }}} + */ def init: List[A] = tail match { case Nil => List.empty - case t => head :: t.init + case t => head :: t.init } /** - * The size of this NonEmptyList - * - * {{{ - * scala> import cats.data.NonEmptyList - * scala> val nel = NonEmptyList.of(1, 2, 3, 4, 5) - * scala> nel.size - * res0: Int = 5 - * }}} - */ + * The size of this NonEmptyList + * + * {{{ + * scala> import cats.data.NonEmptyList + * scala> val nel = NonEmptyList.of(1, 2, 3, 4, 5) + * scala> nel.size + * res0: Int = 5 + * }}} + */ def size: Int = 1 + tail.size def length: Int = size /** - * Applies f to all the elements of the structure - */ + * Applies f to all the elements of the structure + */ def map[B](f: A => B): NonEmptyList[B] = NonEmptyList(f(head), tail.map(f)) @@ -86,13 +86,13 @@ final case class NonEmptyList[+A](head: A, tail: List[A]) { concatNel(other) /** - * Append another NonEmptyList - */ + * Append another NonEmptyList + */ def concatNel[AA >: A](other: NonEmptyList[AA]): NonEmptyList[AA] = NonEmptyList(head, tail ::: other.toList) def flatMap[B](f: A => NonEmptyList[B]): NonEmptyList[B] = - f(head) ++ tail.flatMap(f andThen (_.toList)) + f(head) ++ tail.flatMap(f.andThen(_.toList)) def ::[AA >: A](a: AA): NonEmptyList[AA] = prepend(a) @@ -130,15 +130,15 @@ final case class NonEmptyList[+A](head: A, tail: List[A]) { other.concatNel(this) /** - * Remove elements not matching the predicate - * - * {{{ - * scala> import cats.data.NonEmptyList - * scala> val nel = NonEmptyList.of(1, 2, 3, 4, 5) - * scala> nel.filter(_ < 3) - * res0: scala.collection.immutable.List[Int] = List(1, 2) - * }}} - */ + * Remove elements not matching the predicate + * + * {{{ + * scala> import cats.data.NonEmptyList + * scala> val nel = NonEmptyList.of(1, 2, 3, 4, 5) + * scala> nel.filter(_ < 3) + * res0: scala.collection.immutable.List[Int] = List(1, 2) + * }}} + */ def filter(p: A => Boolean): List[A] = { val ftail = tail.filter(p) if (p(head)) head :: ftail @@ -177,54 +177,53 @@ final case class NonEmptyList[+A](head: A, tail: List[A]) { * res1: scala.collection.immutable.List[String] = List(odd, even, odd, even, odd) * }}} */ - def collect[B](pf: PartialFunction[A, B]) : List[B] = { + def collect[B](pf: PartialFunction[A, B]): List[B] = if (pf.isDefinedAt(head)) { pf.apply(head) :: tail.collect(pf) } else { tail.collect(pf) } - } /** - * Find the first element matching the predicate, if one exists - */ + * Find the first element matching the predicate, if one exists + */ def find(p: A => Boolean): Option[A] = if (p(head)) Some(head) else tail.find(p) /** - * Check whether at least one element satisfies the predicate - */ + * Check whether at least one element satisfies the predicate + */ def exists(p: A => Boolean): Boolean = p(head) || tail.exists(p) /** - * Check whether all elements satisfy the predicate - */ + * Check whether all elements satisfy the predicate + */ def forall(p: A => Boolean): Boolean = p(head) && tail.forall(p) /** - * Left-associative fold on the structure using f. - */ + * Left-associative fold on the structure using f. + */ def foldLeft[B](b: B)(f: (B, A) => B): B = tail.foldLeft(f(b, head))(f) /** - * Right-associative fold on the structure using f. - */ + * Right-associative fold on the structure using f. + */ def foldRight[B](lb: Eval[B])(f: (A, Eval[B]) => Eval[B]): Eval[B] = Foldable[List].foldRight(toList, lb)(f) /** - * Left-associative reduce using f. - */ + * Left-associative reduce using f. + */ def reduceLeft[AA >: A](f: (AA, AA) => AA): AA = tail.foldLeft[AA](head)(f) /** - * Reduce using the `Semigroup` of `AA`. - */ + * Reduce using the `Semigroup` of `AA`. + */ def reduce[AA >: A](implicit S: Semigroup[AA]): AA = S.combineAllOption(toList).get @@ -252,8 +251,8 @@ final case class NonEmptyList[+A](head: A, tail: List[A]) { override def toString: String = s"NonEmpty$toList" /** - * Remove duplicates. Duplicates are checked using `Order[_]` instance. - */ + * Remove duplicates. Duplicates are checked using `Order[_]` instance. + */ def distinct[AA >: A](implicit O: Order[AA]): NonEmptyList[AA] = { implicit val ord = O.toOrdering @@ -266,20 +265,20 @@ final case class NonEmptyList[+A](head: A, tail: List[A]) { } /** - * Reverse this `NonEmptyList`. - * - * {{{ - * scala> import cats.data.NonEmptyList - * scala> val nel = NonEmptyList.of(1, 2, 3) - * scala> nel.reverse - * res0: cats.data.NonEmptyList[Int] = NonEmptyList(3, 2, 1) - * }}} - */ + * Reverse this `NonEmptyList`. + * + * {{{ + * scala> import cats.data.NonEmptyList + * scala> val nel = NonEmptyList.of(1, 2, 3) + * scala> nel.reverse + * res0: cats.data.NonEmptyList[Int] = NonEmptyList(3, 2, 1) + * }}} + */ def reverse: NonEmptyList[A] = { @tailrec def go(h: A, rest: List[A], acc: List[A]): NonEmptyList[A] = rest match { - case Nil => NonEmptyList(h, acc) + case Nil => NonEmptyList(h, acc) case h1 :: t1 => go(h1, t1, h :: acc) } go(head, tail, Nil) @@ -300,8 +299,8 @@ final case class NonEmptyList[+A](head: A, tail: List[A]) { @tailrec def zwRev(as: List[A], bs: List[B], acc: List[C]): List[C] = (as, bs) match { - case (Nil, _) => acc - case (_, Nil) => acc + case (Nil, _) => acc + case (_, Nil) => acc case (x :: xs, y :: ys) => zwRev(xs, ys, f(x, y) :: acc) } @@ -309,15 +308,15 @@ final case class NonEmptyList[+A](head: A, tail: List[A]) { } /** - * Zips each element of this `NonEmptyList` with its index. - * - * {{{ - * scala> import cats.data.NonEmptyList - * scala> val nel = NonEmptyList.of("a", "b", "c") - * scala> nel.zipWithIndex - * res0: cats.data.NonEmptyList[(String, Int)] = NonEmptyList((a,0), (b,1), (c,2)) - * }}} - */ + * Zips each element of this `NonEmptyList` with its index. + * + * {{{ + * scala> import cats.data.NonEmptyList + * scala> val nel = NonEmptyList.of("a", "b", "c") + * scala> nel.zipWithIndex + * res0: cats.data.NonEmptyList[(String, Int)] = NonEmptyList((a,0), (b,1), (c,2)) + * }}} + */ def zipWithIndex: NonEmptyList[(A, Int)] = { val bldr = List.newBuilder[(A, Int)] var idx = 1 @@ -340,10 +339,9 @@ final case class NonEmptyList[+A](head: A, tail: List[A]) { * res0: cats.data.NonEmptyList[(Char, Int)] = NonEmptyList((z,1), (a,4), (e,22)) * }}} */ - def sortBy[B](f: A => B)(implicit B: Order[B]): NonEmptyList[A] = { + def sortBy[B](f: A => B)(implicit B: Order[B]): NonEmptyList[A] = // safe: sorting a NonEmptyList cannot produce an empty List NonEmptyList.fromListUnsafe(toList.sortBy(f)(B.toOrdering)) - } /** * Sorts this `NonEmptyList` according to an `Order` @@ -356,10 +354,9 @@ final case class NonEmptyList[+A](head: A, tail: List[A]) { * res0: cats.data.NonEmptyList[Int] = NonEmptyList(3, 4, 9, 12) * }}} */ - def sorted[AA >: A](implicit AA: Order[AA]): NonEmptyList[AA] = { + def sorted[AA >: A](implicit AA: Order[AA]): NonEmptyList[AA] = // safe: sorting a NonEmptyList cannot produce an empty List NonEmptyList.fromListUnsafe(toList.sorted(AA.toOrdering)) - } /** * Groups elements inside this `NonEmptyList` according to the `Order` @@ -382,14 +379,14 @@ final case class NonEmptyList[+A](head: A, tail: List[A]) { val k = f(elem) m.get(k) match { - case None => m += ((k, List.newBuilder[A] += elem)) + case None => m += ((k, List.newBuilder[A] += elem)) case Some(builder) => builder += elem } } m.map { case (k, v) => (k, NonEmptyList.fromListUnsafe(v.result)) - } : TreeMap[B, NonEmptyList[A]] + }: TreeMap[B, NonEmptyList[A]] } /** @@ -407,7 +404,6 @@ final case class NonEmptyList[+A](head: A, tail: List[A]) { def groupByNem[B](f: A => B)(implicit B: Order[B]): NonEmptyMap[B, NonEmptyList[A]] = NonEmptyMap.fromMapUnsafe(groupBy(f)) - /** * Creates new `NonEmptyMap`, similarly to List#toMap from scala standard library. *{{{ @@ -428,37 +424,37 @@ object NonEmptyList extends NonEmptyListInstances { def ofInitLast[A](init: List[A], last: A): NonEmptyList[A] = init match { - case Nil => NonEmptyList(last, Nil) + case Nil => NonEmptyList(last, Nil) case h :: t => NonEmptyList(h, t :+ last) } def one[A](head: A): NonEmptyList[A] = NonEmptyList(head, Nil) /** - * Create a `NonEmptyList` from a `List`. - * - * The result will be `None` if the input list is empty and `Some` wrapping a - * `NonEmptyList` otherwise. - * - * @see [[fromListUnsafe]] for an unsafe version that throws an exception if - * the input list is empty. - */ + * Create a `NonEmptyList` from a `List`. + * + * The result will be `None` if the input list is empty and `Some` wrapping a + * `NonEmptyList` otherwise. + * + * @see [[fromListUnsafe]] for an unsafe version that throws an exception if + * the input list is empty. + */ def fromList[A](l: List[A]): Option[NonEmptyList[A]] = l match { - case Nil => None + case Nil => None case h :: t => Some(NonEmptyList(h, t)) } /** - * Create a `NonEmptyList` from a `List`, or throw an - * `IllegalArgumentException` if the input list is empty. - * - * @see [[fromList]] for a safe version that returns `None` if the input list - * is empty. - */ + * Create a `NonEmptyList` from a `List`, or throw an + * `IllegalArgumentException` if the input list is empty. + * + * @see [[fromList]] for a safe version that returns `None` if the input list + * is empty. + */ def fromListUnsafe[A](l: List[A]): NonEmptyList[A] = l match { - case Nil => throw new IllegalArgumentException("Cannot create NonEmptyList from empty list") + case Nil => throw new IllegalArgumentException("Cannot create NonEmptyList from empty list") case h :: t => NonEmptyList(h, t) } @@ -478,28 +474,30 @@ object NonEmptyList extends NonEmptyListInstances { implicit val catsDataCommutativeApplyForZipNonEmptyList: CommutativeApply[ZipNonEmptyList] = new CommutativeApply[ZipNonEmptyList] { def ap[A, B](ff: ZipNonEmptyList[A => B])(fa: ZipNonEmptyList[A]): ZipNonEmptyList[B] = - ZipNonEmptyList(ff.value.zipWith(fa.value)(_ apply _)) + ZipNonEmptyList(ff.value.zipWith(fa.value)(_.apply(_))) override def map[A, B](fa: ZipNonEmptyList[A])(f: (A) => B): ZipNonEmptyList[B] = ZipNonEmptyList(fa.value.map(f)) override def product[A, B](fa: ZipNonEmptyList[A], fb: ZipNonEmptyList[B]): ZipNonEmptyList[(A, B)] = - ZipNonEmptyList(fa.value.zipWith(fb.value){ case (a, b) => (a, b) }) + ZipNonEmptyList(fa.value.zipWith(fb.value) { case (a, b) => (a, b) }) } implicit def zipNelEq[A: Eq]: Eq[ZipNonEmptyList[A]] = Eq.by(_.value) } } -private[data] sealed abstract class NonEmptyListInstances extends NonEmptyListInstances0 { +sealed abstract private[data] class NonEmptyListInstances extends NonEmptyListInstances0 { - implicit val catsDataInstancesForNonEmptyList: SemigroupK[NonEmptyList] with Reducible[NonEmptyList] - with Bimonad[NonEmptyList] with NonEmptyTraverse[NonEmptyList] = + implicit val catsDataInstancesForNonEmptyList: SemigroupK[NonEmptyList] + with Reducible[NonEmptyList] + with Bimonad[NonEmptyList] + with NonEmptyTraverse[NonEmptyList] = new NonEmptyReducible[NonEmptyList, List] with SemigroupK[NonEmptyList] with Bimonad[NonEmptyList] - with NonEmptyTraverse[NonEmptyList] { + with NonEmptyTraverse[NonEmptyList] { def combineK[A](a: NonEmptyList[A], b: NonEmptyList[A]): NonEmptyList[A] = - a concatNel b + a.concatNel(b) override def split[A](fa: NonEmptyList[A]): (A, List[A]) = (fa.head, fa.tail) @@ -510,29 +508,34 @@ private[data] sealed abstract class NonEmptyListInstances extends NonEmptyListIn fa.reduce override def map[A, B](fa: NonEmptyList[A])(f: A => B): NonEmptyList[B] = - fa map f + fa.map(f) def pure[A](x: A): NonEmptyList[A] = NonEmptyList.one(x) def flatMap[A, B](fa: NonEmptyList[A])(f: A => NonEmptyList[B]): NonEmptyList[B] = - fa flatMap f + fa.flatMap(f) def coflatMap[A, B](fa: NonEmptyList[A])(f: NonEmptyList[A] => B): NonEmptyList[B] = - fa coflatMap f + fa.coflatMap(f) def extract[A](fa: NonEmptyList[A]): A = fa.head def nonEmptyTraverse[G[_], A, B](nel: NonEmptyList[A])(f: A => G[B])(implicit G: Apply[G]): G[NonEmptyList[B]] = - Foldable[List].reduceRightToOption[A, G[List[B]]](nel.tail)(a => G.map(f(a))(_ :: Nil)) { (a, lglb) => - G.map2Eval(f(a), lglb)(_ :: _) - }.map { - case None => G.map(f(nel.head))(NonEmptyList(_, Nil)) - case Some(gtail) => G.map2(f(nel.head), gtail)(NonEmptyList(_, _)) - }.value + Foldable[List] + .reduceRightToOption[A, G[List[B]]](nel.tail)(a => G.map(f(a))(_ :: Nil)) { (a, lglb) => + G.map2Eval(f(a), lglb)(_ :: _) + } + .map { + case None => G.map(f(nel.head))(NonEmptyList(_, Nil)) + case Some(gtail) => G.map2(f(nel.head), gtail)(NonEmptyList(_, _)) + } + .value - override def traverse[G[_], A, B](fa: NonEmptyList[A])(f: A => G[B])(implicit G: Applicative[G]): G[NonEmptyList[B]] = - fa traverse f + override def traverse[G[_], A, B]( + fa: NonEmptyList[A] + )(f: A => G[B])(implicit G: Applicative[G]): G[NonEmptyList[B]] = + fa.traverse(f) override def foldLeft[A, B](fa: NonEmptyList[A], b: B)(f: (B, A) => B): B = fa.foldLeft(b)(f) @@ -546,14 +549,14 @@ private[data] sealed abstract class NonEmptyListInstances extends NonEmptyListIn def tailRecM[A, B](a: A)(f: A => NonEmptyList[Either[A, B]]): NonEmptyList[B] = { val buf = new ListBuffer[B] @tailrec def go(v: NonEmptyList[Either[A, B]]): Unit = v.head match { - case Right(b) => + case Right(b) => buf += b NonEmptyList.fromList(v.tail) match { case Some(t) => go(t) - case None => () + case None => () } case Left(a) => go(f(a) ++ v.tail) - } + } go(f(a)) NonEmptyList.fromListUnsafe(buf.result()) } @@ -561,31 +564,34 @@ private[data] sealed abstract class NonEmptyListInstances extends NonEmptyListIn override def fold[A](fa: NonEmptyList[A])(implicit A: Monoid[A]): A = fa.reduce - override def nonEmptyPartition[A, B, C](fa: NonEmptyList[A]) - (f: (A) => Either[B, C]): Ior[NonEmptyList[B], NonEmptyList[C]] = { + override def nonEmptyPartition[A, B, C]( + fa: NonEmptyList[A] + )(f: (A) => Either[B, C]): Ior[NonEmptyList[B], NonEmptyList[C]] = { import cats.syntax.either._ val reversed = fa.reverse val lastIor = f(reversed.head).bimap(NonEmptyList.one, NonEmptyList.one).toIor - reversed.tail.foldLeft(lastIor)((ior, a) => (f(a), ior) match { - case (Right(c), Ior.Left(_)) => ior.putRight(NonEmptyList.one(c)) - case (Right(c), _) => ior.map(c :: _) - case (Left(b), Ior.Right(r)) => Ior.bothNel(b, r) - case (Left(b), _) => ior.leftMap(b :: _) - }) + reversed.tail.foldLeft(lastIor)( + (ior, a) => + (f(a), ior) match { + case (Right(c), Ior.Left(_)) => ior.putRight(NonEmptyList.one(c)) + case (Right(c), _) => ior.map(c :: _) + case (Left(b), Ior.Right(r)) => Ior.bothNel(b, r) + case (Left(b), _) => ior.leftMap(b :: _) + } + ) } - override def find[A](fa: NonEmptyList[A])(f: A => Boolean): Option[A] = - fa find f + fa.find(f) override def forall[A](fa: NonEmptyList[A])(p: A => Boolean): Boolean = - fa forall p + fa.forall(p) override def exists[A](fa: NonEmptyList[A])(p: A => Boolean): Boolean = - fa exists p + fa.exists(p) override def toList[A](fa: NonEmptyList[A]): List[A] = fa.toList @@ -621,14 +627,14 @@ private[data] sealed abstract class NonEmptyListInstances extends NonEmptyListIn } } -private[data] sealed abstract class NonEmptyListInstances0 extends NonEmptyListInstances1 { +sealed abstract private[data] class NonEmptyListInstances0 extends NonEmptyListInstances1 { implicit def catsDataPartialOrderForNonEmptyList[A](implicit A: PartialOrder[A]): PartialOrder[NonEmptyList[A]] = new NonEmptyListPartialOrder[A] { val A0 = A } } -private[data] sealed abstract class NonEmptyListInstances1 { +sealed abstract private[data] class NonEmptyListInstances1 { implicit def catsDataEqForNonEmptyList[A](implicit A: Eq[A]): Eq[NonEmptyList[A]] = new NonEmptyListEq[A] { @@ -636,22 +642,24 @@ private[data] sealed abstract class NonEmptyListInstances1 { } } -private[data] sealed trait NonEmptyListEq[A] extends Eq[NonEmptyList[A]] { +sealed private[data] trait NonEmptyListEq[A] extends Eq[NonEmptyList[A]] { implicit def A0: Eq[A] override def eqv(x: NonEmptyList[A], y: NonEmptyList[A]): Boolean = x === y } -private[data] sealed trait NonEmptyListPartialOrder[A] extends PartialOrder[NonEmptyList[A]] with NonEmptyListEq[A] { - override implicit def A0: PartialOrder[A] +sealed private[data] trait NonEmptyListPartialOrder[A] extends PartialOrder[NonEmptyList[A]] with NonEmptyListEq[A] { + implicit override def A0: PartialOrder[A] override def partialCompare(x: NonEmptyList[A], y: NonEmptyList[A]): Double = - x.toList partialCompare y.toList + x.toList.partialCompare(y.toList) } -private[data] sealed abstract class NonEmptyListOrder[A] extends Order[NonEmptyList[A]] with NonEmptyListPartialOrder[A] { - override implicit def A0: Order[A] +sealed abstract private[data] class NonEmptyListOrder[A] + extends Order[NonEmptyList[A]] + with NonEmptyListPartialOrder[A] { + implicit override def A0: Order[A] override def compare(x: NonEmptyList[A], y: NonEmptyList[A]): Int = - x.toList compare y.toList + x.toList.compare(y.toList) } diff --git a/core/src/main/scala/cats/data/NonEmptyMapImpl.scala b/core/src/main/scala/cats/data/NonEmptyMapImpl.scala index 9ce00f0ece2..4ecbf479eb0 100644 --- a/core/src/main/scala/cats/data/NonEmptyMapImpl.scala +++ b/core/src/main/scala/cats/data/NonEmptyMapImpl.scala @@ -41,7 +41,6 @@ private[data] object NonEmptyMapImpl extends NonEmptyMapInstances with Newtype2 def apply[K, A](head: (K, A), tail: SortedMap[K, A])(implicit K: Order[K]): NonEmptyMap[K, A] = create(SortedMap(head)(K.toOrdering) ++ tail) - def of[K, A](a: (K, A), as: (K, A)*)(implicit K: Order[K]): NonEmptyMap[K, A] = create(SortedMap(as: _*)(K.toOrdering) + a) @@ -51,22 +50,23 @@ private[data] object NonEmptyMapImpl extends NonEmptyMapInstances with Newtype2 implicit def catsNonEmptyMapOps[K, A](value: Type[K, A]): NonEmptyMapOps[K, A] = new NonEmptyMapOps(value) - } sealed class NonEmptyMapOps[K, A](val value: NonEmptyMap[K, A]) { + /** * Converts this map to a `SortedMap`. */ def toSortedMap: SortedMap[K, A] = NonEmptyMapImpl.unwrap(value) - private implicit val ordering: Ordering[K] = toSortedMap.ordering - private implicit val order: Order[K] = Order.fromOrdering + implicit private val ordering: Ordering[K] = toSortedMap.ordering + implicit private val order: Order[K] = Order.fromOrdering /** * Alias for [[concat]] */ def ++(as: NonEmptyMap[K, A]): NonEmptyMap[K, A] = concat(as) + /** * Appends this NEM to another NEM, producing a new `NonEmptyMap`. */ @@ -77,7 +77,6 @@ sealed class NonEmptyMapOps[K, A](val value: NonEmptyMap[K, A]) { */ def -(key: K): SortedMap[K, A] = toSortedMap - key - /** * Adds a key-value pair to this map, returning a new `NonEmptyMap`. * */ @@ -103,6 +102,7 @@ sealed class NonEmptyMapOps[K, A](val value: NonEmptyMap[K, A]) { * Returns the first key-value pair of this map. */ def head: (K, A) = toSortedMap.head + /** * Returns the last key-value pair of this map. */ @@ -123,7 +123,6 @@ sealed class NonEmptyMapOps[K, A](val value: NonEmptyMap[K, A]) { */ def contains(key: K): Boolean = toSortedMap.contains(key) - /** * Tests whether a predicate holds for all elements of this map. */ @@ -142,14 +141,13 @@ sealed class NonEmptyMapOps[K, A](val value: NonEmptyMap[K, A]) { /** * Filters all elements of this map that do not satisfy the given predicate. */ - def filter(p: A ⇒ Boolean): SortedMap[K, A] = toSortedMap.filter { case (_, a) => p(a) } + def filter(p: A ⇒ Boolean): SortedMap[K, A] = toSortedMap.filter { case (_, a) => p(a) } /** * Filters all elements of this map that satisfy the given predicate. */ def filterNot(p: A ⇒ Boolean): SortedMap[K, A] = filter(t => !p(t)) - /** * Left-associative fold using f. */ @@ -168,7 +166,6 @@ sealed class NonEmptyMapOps[K, A](val value: NonEmptyMap[K, A]) { def reduceLeft(f: (A, A) => A): A = reduceLeftTo(identity)(f) - /** * Apply `f` to the "initial element" of `fa` and combine it with * every other value using the given function `g`. @@ -187,25 +184,27 @@ sealed class NonEmptyMapOps[K, A](val value: NonEmptyMap[K, A]) { * with every other value using the given function `g`. */ def reduceRightTo[B](f: A => B)(g: (A, Eval[B]) => Eval[B]): Eval[B] = - Always((head, tail)).flatMap { case ((_, a), ga) => - Foldable[SortedMap[K, ?]].reduceRightToOption(ga)(f)(g).flatMap { - case Some(b) => g(a, Now(b)) - case None => Later(f(a)) - } + Always((head, tail)).flatMap { + case ((_, a), ga) => + Foldable[SortedMap[K, ?]].reduceRightToOption(ga)(f)(g).flatMap { + case Some(b) => g(a, Now(b)) + case None => Later(f(a)) + } } - /** * Reduce using the Semigroup of A */ def reduce(implicit S: Semigroup[A]): A = reduceLeft(S.combine) - private def reduceRightToOptionWithKey[V, B](fa: SortedMap[K, V])(f: (K, V) => B)(g: ((K, V), Eval[B]) => Eval[B]): Eval[Option[B]] = + private def reduceRightToOptionWithKey[V, B]( + fa: SortedMap[K, V] + )(f: (K, V) => B)(g: ((K, V), Eval[B]) => Eval[B]): Eval[Option[B]] = Foldable.iterateRight(fa.toIterable, Now(Option.empty[B])) { (a, lb) => lb.flatMap { case Some(b) => g(a, Now(b)).map(Some(_)) - case None => Later(Some(f.tupled(a))) + case None => Later(Some(f.tupled(a))) } } @@ -215,12 +214,13 @@ sealed class NonEmptyMapOps[K, A](val value: NonEmptyMap[K, A]) { * returning an NonEmptyMap[K, B] in a G context. */ def nonEmptyTraverse[G[_], B](f: A => G[B])(implicit G: Apply[G]): G[NonEmptyMap[K, B]] = - reduceRightToOptionWithKey[A, G[SortedMap[K, B]]](tail)({ case (k, a) => - G.map(f(a))(b => SortedMap.empty[K, B] + ((k, b))) + reduceRightToOptionWithKey[A, G[SortedMap[K, B]]](tail)({ + case (k, a) => + G.map(f(a))(b => SortedMap.empty[K, B] + ((k, b))) }) { (t, lglb) => G.map2Eval(f(t._2), lglb)((b, bs) => bs + ((t._1, b))) }.map { - case None => G.map(f(head._2))(a => NonEmptyMapImpl.one(head._1, a)) + case None => G.map(f(head._2))(a => NonEmptyMapImpl.one(head._1, a)) case Some(gtail) => G.map2(f(head._2), gtail)((a, bs) => NonEmptyMapImpl((head._1, a), bs)) }.value @@ -256,10 +256,10 @@ sealed class NonEmptyMapOps[K, A](val value: NonEmptyMap[K, A]) { def toNel: NonEmptyList[(K, A)] = NonEmptyList.fromListUnsafe(toSortedMap.toList) } -private[data] sealed abstract class NonEmptyMapInstances { - +sealed abstract private[data] class NonEmptyMapInstances { - implicit def catsDataInstancesForNonEmptyMap[K: Order]: SemigroupK[NonEmptyMap[K, ?]] with NonEmptyTraverse[NonEmptyMap[K, ?]] = + implicit def catsDataInstancesForNonEmptyMap[K: Order] + : SemigroupK[NonEmptyMap[K, ?]] with NonEmptyTraverse[NonEmptyMap[K, ?]] = new SemigroupK[NonEmptyMap[K, ?]] with NonEmptyTraverse[NonEmptyMap[K, ?]] { override def map[A, B](fa: NonEmptyMap[K, A])(f: A => B): NonEmptyMap[K, B] = @@ -282,7 +282,7 @@ private[data] sealed abstract class NonEmptyMapInstances { fa.reduceRightTo(f)(g) def nonEmptyTraverse[G[_], A, B](fa: NonEmptyMap[K, A])(f: A => G[B])(implicit G: Apply[G]) = - fa nonEmptyTraverse f + fa.nonEmptyTraverse(f) override def foldLeft[A, B](fa: NonEmptyMap[K, A], b: B)(f: (B, A) => B): B = fa.foldLeft(b)(f) @@ -310,7 +310,7 @@ private[data] sealed abstract class NonEmptyMapInstances { } implicit def catsDataEqForNonEmptyMap[K: Order, A: Eq]: Eq[NonEmptyMap[K, A]] = - new Eq[NonEmptyMap[K, A]]{ + new Eq[NonEmptyMap[K, A]] { def eqv(x: NonEmptyMap[K, A], y: NonEmptyMap[K, A]): Boolean = x === y } @@ -321,4 +321,3 @@ private[data] sealed abstract class NonEmptyMapInstances { def combine(x: NonEmptyMap[K, A], y: NonEmptyMap[K, A]): NonEmptyMap[K, A] = x ++ y } } - diff --git a/core/src/main/scala/cats/data/NonEmptySet.scala b/core/src/main/scala/cats/data/NonEmptySet.scala index cf39299c121..9d92b660f61 100644 --- a/core/src/main/scala/cats/data/NonEmptySet.scala +++ b/core/src/main/scala/cats/data/NonEmptySet.scala @@ -22,7 +22,6 @@ import cats.kernel._ import scala.collection.immutable._ - private[data] object NonEmptySetImpl extends NonEmptySetInstances with Newtype { private[cats] def create[A](s: SortedSet[A]): Type[A] = @@ -31,7 +30,6 @@ private[data] object NonEmptySetImpl extends NonEmptySetInstances with Newtype { private[cats] def unwrap[A](s: Type[A]): SortedSet[A] = s.asInstanceOf[SortedSet[A]] - def fromSet[A](as: SortedSet[A]): Option[NonEmptySet[A]] = if (as.nonEmpty) Option(create(as)) else None @@ -39,7 +37,6 @@ private[data] object NonEmptySetImpl extends NonEmptySetInstances with Newtype { if (set.nonEmpty) create(set) else throw new IllegalArgumentException("Cannot create NonEmptySet from empty set") - def of[A](a: A, as: A*)(implicit A: Order[A]): NonEmptySet[A] = create(SortedSet(a +: as: _*)(A.toOrdering)) def apply[A](head: A, tail: SortedSet[A])(implicit A: Order[A]): NonEmptySet[A] = @@ -50,18 +47,16 @@ private[data] object NonEmptySetImpl extends NonEmptySetInstances with Newtype { new NonEmptySetOps(value) } - sealed class NonEmptySetOps[A](val value: NonEmptySet[A]) { - private implicit val ordering: Ordering[A] = toSortedSet.ordering - private implicit val order: Order[A] = Order.fromOrdering + implicit private val ordering: Ordering[A] = toSortedSet.ordering + implicit private val order: Order[A] = Order.fromOrdering /** * Converts this set to a `SortedSet` */ def toSortedSet: SortedSet[A] = NonEmptySetImpl.unwrap(value) - /** * Adds an element to this set, returning a new `NonEmptySet` */ @@ -89,7 +84,7 @@ sealed class NonEmptySetOps[A](val value: NonEmptySet[A]) { * res0: cats.data.NonEmptySet[Int] = TreeSet(1, 2, 4, 5, 7) * }}} */ - def | (as: NonEmptySet[A]): NonEmptySet[A] = union(as) + def |(as: NonEmptySet[A]): NonEmptySet[A] = union(as) /** * Alias for [[diff]] @@ -127,7 +122,6 @@ sealed class NonEmptySetOps[A](val value: NonEmptySet[A]) { */ def &(as: NonEmptySet[A]): SortedSet[A] = intersect(as) - /** * Removes a key from this set, returning a new `SortedSet`. */ @@ -141,7 +135,6 @@ sealed class NonEmptySetOps[A](val value: NonEmptySet[A]) { NonEmptySetImpl.create(toSortedSet.map(f)) } - /** * Converts this set to a `NonEmptyList`. * {{{ @@ -236,7 +229,6 @@ sealed class NonEmptySetOps[A](val value: NonEmptySet[A]) { */ def filterNot(p: A ⇒ Boolean): SortedSet[A] = filter(t => !p(t)) - /** * Left-associative fold using f. */ @@ -256,12 +248,11 @@ sealed class NonEmptySetOps[A](val value: NonEmptySet[A]) { toSortedSet.reduceLeft(f) /** - * Apply `f` to the "initial element" of this set and lazily combine it - * with every other value using the given function `g`. - */ - def reduceLeftTo[B](f: A => B)(g: (B, A) => B): B = { + * Apply `f` to the "initial element" of this set and lazily combine it + * with every other value using the given function `g`. + */ + def reduceLeftTo[B](f: A => B)(g: (B, A) => B): B = tail.foldLeft(f(head))((b, a) => g(b, a)) - } /** * Left-associative reduce using f. @@ -274,11 +265,12 @@ sealed class NonEmptySetOps[A](val value: NonEmptySet[A]) { * with every other value using the given function `g`. */ def reduceRightTo[B](f: A => B)(g: (A, Eval[B]) => Eval[B]): Eval[B] = - Always((head, tail)).flatMap { case (a, ga) => - Foldable[SortedSet].reduceRightToOption(ga)(f)(g).flatMap { - case Some(b) => g(a, Now(b)) - case None => Later(f(a)) - } + Always((head, tail)).flatMap { + case (a, ga) => + Foldable[SortedSet].reduceRightToOption(ga)(f)(g).flatMap { + case Some(b) => g(a, Now(b)) + case None => Later(f(a)) + } } /** @@ -299,10 +291,9 @@ sealed class NonEmptySetOps[A](val value: NonEmptySet[A]) { */ def concatMap[B](f: A => NonEmptySet[B])(implicit B: Order[B]): NonEmptySet[B] = { implicit val ordering = B.toOrdering - NonEmptySetImpl.create(toSortedSet.flatMap(f andThen (_.toSortedSet))) + NonEmptySetImpl.create(toSortedSet.flatMap(f.andThen(_.toSortedSet))) } - /** * Typesafe stringification method. * @@ -349,27 +340,25 @@ sealed class NonEmptySetOps[A](val value: NonEmptySet[A]) { /** * Zips this `NonEmptySet` with its index. */ - def zipWithIndex: NonEmptySet[(A, Int)] = { + def zipWithIndex: NonEmptySet[(A, Int)] = NonEmptySetImpl.create(cats.compat.SortedSet.zipWithIndex(toSortedSet)) - } /** * Groups elements inside this `NonEmptySet` according to the `Order` * of the keys produced by the given mapping function. */ - def groupBy[B](f: A => B)(implicit B: Order[B]): NonEmptyMap[B, NonEmptySet[A]] = { - reduceLeftTo(a => NonEmptyMap.one(f(a), NonEmptySet.one(a))) { (acc, a) => - val key = f(a) - val result = acc.lookup(key) match { - case Some(nes) => nes.add(a) - case _ => NonEmptySet.one(a) - } - acc.add((key, result)) - } - } + def groupBy[B](f: A => B)(implicit B: Order[B]): NonEmptyMap[B, NonEmptySet[A]] = + reduceLeftTo(a => NonEmptyMap.one(f(a), NonEmptySet.one(a))) { (acc, a) => + val key = f(a) + val result = acc.lookup(key) match { + case Some(nes) => nes.add(a) + case _ => NonEmptySet.one(a) + } + acc.add((key, result)) + } } -private[data] sealed abstract class NonEmptySetInstances { +sealed abstract private[data] class NonEmptySetInstances { implicit val catsDataInstancesForNonEmptySet: SemigroupK[NonEmptySet] with Reducible[NonEmptySet] = new SemigroupK[NonEmptySet] with Reducible[NonEmptySet] { @@ -417,7 +406,7 @@ private[data] sealed abstract class NonEmptySetInstances { } implicit def catsDataEqForNonEmptySet[A: Order]: Eq[NonEmptySet[A]] = - new Eq[NonEmptySet[A]]{ + new Eq[NonEmptySet[A]] { def eqv(x: NonEmptySet[A], y: NonEmptySet[A]): Boolean = x === y } @@ -428,4 +417,3 @@ private[data] sealed abstract class NonEmptySetInstances { def combine(x: NonEmptySet[A], y: NonEmptySet[A]): NonEmptySet[A] = x | y } } - diff --git a/core/src/main/scala/cats/data/NonEmptyVector.scala b/core/src/main/scala/cats/data/NonEmptyVector.scala index d0db284d52c..6447114c429 100644 --- a/core/src/main/scala/cats/data/NonEmptyVector.scala +++ b/core/src/main/scala/cats/data/NonEmptyVector.scala @@ -7,12 +7,12 @@ import scala.collection.immutable.{TreeSet, VectorBuilder} import cats.instances.vector._ /** - * A data type which represents a `Vector` guaranteed to contain at least one element. - *
- * Note that the constructor is `private` to prevent accidental construction of an empty - * `NonEmptyVector`. However, due to https://issues.scala-lang.org/browse/SI-6601, on - * Scala 2.10, this may be bypassed due to a compiler bug. - */ + * A data type which represents a `Vector` guaranteed to contain at least one element. + *
+ * Note that the constructor is `private` to prevent accidental construction of an empty + * `NonEmptyVector`. However, due to https://issues.scala-lang.org/browse/SI-6601, on + * Scala 2.10, this may be bypassed due to a compiler bug. + */ final class NonEmptyVector[+A] private (val toVector: Vector[A]) extends AnyVal { /** Gets the element at the index, if it exists */ @@ -27,11 +27,10 @@ final class NonEmptyVector[+A] private (val toVector: Vector[A]) extends AnyVal if (toVector.isDefinedAt(i)) Some(new NonEmptyVector(toVector.updated(i, a))) else None /** - * Updates the element at the index, or throws an `IndexOutOfBoundsException` - * if none exists (if `i` does not satisfy `0 <= i < length`). - */ - def updatedUnsafe[AA >: A](i: Int, a: AA): - NonEmptyVector[AA] = new NonEmptyVector(toVector.updated(i, a)) + * Updates the element at the index, or throws an `IndexOutOfBoundsException` + * if none exists (if `i` does not satisfy `0 <= i < length`). + */ + def updatedUnsafe[AA >: A](i: Int, a: AA): NonEmptyVector[AA] = new NonEmptyVector(toVector.updated(i, a)) def head: A = toVector.head @@ -68,8 +67,8 @@ final class NonEmptyVector[+A] private (val toVector: Vector[A]) extends AnyVal def collect[B](pf: PartialFunction[A, B]): Vector[B] = toVector.collect(pf) /** - * Alias for [[concat]] - */ + * Alias for [[concat]] + */ def ++[AA >: A](other: Vector[AA]): NonEmptyVector[AA] = concat(other) /** @@ -85,18 +84,18 @@ final class NonEmptyVector[+A] private (val toVector: Vector[A]) extends AnyVal def ++:[AA >: A](other: NonEmptyVector[AA]): NonEmptyVector[AA] = other.concatNev(this) /** - * Append another `Vector` to this, producing a new `NonEmptyVector`. - */ + * Append another `Vector` to this, producing a new `NonEmptyVector`. + */ def concat[AA >: A](other: Vector[AA]): NonEmptyVector[AA] = new NonEmptyVector(toVector ++ other) /** - * Append another `NonEmptyVector` to this, producing a new `NonEmptyVector`. - */ + * Append another `NonEmptyVector` to this, producing a new `NonEmptyVector`. + */ def concatNev[AA >: A](other: NonEmptyVector[AA]): NonEmptyVector[AA] = new NonEmptyVector(toVector ++ other.toVector) /** - * Append an item to this, producing a new `NonEmptyVector`. - */ + * Append an item to this, producing a new `NonEmptyVector`. + */ def append[AA >: A](a: AA): NonEmptyVector[AA] = new NonEmptyVector(toVector :+ a) /** @@ -105,8 +104,8 @@ final class NonEmptyVector[+A] private (val toVector: Vector[A]) extends AnyVal def :+[AA >: A](a: AA): NonEmptyVector[AA] = append(a) /** - * Prepend an item to this, producing a new `NonEmptyVector`. - */ + * Prepend an item to this, producing a new `NonEmptyVector`. + */ def prepend[AA >: A](a: AA): NonEmptyVector[AA] = new NonEmptyVector(a +: toVector) /** @@ -115,29 +114,29 @@ final class NonEmptyVector[+A] private (val toVector: Vector[A]) extends AnyVal def +:[AA >: A](a: AA): NonEmptyVector[AA] = prepend(a) /** - * Find the first element matching the predicate, if one exists - */ + * Find the first element matching the predicate, if one exists + */ def find(f: A => Boolean): Option[A] = toVector.find(f) /** - * Check whether at least one element satisfies the predicate. - */ + * Check whether at least one element satisfies the predicate. + */ def exists(f: A => Boolean): Boolean = toVector.exists(f) /** - * Check whether all elements satisfy the predicate. - */ + * Check whether all elements satisfy the predicate. + */ def forall(f: A => Boolean): Boolean = toVector.forall(f) /** - * Left-associative fold using f. - */ + * Left-associative fold using f. + */ def foldLeft[B](b: B)(f: (B, A) => B): B = toVector.foldLeft(b)(f) /** - * Right-associative fold using f. - */ + * Right-associative fold using f. + */ def foldRight[B](lb: Eval[B])(f: (A, Eval[B]) => Eval[B]): Eval[B] = Foldable[Vector].foldRight(toVector, lb)(f) @@ -166,23 +165,23 @@ final class NonEmptyVector[+A] private (val toVector: Vector[A]) extends AnyVal S.combineAllOption(toVector).get /** - * Typesafe equality operator. - * - * This method is similar to == except that it only allows two - * NonEmptyVector[A] values to be compared to each other, and uses - * equality provided by Eq[_] instances, rather than using the - * universal equality provided by .equals. - */ + * Typesafe equality operator. + * + * This method is similar to == except that it only allows two + * NonEmptyVector[A] values to be compared to each other, and uses + * equality provided by Eq[_] instances, rather than using the + * universal equality provided by .equals. + */ def ===[AA >: A](that: NonEmptyVector[AA])(implicit A: Eq[AA]): Boolean = Eq[Vector[AA]].eqv(toVector, that.toVector) /** - * Typesafe stringification method. - * - * This method is similar to .toString except that it stringifies - * values according to Show[_] instances, rather than using the - * universal .toString method. - */ + * Typesafe stringification method. + * + * This method is similar to .toString except that it stringifies + * values according to Show[_] instances, rather than using the + * universal .toString method. + */ def show[AA >: A](implicit AA: Show[AA]): String = s"NonEmpty${Show[Vector[AA]].show(toVector)}" @@ -191,8 +190,8 @@ final class NonEmptyVector[+A] private (val toVector: Vector[A]) extends AnyVal override def toString: String = s"NonEmpty${toVector.toString}" /** - * Remove duplicates. Duplicates are checked using `Order[_]` instance. - */ + * Remove duplicates. Duplicates are checked using `Order[_]` instance. + */ def distinct[AA >: A](implicit O: Order[AA]): NonEmptyVector[AA] = { implicit val ord = O.toOrdering @@ -231,15 +230,17 @@ final class NonEmptyVector[+A] private (val toVector: Vector[A]) extends AnyVal new NonEmptyVector(toVector.sorted(AA.toOrdering)) } -private[data] sealed abstract class NonEmptyVectorInstances { +sealed abstract private[data] class NonEmptyVectorInstances { - implicit val catsDataInstancesForNonEmptyVector: SemigroupK[NonEmptyVector] with Reducible[NonEmptyVector] - with Bimonad[NonEmptyVector] with NonEmptyTraverse[NonEmptyVector] = + implicit val catsDataInstancesForNonEmptyVector: SemigroupK[NonEmptyVector] + with Reducible[NonEmptyVector] + with Bimonad[NonEmptyVector] + with NonEmptyTraverse[NonEmptyVector] = new NonEmptyReducible[NonEmptyVector, Vector] with SemigroupK[NonEmptyVector] with Bimonad[NonEmptyVector] - with NonEmptyTraverse[NonEmptyVector] { + with NonEmptyTraverse[NonEmptyVector] { def combineK[A](a: NonEmptyVector[A], b: NonEmptyVector[A]): NonEmptyVector[A] = - a concatNev b + a.concatNev(b) override def split[A](fa: NonEmptyVector[A]): (A, Vector[A]) = (fa.head, fa.tail) @@ -252,34 +253,41 @@ private[data] sealed abstract class NonEmptyVectorInstances { fa.reduce override def map[A, B](fa: NonEmptyVector[A])(f: A => B): NonEmptyVector[B] = - fa map f + fa.map(f) def pure[A](x: A): NonEmptyVector[A] = NonEmptyVector.one(x) def flatMap[A, B](fa: NonEmptyVector[A])(f: A => NonEmptyVector[B]): NonEmptyVector[B] = - fa flatMap f + fa.flatMap(f) def coflatMap[A, B](fa: NonEmptyVector[A])(f: NonEmptyVector[A] => B): NonEmptyVector[B] = { @tailrec def consume(as: Vector[A], buf: VectorBuilder[B]): Vector[B] = as match { case a +: as => consume(as, buf += f(NonEmptyVector(a, as))) - case _ => buf.result() + case _ => buf.result() } NonEmptyVector(f(fa), consume(fa.tail, new VectorBuilder[B])) } def extract[A](fa: NonEmptyVector[A]): A = fa.head - def nonEmptyTraverse[G[_], A, B](nel: NonEmptyVector[A])(f: A => G[B])(implicit G: Apply[G]): G[NonEmptyVector[B]] = - Foldable[Vector].reduceRightToOption[A, G[Vector[B]]](nel.tail)(a => G.map(f(a))(_ +: Vector.empty)) { (a, lglb) => - G.map2Eval(f(a), lglb)(_ +: _) - }.map { - case None => G.map(f(nel.head))(NonEmptyVector(_, Vector.empty)) - case Some(gtail) => G.map2(f(nel.head), gtail)(NonEmptyVector(_, _)) - }.value + def nonEmptyTraverse[G[_], A, B]( + nel: NonEmptyVector[A] + )(f: A => G[B])(implicit G: Apply[G]): G[NonEmptyVector[B]] = + Foldable[Vector] + .reduceRightToOption[A, G[Vector[B]]](nel.tail)(a => G.map(f(a))(_ +: Vector.empty)) { (a, lglb) => + G.map2Eval(f(a), lglb)(_ +: _) + } + .map { + case None => G.map(f(nel.head))(NonEmptyVector(_, Vector.empty)) + case Some(gtail) => G.map2(f(nel.head), gtail)(NonEmptyVector(_, _)) + } + .value - override def traverse[G[_], A, B](fa: NonEmptyVector[A])(f: (A) => G[B])(implicit G: Applicative[G]): G[NonEmptyVector[B]] = + override def traverse[G[_], A, B]( + fa: NonEmptyVector[A] + )(f: (A) => G[B])(implicit G: Applicative[G]): G[NonEmptyVector[B]] = G.map2Eval(f(fa.head), Always(Traverse[Vector].traverse(fa.tail)(f)))(NonEmptyVector(_, _)).value override def zipWithIndex[A](fa: NonEmptyVector[A]): NonEmptyVector[(A, Int)] = @@ -294,16 +302,21 @@ private[data] sealed abstract class NonEmptyVectorInstances { override def foldMap[A, B](fa: NonEmptyVector[A])(f: A => B)(implicit B: Monoid[B]): B = B.combineAll(fa.toVector.iterator.map(f)) - override def nonEmptyPartition[A, B, C](fa: NonEmptyVector[A])(f: (A) => Either[B, C]): Ior[NonEmptyList[B], NonEmptyList[C]] = { + override def nonEmptyPartition[A, B, C]( + fa: NonEmptyVector[A] + )(f: (A) => Either[B, C]): Ior[NonEmptyList[B], NonEmptyList[C]] = { import cats.syntax.either._ import cats.syntax.reducible._ - reduceLeftTo(fa)(a => f(a).bimap(NonEmptyVector.one, NonEmptyVector.one).toIor)((ior, a) => (f(a), ior) match { - case (Right(c), Ior.Left(_)) => ior.putRight(NonEmptyVector.one(c)) - case (Right(c), _) => ior.map(_ :+ c) - case (Left(b), Ior.Right(_)) => ior.putLeft(NonEmptyVector.one(b)) - case (Left(b), _) => ior.leftMap(_ :+ b) - }).bimap(_.toNonEmptyList, _.toNonEmptyList) + reduceLeftTo(fa)(a => f(a).bimap(NonEmptyVector.one, NonEmptyVector.one).toIor)( + (ior, a) => + (f(a), ior) match { + case (Right(c), Ior.Left(_)) => ior.putRight(NonEmptyVector.one(c)) + case (Right(c), _) => ior.map(_ :+ c) + case (Left(b), Ior.Right(_)) => ior.putLeft(NonEmptyVector.one(b)) + case (Left(b), _) => ior.leftMap(_ :+ b) + } + ).bimap(_.toNonEmptyList, _.toNonEmptyList) } @@ -313,14 +326,14 @@ private[data] sealed abstract class NonEmptyVectorInstances { def tailRecM[A, B](a: A)(f: A => NonEmptyVector[Either[A, B]]): NonEmptyVector[B] = { val buf = new VectorBuilder[B] @tailrec def go(v: NonEmptyVector[Either[A, B]]): Unit = v.head match { - case Right(b) => + case Right(b) => buf += b NonEmptyVector.fromVector(v.tail) match { case Some(t) => go(t) - case None => () + case None => () } case Left(a) => go(f(a).concat(v.tail)) - } + } go(f(a)) NonEmptyVector.fromVectorUnsafe(buf.result()) } @@ -344,7 +357,7 @@ private[data] sealed abstract class NonEmptyVectorInstances { } implicit def catsDataEqForNonEmptyVector[A](implicit A: Eq[A]): Eq[NonEmptyVector[A]] = - new Eq[NonEmptyVector[A]]{ + new Eq[NonEmptyVector[A]] { def eqv(x: NonEmptyVector[A], y: NonEmptyVector[A]): Boolean = x === y } @@ -402,13 +415,13 @@ object NonEmptyVector extends NonEmptyVectorInstances with Serializable { implicit val catsDataCommutativeApplyForZipNonEmptyVector: CommutativeApply[ZipNonEmptyVector] = new CommutativeApply[ZipNonEmptyVector] { def ap[A, B](ff: ZipNonEmptyVector[A => B])(fa: ZipNonEmptyVector[A]): ZipNonEmptyVector[B] = - ZipNonEmptyVector(ff.value.zipWith(fa.value)(_ apply _)) + ZipNonEmptyVector(ff.value.zipWith(fa.value)(_.apply(_))) override def map[A, B](fa: ZipNonEmptyVector[A])(f: (A) => B): ZipNonEmptyVector[B] = ZipNonEmptyVector(fa.value.map(f)) override def product[A, B](fa: ZipNonEmptyVector[A], fb: ZipNonEmptyVector[B]): ZipNonEmptyVector[(A, B)] = - ZipNonEmptyVector(fa.value.zipWith(fb.value){ case (a, b) => (a, b) }) + ZipNonEmptyVector(fa.value.zipWith(fb.value) { case (a, b) => (a, b) }) } implicit def zipNevEq[A: Eq]: Eq[ZipNonEmptyVector[A]] = Eq.by(_.value) diff --git a/core/src/main/scala/cats/data/OneAnd.scala b/core/src/main/scala/cats/data/OneAnd.scala index 3d4454f989e..6ab9ed36163 100644 --- a/core/src/main/scala/cats/data/OneAnd.scala +++ b/core/src/main/scala/cats/data/OneAnd.scala @@ -6,109 +6,108 @@ import scala.collection.mutable.Builder import cats.instances.stream._ /** - * A data type which represents a single element (head) and some other - * structure (tail). As we have done in package.scala, this can be - * used to represent a Stream which is guaranteed to not be empty: - * - * {{{ - * type NonEmptyStream[A] = OneAnd[Stream, A] - * }}} - */ + * A data type which represents a single element (head) and some other + * structure (tail). As we have done in package.scala, this can be + * used to represent a Stream which is guaranteed to not be empty: + * + * {{{ + * type NonEmptyStream[A] = OneAnd[Stream, A] + * }}} + */ final case class OneAnd[F[_], A](head: A, tail: F[A]) { /** - * Combine the head and tail into a single `F[A]` value. - */ + * Combine the head and tail into a single `F[A]` value. + */ def unwrap(implicit F: Alternative[F]): F[A] = F.combineK(F.pure(head), tail) /** - * remove elements not matching the predicate - */ + * remove elements not matching the predicate + */ def filter(f: A => Boolean)(implicit FA: Alternative[F], FM: Monad[F]): F[A] = { val rest = FM.flatMap(tail)(a => if (f(a)) FM.pure(a) else FA.empty[A]) if (f(head)) FA.combineK(FM.pure(head), rest) else rest } /** - * Append another OneAnd to this - */ + * Append another OneAnd to this + */ def combine(other: OneAnd[F, A])(implicit F: Alternative[F]): OneAnd[F, A] = OneAnd(head, F.combineK(tail, F.combineK(F.pure(other.head), other.tail))) /** - * find the first element matching the predicate, if one exists - */ + * find the first element matching the predicate, if one exists + */ def find(f: A => Boolean)(implicit F: Foldable[F]): Option[A] = if (f(head)) Some(head) else F.find(tail)(f) /** - * Check whether at least one element satisfies the predicate. - */ + * Check whether at least one element satisfies the predicate. + */ def exists(p: A => Boolean)(implicit F: Foldable[F]): Boolean = p(head) || F.exists(tail)(p) /** - * Check whether all elements satisfy the predicate. - */ + * Check whether all elements satisfy the predicate. + */ def forall(p: A => Boolean)(implicit F: Foldable[F]): Boolean = p(head) && F.forall(tail)(p) - def reduceLeft(f: (A, A) => A)(implicit F: Foldable[F]): A = F.foldLeft(tail, head)(f) /** - * Left-associative fold on the structure using f. - */ + * Left-associative fold on the structure using f. + */ def foldLeft[B](b: B)(f: (B, A) => B)(implicit F: Foldable[F]): B = F.foldLeft(tail, f(b, head))(f) /** - * Right-associative fold on the structure using f. - */ + * Right-associative fold on the structure using f. + */ def foldRight[B](lb: Eval[B])(f: (A, Eval[B]) => Eval[B])(implicit F: Foldable[F]): Eval[B] = Eval.defer(f(head, F.foldRight(tail, lb)(f))) /** - * Applies f to all the elements of the structure - */ + * Applies f to all the elements of the structure + */ def map[B](f: A => B)(implicit F: Functor[F]): OneAnd[F, B] = OneAnd(f(head), F.map(tail)(f)) /** - * Modify the context `F` using transformation `f`. - */ + * Modify the context `F` using transformation `f`. + */ def mapK[G[_]](f: F ~> G): OneAnd[G, A] = OneAnd(head, f(tail)) /** - * Typesafe equality operator. - * - * This method is similar to == except that it only allows two - * OneAnd[F, A] values to be compared to each other, and uses - * equality provided by Eq[_] instances, rather than using the - * universal equality provided by .equals. - */ + * Typesafe equality operator. + * + * This method is similar to == except that it only allows two + * OneAnd[F, A] values to be compared to each other, and uses + * equality provided by Eq[_] instances, rather than using the + * universal equality provided by .equals. + */ def ===(that: OneAnd[F, A])(implicit A: Eq[A], FA: Eq[F[A]]): Boolean = A.eqv(head, that.head) && FA.eqv(tail, that.tail) /** - * Typesafe stringification method. - * - * This method is similar to .toString except that it stringifies - * values according to Show[_] instances, rather than using the - * universal .toString method. - */ + * Typesafe stringification method. + * + * This method is similar to .toString except that it stringifies + * values according to Show[_] instances, rather than using the + * universal .toString method. + */ def show(implicit A: Show[A], FA: Show[F[A]]): String = s"OneAnd(${A.show(head)}, ${FA.show(tail)})" } +sealed abstract private[data] class OneAndInstances extends OneAndLowPriority0 { -private[data] sealed abstract class OneAndInstances extends OneAndLowPriority0 { - - implicit def catsDataParallelForOneAnd[A, M[_] : Alternative, F[_] : Alternative] - (implicit P: Parallel[M, F]): Parallel[OneAnd[M, ?], OneAnd[F, ?]] = + implicit def catsDataParallelForOneAnd[A, M[_]: Alternative, F[_]: Alternative]( + implicit P: Parallel[M, F] + ): Parallel[OneAnd[M, ?], OneAnd[F, ?]] = new Parallel[OneAnd[M, ?], OneAnd[F, ?]] { def monad: Monad[OneAnd[M, ?]] = catsDataMonadForOneAnd(P.monad, Alternative[M]) @@ -123,7 +122,7 @@ private[data] sealed abstract class OneAndInstances extends OneAndLowPriority0 { } implicit def catsDataEqForOneAnd[A, F[_]](implicit A: Eq[A], FA: Eq[F[A]]): Eq[OneAnd[F, A]] = - new Eq[OneAnd[F, A]]{ + new Eq[OneAnd[F, A]] { def eqv(x: OneAnd[F, A], y: OneAnd[F, A]): Boolean = x === y } @@ -133,14 +132,14 @@ private[data] sealed abstract class OneAndInstances extends OneAndLowPriority0 { implicit def catsDataSemigroupKForOneAnd[F[_]: Alternative]: SemigroupK[OneAnd[F, ?]] = new SemigroupK[OneAnd[F, ?]] { def combineK[A](a: OneAnd[F, A], b: OneAnd[F, A]): OneAnd[F, A] = - a combine b + a.combine(b) } implicit def catsDataSemigroupForOneAnd[F[_]: Alternative, A]: Semigroup[OneAnd[F, A]] = catsDataSemigroupKForOneAnd[F].algebra - - implicit def catsDataMonadForOneAnd[F[_]](implicit monad: Monad[F], alternative: Alternative[F]): Monad[OneAnd[F, ?]] = + implicit def catsDataMonadForOneAnd[F[_]](implicit monad: Monad[F], + alternative: Alternative[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)(monad) @@ -170,8 +169,8 @@ private[data] sealed abstract class OneAndInstances extends OneAndLowPriority0 { // This could probably be in SemigroupK to perform well @tailrec def combineAll(items: List[F[B]]): F[B] = items match { - case Nil => alternative.empty - case h :: Nil => h + case Nil => alternative.empty + case h :: Nil => h case h1 :: h2 :: tail => combineAll(alternative.combineK(h1, h2) :: tail) } @@ -191,7 +190,7 @@ private[data] sealed abstract class OneAndInstances extends OneAndLowPriority0 { } } -private[data] sealed abstract class OneAndLowPriority4 { +sealed abstract private[data] class OneAndLowPriority4 { implicit val catsDataComonadForNonEmptyStream: Comonad[OneAnd[Stream, ?]] = new Comonad[OneAnd[Stream, ?]] { def coflatMap[A, B](fa: OneAnd[Stream, A])(f: OneAnd[Stream, A] => B): OneAnd[Stream, B] = { @@ -208,21 +207,21 @@ private[data] sealed abstract class OneAndLowPriority4 { fa.head def map[A, B](fa: OneAnd[Stream, A])(f: A => B): OneAnd[Stream, B] = - fa map f + fa.map(f) } } -private[data] sealed abstract class OneAndLowPriority3 extends OneAndLowPriority4 { +sealed abstract private[data] class OneAndLowPriority3 extends OneAndLowPriority4 { 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 + fa.map(f) } } -private[data] sealed abstract class OneAndLowPriority2 extends OneAndLowPriority3 { +sealed abstract private[data] class OneAndLowPriority2 extends OneAndLowPriority3 { implicit def catsDataApplicativeForOneAnd[F[_]](implicit F: Alternative[F]): Applicative[OneAnd[F, ?]] = new Applicative[OneAnd[F, ?]] { @@ -242,25 +241,22 @@ private[data] sealed abstract class OneAndLowPriority2 extends OneAndLowPriority } -private[data] sealed abstract class OneAndLowPriority1 extends OneAndLowPriority2 { +sealed abstract private[data] class OneAndLowPriority1 extends OneAndLowPriority2 { 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]] = { + 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 - } - def foldLeft[A, B](fa: OneAnd[F, A], b: B)(f: (B, A) => B): B = { + def foldLeft[A, B](fa: OneAnd[F, A], b: B)(f: (B, A) => B): B = fa.foldLeft(b)(f) - } - def foldRight[A, B](fa: OneAnd[F, A], lb: Eval[B])(f: (A, Eval[B]) => Eval[B]): Eval[B] = { + def foldRight[A, B](fa: OneAnd[F, A], lb: Eval[B])(f: (A, Eval[B]) => Eval[B]): Eval[B] = fa.foldRight(lb)(f) - } } } -private[data] sealed abstract class OneAndLowPriority0_5 extends OneAndLowPriority1 { +sealed abstract private[data] class OneAndLowPriority0_5 extends OneAndLowPriority1 { 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) @@ -272,8 +268,9 @@ private[data] sealed abstract class OneAndLowPriority0_5 extends OneAndLowPriori } } -private[data] sealed abstract class OneAndLowPriority0 extends OneAndLowPriority0_5 { - implicit def catsDataNonEmptyTraverseForOneAnd[F[_]](implicit F: Traverse[F], F2: Alternative[F]): NonEmptyTraverse[OneAnd[F, ?]] = +sealed abstract private[data] class OneAndLowPriority0 extends OneAndLowPriority0_5 { + implicit def catsDataNonEmptyTraverseForOneAnd[F[_]](implicit F: Traverse[F], + F2: Alternative[F]): NonEmptyTraverse[OneAnd[F, ?]] = new NonEmptyReducible[OneAnd[F, ?], F] with NonEmptyTraverse[OneAnd[F, ?]] { def nonEmptyTraverse[G[_], A, B](fa: OneAnd[F, A])(f: (A) => G[B])(implicit G: Apply[G]): G[OneAnd[F, B]] = { import cats.syntax.apply._ @@ -282,10 +279,8 @@ private[data] sealed abstract class OneAndLowPriority0 extends OneAndLowPriority .reduceLeft(((acc, a) => (acc, a).mapN((x: OneAnd[F, B], y: OneAnd[F, B]) => x.combine(y)))) } - - override def traverse[G[_], A, B](fa: OneAnd[F, A])(f: (A) => G[B])(implicit G: Applicative[G]): G[OneAnd[F, B]] = { + override 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 - } def split[A](fa: OneAnd[F, A]): (A, F[A]) = (fa.head, fa.tail) } diff --git a/core/src/main/scala/cats/data/Op.scala b/core/src/main/scala/cats/data/Op.scala index e93d3be6482..30dbca5cc34 100644 --- a/core/src/main/scala/cats/data/Op.scala +++ b/core/src/main/scala/cats/data/Op.scala @@ -4,8 +4,8 @@ package data import cats.arrow._ /** - * The dual category of some other category, `Arr`. - */ + * The dual category of some other category, `Arr`. + */ final case class Op[Arr[_, _], A, B](run: Arr[B, A]) { def compose[Z](op: Op[Arr, Z, A])(implicit Arr: Compose[Arr]): Op[Arr, Z, B] = Op(Arr.compose(op.run, run)) @@ -16,7 +16,7 @@ final case class Op[Arr[_, _], A, B](run: Arr[B, A]) { object Op extends OpInstances -private[data] sealed abstract class OpInstances extends OpInstances0 { +sealed abstract private[data] class OpInstances extends OpInstances0 { implicit def catsDataCategoryForOp[Arr[_, _]](implicit ArrC: Category[Arr]): Category[Op[Arr, ?, ?]] = new OpCategory[Arr] { def Arr: Category[Arr] = ArrC } @@ -24,7 +24,7 @@ private[data] sealed abstract class OpInstances extends OpInstances0 { new OpEq[Arr, A, B] { def Arr: Eq[Arr[B, A]] = ArrEq } } -private[data] sealed abstract class OpInstances0 { +sealed abstract private[data] class OpInstances0 { implicit def catsDataComposeForOp[Arr[_, _]](implicit ArrC: Compose[Arr]): Compose[Op[Arr, ?, ?]] = new OpCompose[Arr] { def Arr: Compose[Arr] = ArrC } } diff --git a/core/src/main/scala/cats/data/OptionT.scala b/core/src/main/scala/cats/data/OptionT.scala index ff57f9c3b01..f0b35ff8fb0 100644 --- a/core/src/main/scala/cats/data/OptionT.scala +++ b/core/src/main/scala/cats/data/OptionT.scala @@ -5,23 +5,23 @@ import cats.instances.option.{catsStdInstancesForOption => optionInstance, catsS import cats.syntax.either._ /** - * `OptionT[F[_], A]` is a light wrapper on an `F[Option[A]]` with some - * convenient methods for working with this nested structure. - * - * It may also be said that `OptionT` is a monad transformer for `Option`. - * - * For more information, see the [[http://typelevel.org/cats/datatypes/optiont.html documentation]]. - */ + * `OptionT[F[_], A]` is a light wrapper on an `F[Option[A]]` with some + * convenient methods for working with this nested structure. + * + * It may also be said that `OptionT` is a monad transformer for `Option`. + * + * For more information, see the [[http://typelevel.org/cats/datatypes/optiont.html documentation]]. + */ final case class OptionT[F[_], A](value: F[Option[A]]) { def fold[B](default: => B)(f: A => B)(implicit F: Functor[F]): F[B] = F.map(value)(_.fold(default)(f)) /** - * Catamorphism on the Option. This is identical to [[fold]], but it only has - * one parameter list, which can result in better type inference in some - * contexts. - */ + * Catamorphism on the Option. This is identical to [[fold]], but it only has + * one parameter list, which can result in better type inference in some + * contexts. + */ def cata[B](default: => B, f: A => B)(implicit F: Functor[F]): F[B] = fold(default)(f) @@ -30,17 +30,17 @@ final case class OptionT[F[_], A](value: F[Option[A]]) { def imap[B](f: A => B)(g: B => A)(implicit F: Invariant[F]): OptionT[F, B] = OptionT { - F.imap(value)(_ map f)(_ map g) + F.imap(value)(_.map(f))(_.map(g)) } def contramap[B](f: B => A)(implicit F: Contravariant[F]): OptionT[F, B] = OptionT { - F.contramap(value)(_ map f) + F.contramap(value)(_.map(f)) } /** - * Modify the context `F` using transformation `f`. - */ + * Modify the context `F` using transformation `f`. + */ def mapK[G[_]](f: F ~> G): OptionT[G, A] = OptionT[G, A](f(value)) def semiflatMap[B](f: A => F[B])(implicit F: Monad[F]): OptionT[F, B] = @@ -98,11 +98,10 @@ final case class OptionT[F[_], A](value: F[Option[A]]) { orElseF(default.value) def orElseF(default: => F[Option[A]])(implicit F: Monad[F]): OptionT[F, A] = - OptionT( - F.flatMap(value) { - case s @ Some(_) => F.pure(s) - case None => default - }) + OptionT(F.flatMap(value) { + case s @ Some(_) => F.pure(s) + case None => default + }) def toRight[L](left: => L)(implicit F: Functor[F]): EitherT[F, L, A] = EitherT(cata(Left(left), Right.apply)) @@ -131,102 +130,102 @@ final case class OptionT[F[_], A](value: F[Option[A]]) { F.compose(optionInstance).foldRight(value, lb)(f) /** - * Transform this `OptionT[F, A]` into a `[[Nested]][F, Option, A]`. - * - * An example where `toNested` can be used, is to get the `Apply.ap` function with the - * behavior from the composed `Apply` instances from `F` and `Option`, which is - * inconsistent with the behavior of the `ap` from `Monad` of `OptionT`. - * - * {{{ - * scala> import cats.implicits._ - * scala> import cats.data.OptionT - * scala> val ff: OptionT[List, Int => String] = - * | OptionT(List(Option(_.toString), None)) - * scala> val fa: OptionT[List, Int] = OptionT(List(Option(1), Option(2))) - * scala> ff.ap(fa) - * res0: OptionT[List,String] = OptionT(List(Some(1), Some(2), None)) - * scala> OptionT(ff.toNested.ap(fa.toNested).value) - * res1: OptionT[List,String] = OptionT(List(Some(1), Some(2), None, None)) - * }}} - */ + * Transform this `OptionT[F, A]` into a `[[Nested]][F, Option, A]`. + * + * An example where `toNested` can be used, is to get the `Apply.ap` function with the + * behavior from the composed `Apply` instances from `F` and `Option`, which is + * inconsistent with the behavior of the `ap` from `Monad` of `OptionT`. + * + * {{{ + * scala> import cats.implicits._ + * scala> import cats.data.OptionT + * scala> val ff: OptionT[List, Int => String] = + * | OptionT(List(Option(_.toString), None)) + * scala> val fa: OptionT[List, Int] = OptionT(List(Option(1), Option(2))) + * scala> ff.ap(fa) + * res0: OptionT[List,String] = OptionT(List(Some(1), Some(2), None)) + * scala> OptionT(ff.toNested.ap(fa.toNested).value) + * res1: OptionT[List,String] = OptionT(List(Some(1), Some(2), None, None)) + * }}} + */ def toNested: Nested[F, Option, A] = Nested(value) } object OptionT extends OptionTInstances { /** - * Uses the [[http://typelevel.org/cats/guidelines.html#partially-applied-type-params Partially Applied Type Params technique]] for ergonomics. - */ - private[data] final class PurePartiallyApplied[F[_]](val dummy: Boolean = true ) extends AnyVal { + * Uses the [[http://typelevel.org/cats/guidelines.html#partially-applied-type-params Partially Applied Type Params technique]] for ergonomics. + */ + final private[data] class PurePartiallyApplied[F[_]](val dummy: Boolean = true) extends AnyVal { def apply[A](value: A)(implicit F: Applicative[F]): OptionT[F, A] = OptionT(F.pure(Some(value))) } /** Creates a `OptionT[A]` from an `A` - * - * {{{ - * scala> import cats.implicits._ - * scala> OptionT.pure[List](2) - * res0: OptionT[List, Int] = OptionT(List(Some(2))) - * }}} - * - */ + * + * {{{ + * scala> import cats.implicits._ + * scala> OptionT.pure[List](2) + * res0: OptionT[List, Int] = OptionT(List(Some(2))) + * }}} + * + */ def pure[F[_]]: PurePartiallyApplied[F] = new PurePartiallyApplied[F] /** An alias for pure - * - * {{{ - * scala> import cats.implicits._ - * scala> OptionT.some[List](2) - * res0: OptionT[List, Int] = OptionT(List(Some(2))) - * }}} - * - */ + * + * {{{ + * scala> import cats.implicits._ + * scala> OptionT.some[List](2) + * res0: OptionT[List, Int] = OptionT(List(Some(2))) + * }}} + * + */ def some[F[_]]: PurePartiallyApplied[F] = pure - def none[F[_], A](implicit F: Applicative[F]) : OptionT[F, A] = + def none[F[_], A](implicit F: Applicative[F]): OptionT[F, A] = OptionT(F.pure(None)) /** - * Transforms an `Option` into an `OptionT`, lifted into the specified `Applicative`. - * - * {{{ - * scala> import cats.implicits._ - * scala> val o: Option[Int] = Some(2) - * scala> OptionT.fromOption[List](o) - * res0: OptionT[List, Int] = OptionT(List(Some(2))) - * }}} - */ + * Transforms an `Option` into an `OptionT`, lifted into the specified `Applicative`. + * + * {{{ + * scala> import cats.implicits._ + * scala> val o: Option[Int] = Some(2) + * scala> OptionT.fromOption[List](o) + * res0: OptionT[List, Int] = OptionT(List(Some(2))) + * }}} + */ def fromOption[F[_]]: FromOptionPartiallyApplied[F] = new FromOptionPartiallyApplied /** - * Uses the [[http://typelevel.org/cats/guidelines.html#partially-applied-type-params Partially Applied Type Params technique]] for ergonomics. - */ - private[data] final class FromOptionPartiallyApplied[F[_]](val dummy: Boolean = true ) extends AnyVal { + * Uses the [[http://typelevel.org/cats/guidelines.html#partially-applied-type-params Partially Applied Type Params technique]] for ergonomics. + */ + final private[data] class FromOptionPartiallyApplied[F[_]](val dummy: Boolean = true) extends AnyVal { def apply[A](value: Option[A])(implicit F: Applicative[F]): OptionT[F, A] = OptionT(F.pure(value)) } /** - * Lifts the `F[A]` Functor into an `OptionT[F, A]`. - */ + * Lifts the `F[A]` Functor into an `OptionT[F, A]`. + */ def liftF[F[_], A](fa: F[A])(implicit F: Functor[F]): OptionT[F, A] = OptionT(F.map(fa)(Some(_))) /** - * Same as [[liftF]], but expressed as a FunctionK for use with mapK - * {{{ - * scala> import cats._, data._, implicits._ - * scala> val a: EitherT[Eval, String, Int] = 1.pure[EitherT[Eval, String, ?]] - * scala> val b: EitherT[OptionT[Eval, ?], String, Int] = a.mapK(OptionT.liftK) - * scala> b.value.value.value - * res0: Option[Either[String,Int]] = Some(Right(1)) - * }}} - */ + * Same as [[liftF]], but expressed as a FunctionK for use with mapK + * {{{ + * scala> import cats._, data._, implicits._ + * scala> val a: EitherT[Eval, String, Int] = 1.pure[EitherT[Eval, String, ?]] + * scala> val b: EitherT[OptionT[Eval, ?], String, Int] = a.mapK(OptionT.liftK) + * scala> b.value.value.value + * res0: Option[Either[String,Int]] = Some(Right(1)) + * }}} + */ def liftK[F[_]](implicit F: Functor[F]): F ~> OptionT[F, ?] = λ[F ~> OptionT[F, ?]](OptionT.liftF(_)) } -private[data] sealed abstract class OptionTInstances extends OptionTInstances0 { +sealed abstract private[data] class OptionTInstances extends OptionTInstances0 { // to maintain binary compatibility def catsDataMonadForOptionT[F[_]](implicit F0: Monad[F]): Monad[OptionT[F, ?]] = new OptionTMonad[F] { implicit val F = F0 } @@ -255,26 +254,28 @@ private[data] sealed abstract class OptionTInstances extends OptionTInstances0 { val traverse: Traverse[OptionT[F, ?]] = OptionT.catsDataTraverseForOptionT[F] - def traverseFilter[G[_], A, B](fa: OptionT[F, A]) - (f: A => G[Option[B]]) - (implicit G: Applicative[G]): G[OptionT[F, B]] = - G.map(Traverse[F].traverse[G, Option[A], Option[B]](fa.value) { - oa => TraverseFilter[Option].traverseFilter(oa)(f) - })(OptionT[F, B]) + def traverseFilter[G[_], A, B]( + fa: OptionT[F, A] + )(f: A => G[Option[B]])(implicit G: Applicative[G]): G[OptionT[F, B]] = + G.map(Traverse[F].traverse[G, Option[A], Option[B]](fa.value) { oa => + TraverseFilter[Option].traverseFilter(oa)(f) + })(OptionT[F, B]) - override def filterA[G[_], A](fa: OptionT[F, A]) - (f: A => G[Boolean]) - (implicit G: Applicative[G]): G[OptionT[F, A]] = - G.map(Traverse[F].traverse(fa.value)(TraverseFilter[Option].filterA[G, A](_)(f)))(OptionT[F, A]) + override def filterA[G[_], A]( + fa: OptionT[F, A] + )(f: A => G[Boolean])(implicit G: Applicative[G]): G[OptionT[F, A]] = + G.map(Traverse[F].traverse(fa.value)(TraverseFilter[Option].filterA[G, A](_)(f)))(OptionT[F, A]) } } -private[data] sealed abstract class OptionTInstances0 extends OptionTInstances1 { +sealed abstract private[data] class OptionTInstances0 extends OptionTInstances1 { implicit def catsDataMonadErrorMonadForOptionT[F[_]](implicit F0: Monad[F]): MonadError[OptionT[F, ?], Unit] = new OptionTMonadErrorMonad[F] { implicit val F = F0 } - implicit def catsDataContravariantMonoidalForOptionT[F[_]](implicit F0: ContravariantMonoidal[F]): ContravariantMonoidal[OptionT[F, ?]] = + implicit def catsDataContravariantMonoidalForOptionT[F[_]]( + implicit F0: ContravariantMonoidal[F] + ): ContravariantMonoidal[OptionT[F, ?]] = new OptionTContravariantMonoidal[F] { implicit val F = F0 } implicit def catsDataMonoidKForOptionT[F[_]](implicit F0: Monad[F]): MonoidK[OptionT[F, ?]] = @@ -283,7 +284,9 @@ private[data] sealed abstract class OptionTInstances0 extends OptionTInstances1 implicit def catsDataSemigroupForOptionT[F[_], A](implicit F0: Semigroup[F[Option[A]]]): Semigroup[OptionT[F, A]] = new OptionTSemigroup[F, A] { implicit val F = F0 } - implicit def catsDataPartialOrderForOptionT[F[_], A](implicit F0: PartialOrder[F[Option[A]]]): PartialOrder[OptionT[F, A]] = + implicit def catsDataPartialOrderForOptionT[F[_], A]( + implicit F0: PartialOrder[F[Option[A]]] + ): PartialOrder[OptionT[F, A]] = new OptionTPartialOrder[F, A] { implicit val F = F0 } implicit def catsDateFunctorFilterForOptionT[F[_]](implicit F0: Functor[F]): FunctorFilter[OptionT[F, ?]] = @@ -293,7 +296,7 @@ private[data] sealed abstract class OptionTInstances0 extends OptionTInstances1 new OptionTContravariant[F] { implicit val F = F0 } } -private[data] sealed abstract class OptionTInstances1 extends OptionTInstances2 { +sealed abstract private[data] class OptionTInstances1 extends OptionTInstances2 { implicit def catsDataSemigroupKForOptionT[F[_]](implicit F0: Monad[F]): SemigroupK[OptionT[F, ?]] = new OptionTSemigroupK[F] { implicit val F = F0 } @@ -304,7 +307,7 @@ private[data] sealed abstract class OptionTInstances1 extends OptionTInstances2 new OptionTMonadError[F, E] { implicit val F = F0 } } -private[data] sealed abstract class OptionTInstances2 extends OptionTInstances3 { +sealed abstract private[data] class OptionTInstances2 extends OptionTInstances3 { implicit def catsDataFoldableForOptionT[F[_]](implicit F0: Foldable[F]): Foldable[OptionT[F, ?]] = new OptionTFoldable[F] { implicit val F = F0 } @@ -312,7 +315,7 @@ private[data] sealed abstract class OptionTInstances2 extends OptionTInstances3 new OptionTInvariant[F] { implicit val F = F0 } } -private[data] sealed abstract class OptionTInstances3 { +sealed abstract private[data] class OptionTInstances3 { implicit def catsDataFunctorForOptionT[F[_]](implicit F0: Functor[F]): Functor[OptionT[F, ?]] = new OptionTFunctor[F] { implicit val F = F0 } } @@ -323,18 +326,18 @@ private[data] trait OptionTFunctor[F[_]] extends Functor[OptionT[F, ?]] { override def map[A, B](fa: OptionT[F, A])(f: A => B): OptionT[F, B] = fa.map(f) } -private[data] sealed trait OptionTInvariant[F[_]] extends Invariant[OptionT[F, ?]] { +sealed private[data] trait OptionTInvariant[F[_]] extends Invariant[OptionT[F, ?]] { implicit def F: Invariant[F] override def imap[A, B](fa: OptionT[F, A])(f: A => B)(g: B => A): OptionT[F, B] = fa.imap(f)(g) } -private[data] sealed trait OptionTContravariant[F[_]] extends Contravariant[OptionT[F, ?]] { +sealed private[data] trait OptionTContravariant[F[_]] extends Contravariant[OptionT[F, ?]] { implicit def F: Contravariant[F] override def contramap[A, B](fa: OptionT[F, A])(f: B => A): OptionT[F, B] = - fa contramap f + fa.contramap(f) } private[data] trait OptionTMonad[F[_]] extends Monad[OptionT[F, ?]] { @@ -347,9 +350,14 @@ private[data] trait OptionTMonad[F[_]] extends Monad[OptionT[F, ?]] { override def map[A, B](fa: OptionT[F, A])(f: A => B): OptionT[F, B] = fa.map(f) def tailRecM[A, B](a: A)(f: A => OptionT[F, Either[A, B]]): OptionT[F, B] = - OptionT(F.tailRecM(a)(a0 => F.map(f(a0).value)( - _.fold(Either.right[A, Option[B]](None))(_.map(b => Some(b): Option[B])) - ))) + OptionT( + F.tailRecM(a)( + a0 => + F.map(f(a0).value)( + _.fold(Either.right[A, Option[B]](None))(_.map(b => Some(b): Option[B])) + ) + ) + ) } private[data] trait OptionTMonadErrorMonad[F[_]] extends MonadError[OptionT[F, ?], Unit] with OptionTMonad[F] { @@ -360,7 +368,7 @@ private[data] trait OptionTMonadErrorMonad[F[_]] extends MonadError[OptionT[F, ? override def handleErrorWith[A](fa: OptionT[F, A])(f: Unit => OptionT[F, A]): OptionT[F, A] = OptionT(F.flatMap(fa.value) { case s @ Some(_) => F.pure(s) - case None => f(()).value + case None => f(()).value }) } @@ -380,15 +388,18 @@ private trait OptionTContravariantMonoidal[F[_]] extends ContravariantMonoidal[O override def unit: OptionT[F, Unit] = OptionT(F.trivial) override def contramap[A, B](fa: OptionT[F, A])(f: B => A): OptionT[F, B] = - OptionT(F.contramap(fa.value)(_ map f)) + OptionT(F.contramap(fa.value)(_.map(f))) override def product[A, B](fa: OptionT[F, A], fb: OptionT[F, B]): OptionT[F, (A, B)] = - OptionT(F.contramap(F.product(fa.value, fb.value))( - (t: Option[(A, B)]) => t match { - case Some((x, y)) => (Some(x), Some(y)) - case None => (None, None) + OptionT( + F.contramap(F.product(fa.value, fb.value))( + (t: Option[(A, B)]) => + t match { + case Some((x, y)) => (Some(x), Some(y)) + case None => (None, None) } - )) + ) + ) } private[data] trait OptionTFoldable[F[_]] extends Foldable[OptionT[F, ?]] { @@ -401,11 +412,11 @@ private[data] trait OptionTFoldable[F[_]] extends Foldable[OptionT[F, ?]] { fa.foldRight(lb)(f) } -private[data] sealed trait OptionTTraverse[F[_]] extends Traverse[OptionT[F, ?]] with OptionTFoldable[F] { +sealed private[data] trait OptionTTraverse[F[_]] extends Traverse[OptionT[F, ?]] with OptionTFoldable[F] { implicit def F: Traverse[F] def traverse[G[_]: Applicative, A, B](fa: OptionT[F, A])(f: A => G[B]): G[OptionT[F, B]] = - fa traverse f + fa.traverse(f) } private[data] trait OptionTSemigroup[F[_], A] extends Semigroup[OptionT[F, A]] { @@ -424,26 +435,26 @@ private[data] trait OptionTMonoid[F[_], A] extends Monoid[OptionT[F, A]] with Op private[data] trait OptionTSemigroupK[F[_]] extends SemigroupK[OptionT[F, ?]] { implicit def F: Monad[F] - def combineK[A](x: OptionT[F, A], y: OptionT[F, A]): OptionT[F, A] = x orElse y + def combineK[A](x: OptionT[F, A], y: OptionT[F, A]): OptionT[F, A] = x.orElse(y) } private[data] trait OptionTMonoidK[F[_]] extends MonoidK[OptionT[F, ?]] with OptionTSemigroupK[F] { def empty[A]: OptionT[F, A] = OptionT.none[F, A] } -private[data] sealed trait OptionTEq[F[_], A] extends Eq[OptionT[F, A]] { +sealed private[data] trait OptionTEq[F[_], A] extends Eq[OptionT[F, A]] { implicit def F: Eq[F[Option[A]]] override def eqv(x: OptionT[F, A], y: OptionT[F, A]): Boolean = x === y } -private[data] sealed trait OptionTPartialOrder[F[_], A] extends PartialOrder[OptionT[F, A]] with OptionTEq[F, A]{ - override implicit def F: PartialOrder[F[Option[A]]] +sealed private[data] trait OptionTPartialOrder[F[_], A] extends PartialOrder[OptionT[F, A]] with OptionTEq[F, A] { + implicit override def F: PartialOrder[F[Option[A]]] - override def partialCompare(x: OptionT[F, A], y: OptionT[F, A]): Double = x partialCompare y + override def partialCompare(x: OptionT[F, A], y: OptionT[F, A]): Double = x.partialCompare(y) } -private[data] sealed trait OptionTFunctorFilter[F[_]] extends FunctorFilter[OptionT[F, ?]] { +sealed private[data] trait OptionTFunctorFilter[F[_]] extends FunctorFilter[OptionT[F, ?]] { implicit def F: Functor[F] def functor: Functor[OptionT[F, ?]] = OptionT.catsDataFunctorForOptionT[F] @@ -457,8 +468,8 @@ private[data] sealed trait OptionTFunctorFilter[F[_]] extends FunctorFilter[Opti override def filter[A](fa: OptionT[F, A])(f: (A) => Boolean): OptionT[F, A] = fa.filter(f) } -private[data] sealed trait OptionTOrder[F[_], A] extends Order[OptionT[F, A]] with OptionTPartialOrder[F, A]{ - override implicit def F: Order[F[Option[A]]] +sealed private[data] trait OptionTOrder[F[_], A] extends Order[OptionT[F, A]] with OptionTPartialOrder[F, A] { + implicit override def F: Order[F[Option[A]]] - override def compare(x: OptionT[F, A], y: OptionT[F, A]): Int = x compare y + override def compare(x: OptionT[F, A], y: OptionT[F, A]): Int = x.compare(y) } diff --git a/core/src/main/scala/cats/data/RepresentableStore.scala b/core/src/main/scala/cats/data/RepresentableStore.scala index 4a0349e2212..acf3ee55018 100644 --- a/core/src/main/scala/cats/data/RepresentableStore.scala +++ b/core/src/main/scala/cats/data/RepresentableStore.scala @@ -3,56 +3,59 @@ package cats.data import cats.{Comonad, Functor, Representable} /** - * A generalisation of the Store comonad, for any `Representable` functor. - * `Store` is the dual of `State` - */ + * A generalisation of the Store comonad, for any `Representable` functor. + * `Store` is the dual of `State` + */ final case class RepresentableStore[F[_], S, A](fa: F[A], index: S)(implicit R: Representable.Aux[F, S]) { + /** - * Inspect the value at "index" s - */ + * Inspect the value at "index" s + */ def peek(s: S): A = R.index(fa)(s) /** - * Extract the value at the current index. - */ + * Extract the value at the current index. + */ lazy val extract: A = peek(index) /** - * Duplicate the store structure - */ + * Duplicate the store structure + */ lazy val coflatten: RepresentableStore[F, S, RepresentableStore[F, S, A]] = RepresentableStore(R.tabulate(idx => RepresentableStore(fa, idx)), index) - def map[B](f: A => B): RepresentableStore[F, S, B] = { + def map[B](f: A => B): RepresentableStore[F, S, B] = RepresentableStore(R.F.map(fa)(f), index) - } /** - * Given a functorial computation on the index `S` peek at the value in that functor. - * - * {{{ - * import cats._, implicits._, data.Store - * - * val initial = List("a", "b", "c") - * val store = Store(idx => initial.get(idx).getOrElse(""), 0) - * val adjacent = store.experiment[List] { idx => List(idx - 1, idx, idx + 1) } - * - * require(adjacent == List("", "a", "b")) - * }}} - */ - def experiment[G[_]](fn: S => G[S])(implicit G: Functor[G]): G[A] = { + * Given a functorial computation on the index `S` peek at the value in that functor. + * + * {{{ + * import cats._, implicits._, data.Store + * + * val initial = List("a", "b", "c") + * val store = Store(idx => initial.get(idx).getOrElse(""), 0) + * val adjacent = store.experiment[List] { idx => List(idx - 1, idx, idx + 1) } + * + * require(adjacent == List("", "a", "b")) + * }}} + */ + def experiment[G[_]](fn: S => G[S])(implicit G: Functor[G]): G[A] = G.map(fn(index))(peek) - } } object RepresentableStore { - implicit def catsDataRepresentableStoreComonad[F[_], S](implicit R: Representable[F]): Comonad[RepresentableStore[F, S, ?]] = + implicit def catsDataRepresentableStoreComonad[F[_], S]( + implicit R: Representable[F] + ): Comonad[RepresentableStore[F, S, ?]] = new Comonad[RepresentableStore[F, S, ?]] { override def extract[B](x: RepresentableStore[F, S, B]): B = x.extract - override def coflatMap[A, B](fa: RepresentableStore[F, S, A])(f: RepresentableStore[F, S, A] => B): RepresentableStore[F, S, B] = + override def coflatMap[A, B]( + fa: RepresentableStore[F, S, A] + )(f: RepresentableStore[F, S, A] => B): RepresentableStore[F, S, B] = fa.coflatten.map(f) override def map[A, B](fa: RepresentableStore[F, S, A])(f: A => B): RepresentableStore[F, S, B] = diff --git a/core/src/main/scala/cats/data/Tuple2K.scala b/core/src/main/scala/cats/data/Tuple2K.scala index 18aa1ca2825..c3f97427386 100644 --- a/core/src/main/scala/cats/data/Tuple2K.scala +++ b/core/src/main/scala/cats/data/Tuple2K.scala @@ -4,15 +4,15 @@ package data import cats.Contravariant /** - * [[Tuple2K]] is a product to two independent functor values. - * - * See: [[https://www.cs.ox.ac.uk/jeremy.gibbons/publications/iterator.pdf The Essence of the Iterator Pattern]] - */ + * [[Tuple2K]] is a product to two independent functor values. + * + * See: [[https://www.cs.ox.ac.uk/jeremy.gibbons/publications/iterator.pdf The Essence of the Iterator Pattern]] + */ final case class Tuple2K[F[_], G[_], A](first: F[A], second: G[A]) { /** - * Modify the context `G` of `second` using transformation `f`. - */ + * Modify the context `G` of `second` using transformation `f`. + */ def mapK[H[_]](f: G ~> H): Tuple2K[F, H, A] = Tuple2K(first, f(second)) @@ -21,16 +21,22 @@ final case class Tuple2K[F[_], G[_], A](first: F[A], second: G[A]) { object Tuple2K extends Tuple2KInstances -private[data] sealed abstract class Tuple2KInstances extends Tuple2KInstances0 { - implicit def catsDataOrderForTuple2K[F[_], G[_], A](implicit FF: Order[F[A]], GF: Order[G[A]]): Order[Tuple2K[F, G, A]] = new Tuple2KOrder[F, G, A] { - def F: Order[F[A]] = FF - def G: Order[G[A]] = GF - } - implicit def catsDataShowForTuple2K[F[_], G[_], A](implicit FF: Show[F[A]], GF: Show[G[A]]): Show[Tuple2K[F, G, A]] = new Tuple2KShow[F, G, A] { - def F: Show[F[A]] = FF - def G: Show[G[A]] = GF - } - implicit def catsDataContravariantMonoidalForTuple2k[F[_], G[_]](implicit FD: ContravariantMonoidal[F], GD: ContravariantMonoidal[G]): ContravariantMonoidal[λ[α => Tuple2K[F, G, α]]] = +sealed abstract private[data] class Tuple2KInstances extends Tuple2KInstances0 { + implicit def catsDataOrderForTuple2K[F[_], G[_], A](implicit FF: Order[F[A]], + GF: Order[G[A]]): Order[Tuple2K[F, G, A]] = + new Tuple2KOrder[F, G, A] { + def F: Order[F[A]] = FF + def G: Order[G[A]] = GF + } + implicit def catsDataShowForTuple2K[F[_], G[_], A](implicit FF: Show[F[A]], GF: Show[G[A]]): Show[Tuple2K[F, G, A]] = + new Tuple2KShow[F, G, A] { + def F: Show[F[A]] = FF + def G: Show[G[A]] = GF + } + implicit def catsDataContravariantMonoidalForTuple2k[F[_], G[_]]( + implicit FD: ContravariantMonoidal[F], + GD: ContravariantMonoidal[G] + ): ContravariantMonoidal[λ[α => Tuple2K[F, G, α]]] = new Tuple2KContravariantMonoidal[F, G] with Tuple2KContravariant[F, G] { def F: ContravariantMonoidal[F] = FD def G: ContravariantMonoidal[G] = GD @@ -47,120 +53,152 @@ private[data] sealed abstract class Tuple2KInstances extends Tuple2KInstances0 { } } -private[data] sealed abstract class Tuple2KInstances0 extends Tuple2KInstances1 { - implicit def catsDataTraverseForTuple2K[F[_], G[_]](implicit FF: Traverse[F], GF: Traverse[G]): Traverse[λ[α => Tuple2K[F, G, α]]] = +sealed abstract private[data] class Tuple2KInstances0 extends Tuple2KInstances1 { + implicit def catsDataTraverseForTuple2K[F[_], G[_]](implicit FF: Traverse[F], + GF: Traverse[G]): Traverse[λ[α => Tuple2K[F, G, α]]] = new Tuple2KTraverse[F, G] with Tuple2KFunctor[F, G] { def F: Traverse[F] = FF def G: Traverse[G] = GF } - implicit def catsDataContravariantForTuple2K[F[_], G[_]](implicit FC: Contravariant[F], GC: Contravariant[G]): Contravariant[λ[α => Tuple2K[F, G, α]]] = new Tuple2KContravariant[F, G] { + implicit def catsDataContravariantForTuple2K[F[_], G[_]]( + implicit FC: Contravariant[F], + GC: Contravariant[G] + ): Contravariant[λ[α => Tuple2K[F, G, α]]] = new Tuple2KContravariant[F, G] { def F: Contravariant[F] = FC def G: Contravariant[G] = GC } - implicit def catsDataEqForTuple2K[F[_], G[_], A](implicit FF: Eq[F[A]], GG: Eq[G[A]]): Eq[Tuple2K[F, G, A]] = new Eq[Tuple2K[F, G, A]] { - def eqv(x: Tuple2K[F, G, A], y: Tuple2K[F, G, A]): Boolean = - FF.eqv(x.first, y.first) && GG.eqv(x.second, y.second) - } + implicit def catsDataEqForTuple2K[F[_], G[_], A](implicit FF: Eq[F[A]], GG: Eq[G[A]]): Eq[Tuple2K[F, G, A]] = + new Eq[Tuple2K[F, G, A]] { + def eqv(x: Tuple2K[F, G, A], y: Tuple2K[F, G, A]): Boolean = + FF.eqv(x.first, y.first) && GG.eqv(x.second, y.second) + } } -private[data] sealed abstract class Tuple2KInstances1 extends Tuple2KInstances2 { - implicit def catsDataAlternativeForTuple2K[F[_], G[_]](implicit FF: Alternative[F], GG: Alternative[G]): Alternative[λ[α => Tuple2K[F, G, α]]] = new Tuple2KAlternative[F, G] { - def F: Alternative[F] = FF - def G: Alternative[G] = GG - } - implicit def catsDataFoldableForTuple2K[F[_], G[_]](implicit FF: Foldable[F], GF: Foldable[G]): Foldable[λ[α => Tuple2K[F, G, α]]] = new Tuple2KFoldable[F, G] { - def F: Foldable[F] = FF - def G: Foldable[G] = GF - } +sealed abstract private[data] class Tuple2KInstances1 extends Tuple2KInstances2 { + implicit def catsDataAlternativeForTuple2K[F[_], G[_]](implicit FF: Alternative[F], + GG: Alternative[G]): Alternative[λ[α => Tuple2K[F, G, α]]] = + new Tuple2KAlternative[F, G] { + def F: Alternative[F] = FF + def G: Alternative[G] = GG + } + implicit def catsDataFoldableForTuple2K[F[_], G[_]](implicit FF: Foldable[F], + GF: Foldable[G]): Foldable[λ[α => Tuple2K[F, G, α]]] = + new Tuple2KFoldable[F, G] { + def F: Foldable[F] = FF + def G: Foldable[G] = GF + } } -private[data] sealed abstract class Tuple2KInstances2 extends Tuple2KInstances3 { - implicit def catsDataMonadForTuple2K[F[_], G[_]](implicit FM: Monad[F], GM: Monad[G]): Monad[λ[α => Tuple2K[F, G, α]]] = new Tuple2KMonad[F, G] { - def F: Monad[F] = FM - def G: Monad[G] = GM - } - implicit def catsDataMonoidKForTuple2K[F[_], G[_]](implicit FF: MonoidK[F], GG: MonoidK[G]): MonoidK[λ[α => Tuple2K[F, G, α]]] = new Tuple2KMonoidK[F, G] { - def F: MonoidK[F] = FF - def G: MonoidK[G] = GG - } +sealed abstract private[data] class Tuple2KInstances2 extends Tuple2KInstances3 { + implicit def catsDataMonadForTuple2K[F[_], G[_]](implicit FM: Monad[F], + GM: Monad[G]): Monad[λ[α => Tuple2K[F, G, α]]] = + new Tuple2KMonad[F, G] { + def F: Monad[F] = FM + def G: Monad[G] = GM + } + implicit def catsDataMonoidKForTuple2K[F[_], G[_]](implicit FF: MonoidK[F], + GG: MonoidK[G]): MonoidK[λ[α => Tuple2K[F, G, α]]] = + new Tuple2KMonoidK[F, G] { + def F: MonoidK[F] = FF + def G: MonoidK[G] = GG + } } -private[data] sealed abstract class Tuple2KInstances3 extends Tuple2KInstances4 { - implicit def catsDataCommutativeApplicativeForTuple2K[F[_], G[_]](implicit FF: CommutativeApplicative[F], GG: CommutativeApplicative[G]): CommutativeApplicative[λ[α => Tuple2K[F, G, α]]] = +sealed abstract private[data] class Tuple2KInstances3 extends Tuple2KInstances4 { + implicit def catsDataCommutativeApplicativeForTuple2K[F[_], G[_]]( + implicit FF: CommutativeApplicative[F], + GG: CommutativeApplicative[G] + ): CommutativeApplicative[λ[α => Tuple2K[F, G, α]]] = new Tuple2KApplicative[F, G] with CommutativeApplicative[λ[α => Tuple2K[F, G, α]]] { def F: Applicative[F] = FF def G: Applicative[G] = GG } } -private[data] sealed abstract class Tuple2KInstances4 extends Tuple2KInstances5 { - implicit def catsDataSemigroupKForTuple2K[F[_], G[_]](implicit FF: SemigroupK[F], GG: SemigroupK[G]): SemigroupK[λ[α => Tuple2K[F, G, α]]] = new Tuple2KSemigroupK[F, G] { - def F: SemigroupK[F] = FF - def G: SemigroupK[G] = GG - } - implicit def catsDataCommutativeApplyForTuple2K[F[_], G[_]](implicit FF: CommutativeApply[F], GG: CommutativeApply[G]): CommutativeApply[λ[α => Tuple2K[F, G, α]]] = +sealed abstract private[data] class Tuple2KInstances4 extends Tuple2KInstances5 { + implicit def catsDataSemigroupKForTuple2K[F[_], G[_]](implicit FF: SemigroupK[F], + GG: SemigroupK[G]): SemigroupK[λ[α => Tuple2K[F, G, α]]] = + new Tuple2KSemigroupK[F, G] { + def F: SemigroupK[F] = FF + def G: SemigroupK[G] = GG + } + implicit def catsDataCommutativeApplyForTuple2K[F[_], G[_]]( + implicit FF: CommutativeApply[F], + GG: CommutativeApply[G] + ): CommutativeApply[λ[α => Tuple2K[F, G, α]]] = new Tuple2KApply[F, G] with CommutativeApply[λ[α => Tuple2K[F, G, α]]] { def F: Apply[F] = FF def G: Apply[G] = GG } } -private[data] sealed abstract class Tuple2KInstances5 extends Tuple2KInstances6 { - implicit def catsDataApplicativeForTuple2K[F[_], G[_]](implicit FF: Applicative[F], GG: Applicative[G]): Applicative[λ[α => Tuple2K[F, G, α]]] = new Tuple2KApplicative[F, G] { - def F: Applicative[F] = FF - def G: Applicative[G] = GG - } +sealed abstract private[data] class Tuple2KInstances5 extends Tuple2KInstances6 { + implicit def catsDataApplicativeForTuple2K[F[_], G[_]](implicit FF: Applicative[F], + GG: Applicative[G]): Applicative[λ[α => Tuple2K[F, G, α]]] = + new Tuple2KApplicative[F, G] { + def F: Applicative[F] = FF + def G: Applicative[G] = GG + } } - -private[data] sealed abstract class Tuple2KInstances6 extends Tuple2KInstances7 { - implicit def catsDataApplyForTuple2K[F[_], G[_]](implicit FF: Apply[F], GG: Apply[G]): Apply[λ[α => Tuple2K[F, G, α]]] = new Tuple2KApply[F, G] { - def F: Apply[F] = FF - def G: Apply[G] = GG - } +sealed abstract private[data] class Tuple2KInstances6 extends Tuple2KInstances7 { + implicit def catsDataApplyForTuple2K[F[_], G[_]](implicit FF: Apply[F], + GG: Apply[G]): Apply[λ[α => Tuple2K[F, G, α]]] = + new Tuple2KApply[F, G] { + def F: Apply[F] = FF + def G: Apply[G] = GG + } } -private[data] sealed abstract class Tuple2KInstances7 extends Tuple2KInstances8 { - implicit def catsDataDistributiveForTuple2K[F[_], G[_]](implicit FF: Distributive[F], GG: Distributive[G]): Distributive[λ[α => Tuple2K[F, G, α]]] = +sealed abstract private[data] class Tuple2KInstances7 extends Tuple2KInstances8 { + implicit def catsDataDistributiveForTuple2K[F[_], G[_]](implicit FF: Distributive[F], + GG: Distributive[G]): Distributive[λ[α => Tuple2K[F, G, α]]] = new Tuple2KDistributive[F, G] with Tuple2KFunctor[F, G] { def F: Distributive[F] = FF def G: Distributive[G] = GG } } -private[data] sealed abstract class Tuple2KInstances8 { - implicit def catsDataFunctorForTuple2K[F[_], G[_]](implicit FF: Functor[F], GG: Functor[G]): Functor[λ[α => Tuple2K[F, G, α]]] = new Tuple2KFunctor[F, G] { - def F: Functor[F] = FF - def G: Functor[G] = GG - } +sealed abstract private[data] class Tuple2KInstances8 { + implicit def catsDataFunctorForTuple2K[F[_], G[_]](implicit FF: Functor[F], + GG: Functor[G]): Functor[λ[α => Tuple2K[F, G, α]]] = + new Tuple2KFunctor[F, G] { + def F: Functor[F] = FF + def G: Functor[G] = GG + } } -private[data] sealed trait Tuple2KFunctor[F[_], G[_]] extends Functor[λ[α => Tuple2K[F, G, α]]] { +sealed private[data] trait Tuple2KFunctor[F[_], G[_]] extends Functor[λ[α => Tuple2K[F, G, α]]] { def F: Functor[F] def G: Functor[G] - override def map[A, B](fa: Tuple2K[F, G, A])(f: A => B): Tuple2K[F, G, B] = Tuple2K(F.map(fa.first)(f), G.map(fa.second)(f)) + override def map[A, B](fa: Tuple2K[F, G, A])(f: A => B): Tuple2K[F, G, B] = + Tuple2K(F.map(fa.first)(f), G.map(fa.second)(f)) } - -private[data] sealed trait Tuple2KDistributive[F[_], G[_]] extends Distributive[λ[α => Tuple2K[F, G, α]]] { +sealed private[data] trait Tuple2KDistributive[F[_], G[_]] extends Distributive[λ[α => Tuple2K[F, G, α]]] { def F: Distributive[F] def G: Distributive[G] override def distribute[H[_]: Functor, A, B](ha: H[A])(f: A => Tuple2K[F, G, B]): Tuple2K[F, G, H[B]] = - Tuple2K(F.distribute(ha){a => f(a).first}, G.distribute(ha){a => f(a).second}) + Tuple2K(F.distribute(ha) { a => + f(a).first + }, G.distribute(ha) { a => + f(a).second + }) override def map[A, B](fa: Tuple2K[F, G, A])(f: A => B): Tuple2K[F, G, B] = Tuple2K(F.map(fa.first)(f), G.map(fa.second)(f)) } -private[data] sealed trait Tuple2KContravariant[F[_], G[_]] extends Contravariant[λ[α => Tuple2K[F, G, α]]] { +sealed private[data] trait Tuple2KContravariant[F[_], G[_]] extends Contravariant[λ[α => Tuple2K[F, G, α]]] { def F: Contravariant[F] def G: Contravariant[G] override def contramap[A, B](fa: Tuple2K[F, G, A])(f: B => A): Tuple2K[F, G, B] = Tuple2K(F.contramap(fa.first)(f), G.contramap(fa.second)(f)) } -private[data] sealed trait Tuple2KContravariantMonoidal[F[_], G[_]] extends ContravariantMonoidal[λ[α => Tuple2K[F, G, α]]] { +sealed private[data] trait Tuple2KContravariantMonoidal[F[_], G[_]] + extends ContravariantMonoidal[λ[α => Tuple2K[F, G, α]]] { def F: ContravariantMonoidal[F] def G: ContravariantMonoidal[G] def unit: Tuple2K[F, G, Unit] = Tuple2K(F.unit, G.unit) @@ -170,14 +208,15 @@ private[data] sealed trait Tuple2KContravariantMonoidal[F[_], G[_]] extends Cont Tuple2K(F.contramap(fa.first)(f), G.contramap(fa.second)(f)) } -private[data] sealed trait Tuple2KApply[F[_], G[_]] extends Apply[λ[α => Tuple2K[F, G, α]]] with Tuple2KFunctor[F, G] { +sealed private[data] trait Tuple2KApply[F[_], G[_]] extends Apply[λ[α => Tuple2K[F, G, α]]] with Tuple2KFunctor[F, G] { def F: Apply[F] def G: Apply[G] override def ap[A, B](f: Tuple2K[F, G, A => B])(fa: Tuple2K[F, G, A]): Tuple2K[F, G, B] = Tuple2K(F.ap(f.first)(fa.first), G.ap(f.second)(fa.second)) override def product[A, B](fa: Tuple2K[F, G, A], fb: Tuple2K[F, G, B]): Tuple2K[F, G, (A, B)] = Tuple2K(F.product(fa.first, fb.first), G.product(fa.second, fb.second)) - override def map2Eval[A, B, Z](fa: Tuple2K[F, G, A], fb: Eval[Tuple2K[F, G, B]])(f: (A, B) => Z): Eval[Tuple2K[F, G, Z]] = { + override def map2Eval[A, B, Z](fa: Tuple2K[F, G, A], + fb: Eval[Tuple2K[F, G, B]])(f: (A, B) => Z): Eval[Tuple2K[F, G, Z]] = { val fbmemo = fb.memoize // don't recompute this twice internally for { fz <- F.map2Eval(fa.first, fbmemo.map(_.first))(f) @@ -186,33 +225,41 @@ private[data] sealed trait Tuple2KApply[F[_], G[_]] extends Apply[λ[α => Tuple } } -private[data] sealed trait Tuple2KApplicative[F[_], G[_]] extends Applicative[λ[α => Tuple2K[F, G, α]]] with Tuple2KApply[F, G] { +sealed private[data] trait Tuple2KApplicative[F[_], G[_]] + extends Applicative[λ[α => Tuple2K[F, G, α]]] + with Tuple2KApply[F, G] { def F: Applicative[F] def G: Applicative[G] def pure[A](a: A): Tuple2K[F, G, A] = Tuple2K(F.pure(a), G.pure(a)) } -private[data] sealed trait Tuple2KSemigroupK[F[_], G[_]] extends SemigroupK[λ[α => Tuple2K[F, G, α]]] { +sealed private[data] trait Tuple2KSemigroupK[F[_], G[_]] extends SemigroupK[λ[α => Tuple2K[F, G, α]]] { def F: SemigroupK[F] def G: SemigroupK[G] override def combineK[A](x: Tuple2K[F, G, A], y: Tuple2K[F, G, A]): Tuple2K[F, G, A] = Tuple2K(F.combineK(x.first, y.first), G.combineK(x.second, y.second)) } -private[data] sealed trait Tuple2KMonoidK[F[_], G[_]] extends MonoidK[λ[α => Tuple2K[F, G, α]]] with Tuple2KSemigroupK[F, G] { +sealed private[data] trait Tuple2KMonoidK[F[_], G[_]] + extends MonoidK[λ[α => Tuple2K[F, G, α]]] + with Tuple2KSemigroupK[F, G] { def F: MonoidK[F] def G: MonoidK[G] override def empty[A]: Tuple2K[F, G, A] = Tuple2K(F.empty[A], G.empty[A]) } -private[data] sealed trait Tuple2KAlternative[F[_], G[_]] extends Alternative[λ[α => Tuple2K[F, G, α]]] - with Tuple2KApplicative[F, G] with Tuple2KMonoidK[F, G] { +sealed private[data] trait Tuple2KAlternative[F[_], G[_]] + extends Alternative[λ[α => Tuple2K[F, G, α]]] + with Tuple2KApplicative[F, G] + with Tuple2KMonoidK[F, G] { def F: Alternative[F] def G: Alternative[G] } -private[data] sealed trait Tuple2KMonad[F[_], G[_]] extends Monad[λ[α => Tuple2K[F, G, α]]] with Tuple2KApplicative[F, G] { +sealed private[data] trait Tuple2KMonad[F[_], G[_]] + extends Monad[λ[α => Tuple2K[F, G, α]]] + with Tuple2KApplicative[F, G] { def F: Monad[F] def G: Monad[G] override def pure[A](a: A): Tuple2K[F, G, A] = @@ -225,7 +272,7 @@ private[data] sealed trait Tuple2KMonad[F[_], G[_]] extends Monad[λ[α => Tuple Tuple2K(F.tailRecM(a)(f(_).first), G.tailRecM(a)(f(_).second)) } -private[data] sealed trait Tuple2KFoldable[F[_], G[_]] extends Foldable[λ[α => Tuple2K[F, G, α]]] { +sealed private[data] trait Tuple2KFoldable[F[_], G[_]] extends Foldable[λ[α => Tuple2K[F, G, α]]] { def F: Foldable[F] def G: Foldable[G] @@ -236,22 +283,26 @@ private[data] sealed trait Tuple2KFoldable[F[_], G[_]] extends Foldable[λ[α => F.foldRight(fa.first, G.foldRight(fa.second, lb)(f))(f) } -private[data] sealed trait Tuple2KTraverse[F[_], G[_]] extends Traverse[λ[α => Tuple2K[F, G, α]]] with Tuple2KFoldable[F, G] { +sealed private[data] trait Tuple2KTraverse[F[_], G[_]] + extends Traverse[λ[α => Tuple2K[F, G, α]]] + with Tuple2KFoldable[F, G] { def F: Traverse[F] def G: Traverse[G] - override def traverse[H[_], A, B](fa: Tuple2K[F, G, A])(f: A => H[B])(implicit H: Applicative[H]): H[Tuple2K[F, G, B]] = + override def traverse[H[_], A, B]( + fa: Tuple2K[F, G, A] + )(f: A => H[B])(implicit H: Applicative[H]): H[Tuple2K[F, G, B]] = H.map2(F.traverse(fa.first)(f), G.traverse(fa.second)(f))(Tuple2K(_, _)) } -private[data] sealed trait Tuple2KShow[F[_], G[_], A] extends Show[Tuple2K[F, G, A]] { +sealed private[data] trait Tuple2KShow[F[_], G[_], A] extends Show[Tuple2K[F, G, A]] { def F: Show[F[A]] def G: Show[G[A]] def show(tuple: Tuple2K[F, G, A]): String = s"Tuple2K(${F.show(tuple.first)}, ${G.show(tuple.second)})" } -private[data] sealed trait Tuple2KOrder[F[_], G[_], A] extends Order[Tuple2K[F, G, A]] { +sealed private[data] trait Tuple2KOrder[F[_], G[_], A] extends Order[Tuple2K[F, G, A]] { def F: Order[F[A]] def G: Order[G[A]] diff --git a/core/src/main/scala/cats/data/Validated.scala b/core/src/main/scala/cats/data/Validated.scala index 86b41f875bb..9e7b73a18d7 100644 --- a/core/src/main/scala/cats/data/Validated.scala +++ b/core/src/main/scala/cats/data/Validated.scala @@ -12,33 +12,33 @@ sealed abstract class Validated[+E, +A] extends Product with Serializable { def fold[B](fe: E => B, fa: A => B): B = this match { case Invalid(e) => fe(e) - case Valid(a) => fa(a) + case Valid(a) => fa(a) } def isValid: Boolean = this match { case Invalid(_) => false - case _ => true + case _ => true } def isInvalid: Boolean = this match { case Invalid(_) => true - case _ => false + case _ => false } /** - * Run the side-effecting function on the value if it is Valid - */ + * Run the side-effecting function on the value if it is Valid + */ def foreach(f: A => Unit): Unit = this match { case Valid(a) => f(a) - case _ => () + case _ => () } /** - * Return the Valid value, or the default if Invalid - */ + * Return the Valid value, or the default if Invalid + */ def getOrElse[B >: A](default: => B): B = this match { case Valid(a) => a - case _ => default + case _ => default } /** @@ -46,62 +46,64 @@ sealed abstract class Validated[+E, +A] extends Product with Serializable { */ def valueOr[B >: A](f: E => B): B = this match { case Invalid(e) => f(e) - case Valid(a) => a + case Valid(a) => a } /** - * Is this Valid and matching the given predicate - */ + * Is this Valid and matching the given predicate + */ def exists(predicate: A => Boolean): Boolean = this match { case Valid(a) => predicate(a) - case _ => false + case _ => false } /** - * Is this Invalid or matching the predicate - */ + * Is this Invalid or matching the predicate + */ def forall(f: A => Boolean): Boolean = this match { case Valid(a) => f(a) - case _ => true + case _ => true } /** - * Return this if it is Valid, or else fall back to the given default. - * The functionality is similar to that of [[findValid]] except for failure accumulation, - * where here only the error on the right is preserved and the error on the left is ignored. - */ + * Return this if it is Valid, or else fall back to the given default. + * The functionality is similar to that of [[findValid]] except for failure accumulation, + * where here only the error on the right is preserved and the error on the left is ignored. + */ def orElse[EE, AA >: A](default: => Validated[EE, AA]): Validated[EE, AA] = this match { case v @ Valid(_) => v - case _ => default + case _ => default } /** * If `this` is valid return `this`, otherwise if `that` is valid return `that`, otherwise combine the failures. * This is similar to [[orElse]] except that here failures are accumulated. */ - def findValid[EE >: E, AA >: A](that: => Validated[EE, AA])(implicit EE: Semigroup[EE]): Validated[EE, AA] = this match { - case v @ Valid(_) => v - case Invalid(e) => that match { + def findValid[EE >: E, AA >: A](that: => Validated[EE, AA])(implicit EE: Semigroup[EE]): Validated[EE, AA] = + this match { case v @ Valid(_) => v - case Invalid(ee) => Invalid(EE.combine(e, ee)) + case Invalid(e) => + that match { + case v @ Valid(_) => v + case Invalid(ee) => Invalid(EE.combine(e, ee)) + } } - } /** - * Converts the value to an Either[E, A] - */ + * Converts the value to an Either[E, A] + */ def toEither: Either[E, A] = this match { case Invalid(e) => Left(e) - case Valid(a) => Right(a) + case Valid(a) => Right(a) } /** - * Returns Valid values wrapped in Some, and None for Invalid values - */ + * Returns Valid values wrapped in Some, and None for Invalid values + */ def toOption: Option[A] = this match { case Valid(a) => Some(a) - case _ => None + case _ => None } /** @@ -109,199 +111,199 @@ sealed abstract class Validated[+E, +A] extends Product with Serializable { */ def toIor: Ior[E, A] = this match { case Invalid(e) => Ior.Left(e) - case Valid(a) => Ior.Right(a) + case Valid(a) => Ior.Right(a) } /** - * Convert this value to a single element List if it is Valid, - * otherwise return an empty List - */ + * Convert this value to a single element List if it is Valid, + * otherwise return an empty List + */ def toList: List[A] = this match { case Valid(a) => List(a) - case _ => Nil + case _ => Nil } /** Lift the Invalid value into a NonEmptyList. */ def toValidatedNel[EE >: E, AA >: A]: ValidatedNel[EE, AA] = this match { case v @ Valid(_) => v - case Invalid(e) => Validated.invalidNel(e) + case Invalid(e) => Validated.invalidNel(e) } /** Lift the Invalid value into a NonEmptyChain. */ def toValidatedNec[EE >: E, AA >: A]: ValidatedNec[EE, AA] = this match { case v @ Valid(_) => v - case Invalid(e) => Validated.invalidNec(e) + case Invalid(e) => Validated.invalidNec(e) } /** - * Convert to an Either, apply a function, convert back. This is handy - * when you want to use the Monadic properties of the Either type. - */ + * Convert to an Either, apply a function, convert back. This is handy + * when you want to use the Monadic properties of the Either type. + */ def withEither[EE, B](f: Either[E, A] => Either[EE, B]): Validated[EE, B] = Validated.fromEither(f(toEither)) /** - * Validated is a [[Bifunctor]], this method applies one of the - * given functions. - */ + * Validated is a [[Bifunctor]], this method applies one of the + * given functions. + */ def bimap[EE, AA](fe: E => EE, fa: A => AA): Validated[EE, AA] = - fold(fe andThen Invalid.apply, - fa andThen Valid.apply) - - def compare[EE >: E, AA >: A](that: Validated[EE, AA])(implicit EE: Order[EE], AA: Order[AA]): Int = (this, that) match { - case (Valid(a), Valid(aa)) => AA.compare(a, aa) - case (Invalid(e), Invalid(ee)) => EE.compare(e, ee) - case (Invalid(_), _) => -1 - case (Valid(_), _) => 1 - } + fold(fe.andThen(Invalid.apply), fa.andThen(Valid.apply)) + + def compare[EE >: E, AA >: A](that: Validated[EE, AA])(implicit EE: Order[EE], AA: Order[AA]): Int = + (this, that) match { + case (Valid(a), Valid(aa)) => AA.compare(a, aa) + case (Invalid(e), Invalid(ee)) => EE.compare(e, ee) + case (Invalid(_), _) => -1 + case (Valid(_), _) => 1 + } - def partialCompare[EE >: E, AA >: A](that: Validated[EE, AA])(implicit EE: PartialOrder[EE], AA: PartialOrder[AA]): Double = (this, that) match { - case (Valid(a), Valid(aa)) => AA.partialCompare(a, aa) + def partialCompare[EE >: E, AA >: A](that: Validated[EE, AA])(implicit EE: PartialOrder[EE], + AA: PartialOrder[AA]): Double = (this, that) match { + case (Valid(a), Valid(aa)) => AA.partialCompare(a, aa) case (Invalid(e), Invalid(ee)) => EE.partialCompare(e, ee) - case (Invalid(_), _) => -1 - case (Valid(_), _) => 1 + case (Invalid(_), _) => -1 + case (Valid(_), _) => 1 } def ===[EE >: E, AA >: A](that: Validated[EE, AA])(implicit EE: Eq[EE], AA: Eq[AA]): Boolean = (this, that) match { case (Invalid(e), Invalid(ee)) => EE.eqv(e, ee) - case (Valid(a), Valid(aa)) => AA.eqv(a, aa) - case _ => false + case (Valid(a), Valid(aa)) => AA.eqv(a, aa) + case _ => false } /** - * From Apply: - * if both the function and this value are Valid, apply the function - */ + * From Apply: + * if both the function and this value are Valid, apply the function + */ def ap[EE >: E, B](f: Validated[EE, A => B])(implicit EE: Semigroup[EE]): Validated[EE, B] = (this, f) match { - case (Valid(a), Valid(f)) => Valid(f(a)) + case (Valid(a), Valid(f)) => Valid(f(a)) case (Invalid(e1), Invalid(e2)) => Invalid(EE.combine(e2, e1)) - case (e@Invalid(_), _) => e - case (_, e@Invalid(_)) => e + case (e @ Invalid(_), _) => e + case (_, e @ Invalid(_)) => e } /** - * From Product - */ + * From Product + */ def product[EE >: E, B](fb: Validated[EE, B])(implicit EE: Semigroup[EE]): Validated[EE, (A, B)] = (this, fb) match { - case (Valid(a), Valid(b)) => Valid((a, b)) + case (Valid(a), Valid(b)) => Valid((a, b)) case (Invalid(e1), Invalid(e2)) => Invalid(EE.combine(e1, e2)) - case (e @ Invalid(_), _) => e - case (_, e @ Invalid(_)) => e + case (e @ Invalid(_), _) => e + case (_, e @ Invalid(_)) => e } /** - * Apply a function to a Valid value, returning a new Valid value - */ + * Apply a function to a Valid value, returning a new Valid value + */ def map[B](f: A => B): Validated[E, B] = this match { case i @ Invalid(_) => i - case Valid(a) => Valid(f(a)) + case Valid(a) => Valid(f(a)) } /** - * Apply a function to an Invalid value, returning a new Invalid value. - * Or, if the original valid was Valid, return it. - */ + * Apply a function to an Invalid value, returning a new Invalid value. + * Or, if the original valid was Valid, return it. + */ def leftMap[EE](f: E => EE): Validated[EE, A] = this match { case a @ Valid(_) => a - case Invalid(e) => Invalid(f(e)) + case Invalid(e) => Invalid(f(e)) } /** - * When Valid, apply the function, marking the result as valid - * inside the Applicative's context, - * when Invalid, lift the Error into the Applicative's context - */ + * When Valid, apply the function, marking the result as valid + * inside the Applicative's context, + * when Invalid, lift the Error into the Applicative's context + */ def traverse[F[_], EE >: E, B](f: A => F[B])(implicit F: Applicative[F]): F[Validated[EE, B]] = this match { - case Valid(a) => F.map(f(a))(Valid.apply) + case Valid(a) => F.map(f(a))(Valid.apply) case e @ Invalid(_) => F.pure(e) } /** - * apply the given function to the value with the given B when - * valid, otherwise return the given B - */ + * apply the given function to the value with the given B when + * valid, otherwise return the given B + */ def foldLeft[B](b: B)(f: (B, A) => B): B = this match { case Valid(a) => f(b, a) - case _ => b - } + case _ => b + } /** - * Lazily-apply the given function to the value with the given B - * when valid, otherwise return the given B. - */ + * Lazily-apply the given function to the value with the given B + * when valid, otherwise return the given B. + */ def foldRight[B](lb: Eval[B])(f: (A, Eval[B]) => Eval[B]): Eval[B] = this match { case Valid(a) => f(a, lb) - case _ => lb + case _ => lb } - def show[EE >: E, AA >: A](implicit EE: Show[EE], AA: Show[AA]): String = this match { case Invalid(e) => s"Invalid(${EE.show(e)})" - case Valid(a) => s"Valid(${AA.show(a)})" + case Valid(a) => s"Valid(${AA.show(a)})" } - /** - * Apply a function (that returns a `Validated`) in the valid case. - * Otherwise return the original `Validated`. - * - * This allows "chained" validation: the output of one validation can be fed - * into another validation function. - * - * This function is similar to `flatMap` on `Either`. It's not called `flatMap`, - * because by Cats convention, `flatMap` is a monadic bind that is consistent - * with `ap`. This method is not consistent with [[ap]] (or other - * `Apply`-based methods), because it has "fail-fast" behavior as opposed to - * accumulating validation failures. - */ + * Apply a function (that returns a `Validated`) in the valid case. + * Otherwise return the original `Validated`. + * + * This allows "chained" validation: the output of one validation can be fed + * into another validation function. + * + * This function is similar to `flatMap` on `Either`. It's not called `flatMap`, + * because by Cats convention, `flatMap` is a monadic bind that is consistent + * with `ap`. This method is not consistent with [[ap]] (or other + * `Apply`-based methods), because it has "fail-fast" behavior as opposed to + * accumulating validation failures. + */ def andThen[EE >: E, B](f: A => Validated[EE, B]): Validated[EE, B] = this match { - case Valid(a) => f(a) + case Valid(a) => f(a) case i @ Invalid(_) => i } /** - * Combine this `Validated` with another `Validated`, using the `Semigroup` - * instances of the underlying `E` and `A` instances. The resultant `Validated` - * will be `Valid`, if, and only if, both this `Validated` instance and the - * supplied `Validated` instance are also `Valid`. - */ - def combine[EE >: E, AA >: A](that: Validated[EE, AA])(implicit EE: Semigroup[EE], AA: Semigroup[AA]): Validated[EE, AA] = + * Combine this `Validated` with another `Validated`, using the `Semigroup` + * instances of the underlying `E` and `A` instances. The resultant `Validated` + * will be `Valid`, if, and only if, both this `Validated` instance and the + * supplied `Validated` instance are also `Valid`. + */ + def combine[EE >: E, AA >: A](that: Validated[EE, AA])(implicit EE: Semigroup[EE], + AA: Semigroup[AA]): Validated[EE, AA] = (this, that) match { - case (Valid(a), Valid(b)) => Valid(AA.combine(a, b)) + case (Valid(a), Valid(b)) => Valid(AA.combine(a, b)) case (Invalid(a), Invalid(b)) => Invalid(EE.combine(a, b)) - case (Invalid(_), _) => this - case _ => that + case (Invalid(_), _) => this + case _ => that } def swap: Validated[A, E] = this match { - case Valid(a) => Invalid(a) + case Valid(a) => Invalid(a) case Invalid(e) => Valid(e) } def merge[EE >: E](implicit ev: A <:< EE): EE = this match { case Invalid(e) => e - case Valid(a) => ev(a) + case Valid(a) => ev(a) } /** - * Ensure that a successful result passes the given predicate, - * falling back to an Invalid of `onFailure` if the predicate - * returns false. - * - * For example: - * {{{ - * scala> Validated.valid("").ensure(new IllegalArgumentException("Must not be empty"))(_.nonEmpty) - * res0: Validated[IllegalArgumentException, String] = Invalid(java.lang.IllegalArgumentException: Must not be empty) - * }}} - */ + * Ensure that a successful result passes the given predicate, + * falling back to an Invalid of `onFailure` if the predicate + * returns false. + * + * For example: + * {{{ + * scala> Validated.valid("").ensure(new IllegalArgumentException("Must not be empty"))(_.nonEmpty) + * res0: Validated[IllegalArgumentException, String] = Invalid(java.lang.IllegalArgumentException: Must not be empty) + * }}} + */ def ensure[EE >: E](onFailure: => EE)(f: A => Boolean): Validated[EE, A] = this match { case Valid(a) => if (f(a)) this else Validated.invalid(onFailure) - case _ => this + case _ => this } /** @@ -317,7 +319,7 @@ sealed abstract class Validated[+E, +A] extends Product with Serializable { */ def ensureOr[EE >: E](onFailure: A => EE)(f: A => Boolean): Validated[EE, A] = this match { case Valid(a) => if (f(a)) this else Validated.invalid(onFailure(a)) - case _ => this + case _ => this } } @@ -325,27 +327,26 @@ object Validated extends ValidatedInstances with ValidatedFunctions with Validat final case class Valid[+A](a: A) extends Validated[Nothing, A] final case class Invalid[+E](e: E) extends Validated[E, Nothing] - /** - * Evaluates the specified block, catching exceptions of the specified type and returning them on the invalid side of - * the resulting `Validated`. Uncaught exceptions are propagated. - * - * For example: - * {{{ - * scala> Validated.catchOnly[NumberFormatException] { "foo".toInt } - * res0: Validated[NumberFormatException, Int] = Invalid(java.lang.NumberFormatException: For input string: "foo") - * }}} - * - * This method and its usage of [[NotNull]] are inspired by and derived from - * the `fromTryCatchThrowable` method [[https://github.com/scalaz/scalaz/pull/746/files contributed]] - * to Scalaz by Brian McKenna. - */ + * Evaluates the specified block, catching exceptions of the specified type and returning them on the invalid side of + * the resulting `Validated`. Uncaught exceptions are propagated. + * + * For example: + * {{{ + * scala> Validated.catchOnly[NumberFormatException] { "foo".toInt } + * res0: Validated[NumberFormatException, Int] = Invalid(java.lang.NumberFormatException: For input string: "foo") + * }}} + * + * This method and its usage of [[NotNull]] are inspired by and derived from + * the `fromTryCatchThrowable` method [[https://github.com/scalaz/scalaz/pull/746/files contributed]] + * to Scalaz by Brian McKenna. + */ def catchOnly[T >: Null <: Throwable]: CatchOnlyPartiallyApplied[T] = new CatchOnlyPartiallyApplied[T] /** - * Uses the [[http://typelevel.org/cats/guidelines.html#partially-applied-type-params Partially Applied Type Params technique]] for ergonomics. - */ - private[data] final class CatchOnlyPartiallyApplied[T](val dummy: Boolean = true ) extends AnyVal{ + * Uses the [[http://typelevel.org/cats/guidelines.html#partially-applied-type-params Partially Applied Type Params technique]] for ergonomics. + */ + final private[data] class CatchOnlyPartiallyApplied[T](val dummy: Boolean = true) extends AnyVal { def apply[A](f: => A)(implicit T: ClassTag[T], NT: NotNull[T]): Validated[T, A] = try { valid(f) @@ -356,52 +357,58 @@ object Validated extends ValidatedInstances with ValidatedFunctions with Validat } } -private[data] sealed abstract class ValidatedInstances extends ValidatedInstances1 { +sealed abstract private[data] class ValidatedInstances extends ValidatedInstances1 { 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 - case Invalid(ix) => y match { - case Invalid(iy) => Invalid(A.combine(ix, iy)) - case v @ Valid(_) => v - } + case Invalid(ix) => + y match { + case Invalid(iy) => Invalid(A.combine(ix, iy)) + case v @ Valid(_) => v + } } } - 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 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 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 + 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 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 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 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]] = + 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 { case Invalid(a) => G.map(f(a))(Validated.invalid) - case Valid(b) => G.map(g(b))(Validated.valid) + case Valid(b) => G.map(g(b))(Validated.valid) } def bifoldLeft[A, B, C](fab: Validated[A, B], c: C)(f: (C, A) => C, g: (C, B) => C): C = fab match { case Invalid(a) => f(c, a) - case Valid(b) => g(c, b) + case Valid(b) => g(c, b) } - def bifoldRight[A, B, C](fab: Validated[A, B], c: Eval[C])(f: (A, Eval[C]) => Eval[C], g: (B, Eval[C]) => Eval[C]): Eval[C] = + def bifoldRight[A, B, C](fab: Validated[A, B], c: Eval[C])(f: (A, Eval[C]) => Eval[C], + g: (B, Eval[C]) => Eval[C]): Eval[C] = fab match { case Invalid(a) => f(a, c) - case Valid(b) => g(b, c) + case Valid(b) => g(b, c) } override def bimap[A, B, C, D](fab: Validated[A, B])(f: A => C, g: B => D): Validated[C, D] = @@ -416,31 +423,33 @@ private[data] sealed abstract class ValidatedInstances extends ValidatedInstance def handleErrorWith[A](fa: Validated[E, A])(f: E => Validated[E, A]): Validated[E, A] = fa match { - case Validated.Invalid(e) => f(e) + case Validated.Invalid(e) => f(e) case v @ Validated.Valid(_) => v } def raiseError[A](e: E): Validated[E, A] = Validated.Invalid(e) } } -private[data] sealed abstract class ValidatedInstances1 extends ValidatedInstances2 { +sealed abstract private[data] class ValidatedInstances1 extends ValidatedInstances2 { - implicit def catsDataSemigroupForValidated[A, B](implicit A: Semigroup[A], B: Semigroup[B]): Semigroup[Validated[A, B]] = + implicit def catsDataSemigroupForValidated[A, B](implicit A: Semigroup[A], + B: Semigroup[B]): Semigroup[Validated[A, B]] = new Semigroup[Validated[A, B]] { - def combine(x: Validated[A, B], y: Validated[A, B]): Validated[A, B] = x combine y + def combine(x: Validated[A, B], y: Validated[A, B]): Validated[A, B] = x.combine(y) } - implicit def catsDataCommutativeApplicativeForValidated[E: CommutativeSemigroup]: CommutativeApplicative[Validated[E, ?]] = + implicit def catsDataCommutativeApplicativeForValidated[E: CommutativeSemigroup] + : CommutativeApplicative[Validated[E, ?]] = new ValidatedApplicative[E] with CommutativeApplicative[Validated[E, ?]] implicit def catsDataPartialOrderForValidated[A: PartialOrder, B: PartialOrder]: PartialOrder[Validated[A, B]] = new PartialOrder[Validated[A, B]] { - def partialCompare(x: Validated[A, B], y: Validated[A, B]): Double = x partialCompare y + 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 } } -private[data] sealed abstract class ValidatedInstances2 { +sealed abstract private[data] class ValidatedInstances2 { implicit def catsDataEqForValidated[A: Eq, B: Eq]: Eq[Validated[A, B]] = new Eq[Validated[A, B]] { def eqv(x: Validated[A, B], y: Validated[A, B]): Boolean = x === y @@ -450,7 +459,7 @@ private[data] sealed abstract class ValidatedInstances2 { implicit def catsDataTraverseFunctorForValidated[E]: Traverse[Validated[E, ?]] = new Traverse[Validated[E, ?]] { - override def traverse[G[_] : Applicative, A, B](fa: Validated[E, A])(f: (A) => G[B]): G[Validated[E, B]] = + override def traverse[G[_]: Applicative, A, B](fa: Validated[E, A])(f: (A) => G[B]): G[Validated[E, B]] = fa.traverse(f) override def foldLeft[A, B](fa: Validated[E, A], b: B)(f: (B, A) => B): B = @@ -465,7 +474,9 @@ private[data] sealed abstract class ValidatedInstances2 { override def reduceLeftToOption[A, B](fa: Validated[E, A])(f: A => B)(g: (B, A) => B): Option[B] = fa.map(f).toOption - override def reduceRightToOption[A, B](fa: Validated[E, A])(f: A => B)(g: (A, Eval[B]) => Eval[B]): Eval[Option[B]] = + override def reduceRightToOption[A, B]( + fa: Validated[E, A] + )(f: A => B)(g: (A, Eval[B]) => Eval[B]): Eval[Option[B]] = Now(fa.map(f).toOption) override def reduceLeftOption[A](fa: Validated[E, A])(f: (A, A) => A): Option[A] = @@ -476,7 +487,7 @@ private[data] sealed abstract class ValidatedInstances2 { override def size[A](fa: Validated[E, A]): Long = fa match { case Invalid(_) => 0L - case _ => 1L + case _ => 1L } override def get[A](fa: Validated[E, A])(idx: Long): Option[A] = @@ -484,7 +495,7 @@ private[data] sealed abstract class ValidatedInstances2 { override def foldMap[A, B](fa: Validated[E, A])(f: A => B)(implicit B: Monoid[B]): B = fa match { case Valid(a) => f(a) - case _ => B.empty + case _ => B.empty } override def find[A](fa: Validated[E, A])(f: A => Boolean): Option[A] = @@ -498,7 +509,7 @@ private[data] sealed abstract class ValidatedInstances2 { override def toList[A](fa: Validated[E, A]): List[A] = fa match { case Valid(a) => a :: Nil - case _ => Nil + case _ => Nil } override def isEmpty[A](fa: Validated[E, A]): Boolean = fa.isInvalid @@ -520,6 +531,7 @@ private[data] class ValidatedApplicative[E: Semigroup] extends CommutativeApplic } private[data] trait ValidatedFunctions { + /** * Converts an `E` to a `Validated[E, A]`. * @@ -572,22 +584,22 @@ private[data] trait ValidatedFunctions { } /** - * Converts a `Try[A]` to a `Validated[Throwable, A]`. - */ + * Converts a `Try[A]` to a `Validated[Throwable, A]`. + */ def fromTry[A](t: Try[A]): Validated[Throwable, A] = t match { case Failure(e) => invalid(e) case Success(v) => valid(v) } /** - * Converts an `Either[A, B]` to a `Validated[A, B]`. - */ + * Converts an `Either[A, B]` to a `Validated[A, B]`. + */ def fromEither[A, B](e: Either[A, B]): Validated[A, B] = e.fold(invalid, valid) /** - * Converts an `Option[B]` to a `Validated[A, B]`, where the provided `ifNone` values is returned on - * the invalid of the `Validated` when the specified `Option` is `None`. - */ + * Converts an `Option[B]` to a `Validated[A, B]`, where the provided `ifNone` values is returned on + * the invalid of the `Validated` when the specified `Option` is `None`. + */ def fromOption[A, B](o: Option[B], ifNone: => A): Validated[A, B] = o.fold(invalid[A, B](ifNone))(valid) /** @@ -596,51 +608,48 @@ private[data] trait ValidatedFunctions { def fromIor[A, B](ior: Ior[A, B]): Validated[A, B] = ior.fold(invalid, valid, (_, b) => valid(b)) /** - * If the condition is satisfied, return the given `A` as valid, - * otherwise return the given `E` as invalid. - */ + * If the condition is satisfied, return the given `A` as valid, + * otherwise return the given `E` as invalid. + */ final def cond[E, A](test: Boolean, a: => A, e: => E): Validated[E, A] = if (test) valid(a) else invalid(e) /** - * If the condition is satisfied, return the given `A` as valid NEL, - * otherwise return the given `E` as invalid NEL. - */ + * If the condition is satisfied, return the given `A` as valid NEL, + * otherwise return the given `E` as invalid NEL. + */ final def condNel[E, A](test: Boolean, a: => A, e: => E): ValidatedNel[E, A] = if (test) validNel(a) else invalidNel(e) } private[data] trait ValidatedFunctionsBinCompat0 { - /** - * Converts a `B` to a `ValidatedNec[A, B]`. - * - * For example: - * {{{ - * scala> Validated.validNec[IllegalArgumentException, String]("Hello world") - * res0: ValidatedNec[IllegalArgumentException, String] = Valid(Hello world) - * }}} - */ + * Converts a `B` to a `ValidatedNec[A, B]`. + * + * For example: + * {{{ + * scala> Validated.validNec[IllegalArgumentException, String]("Hello world") + * res0: ValidatedNec[IllegalArgumentException, String] = Valid(Hello world) + * }}} + */ def validNec[A, B](b: B): ValidatedNec[A, B] = Validated.Valid(b) - - /** - * Converts an `A` to a `ValidatedNec[A, B]`. - * - * For example: - * {{{ - * scala> Validated.invalidNec[IllegalArgumentException, String](new IllegalArgumentException("Argument is nonzero")) - * res0: ValidatedNec[IllegalArgumentException, String] = Invalid(Chain(java.lang.IllegalArgumentException: Argument is nonzero)) - * }}} - */ + * Converts an `A` to a `ValidatedNec[A, B]`. + * + * For example: + * {{{ + * scala> Validated.invalidNec[IllegalArgumentException, String](new IllegalArgumentException("Argument is nonzero")) + * res0: ValidatedNec[IllegalArgumentException, String] = Invalid(Chain(java.lang.IllegalArgumentException: Argument is nonzero)) + * }}} + */ def invalidNec[A, B](a: A): ValidatedNec[A, B] = Validated.Invalid(NonEmptyChain.one(a)) /** - * If the condition is satisfied, return the given `B` as valid NEC, - * otherwise return the given `A` as invalid NEC. - */ + * If the condition is satisfied, return the given `B` as valid NEC, + * otherwise return the given `A` as invalid NEC. + */ final def condNec[A, B](test: Boolean, b: => B, a: => A): ValidatedNec[A, B] = if (test) validNec(b) else invalidNec(a) } diff --git a/core/src/main/scala/cats/data/WriterT.scala b/core/src/main/scala/cats/data/WriterT.scala index 9dcb53ec2b9..1429fc38719 100644 --- a/core/src/main/scala/cats/data/WriterT.scala +++ b/core/src/main/scala/cats/data/WriterT.scala @@ -17,14 +17,15 @@ final case class WriterT[F[_], L, V](run: F[(L, V)]) { functorF.map(run)(_._2) def ap[Z](f: WriterT[F, L, V => Z])(implicit F: Apply[F], L: Semigroup[L]): WriterT[F, L, Z] = - WriterT( - F.map2(f.run, run){ - case ((l1, fvz), (l2, v)) => (L.combine(l1, l2), fvz(v)) - }) + WriterT(F.map2(f.run, run) { + case ((l1, fvz), (l2, v)) => (L.combine(l1, l2), fvz(v)) + }) def map[Z](fn: V => Z)(implicit functorF: Functor[F]): WriterT[F, L, Z] = WriterT { - functorF.map(run) { z => (z._1, fn(z._2)) } + functorF.map(run) { z => + (z._1, fn(z._2)) + } } def imap[Z](f: V => Z)(g: Z => V)(implicit F: Invariant[F]): WriterT[F, L, Z] = @@ -33,14 +34,16 @@ final case class WriterT[F[_], L, V](run: F[(L, V)]) { } /** - * Modify the context `F` using transformation `f`. - */ + * Modify the context `F` using transformation `f`. + */ def mapK[G[_]](f: F ~> G): WriterT[G, L, V] = WriterT[G, L, V](f(run)) def contramap[Z](fn: Z => V)(implicit F: Contravariant[F]): WriterT[F, L, Z] = WriterT { - F.contramap(run) { z => (z._1, fn(z._2)) } + F.contramap(run) { z => + (z._1, fn(z._2)) + } } def flatMap[U](f: V => WriterT[F, L, U])(implicit flatMapF: FlatMap[F], semigroupL: Semigroup[L]): WriterT[F, L, U] = @@ -87,15 +90,15 @@ object WriterT extends WriterTInstances with WriterTFunctions { WriterT(F.map(fv)(v => (monoidL.empty, v))) /** - * Same as [[liftF]], but expressed as a FunctionK for use with mapK - * {{{ - * scala> import cats._, data._, implicits._ - * scala> val a: OptionT[Eval, Int] = 1.pure[OptionT[Eval, ?]] - * scala> val b: OptionT[WriterT[Eval, String, ?], Int] = a.mapK(WriterT.liftK) - * scala> b.value.run.value - * res0: (String, Option[Int]) = ("",Some(1)) - * }}} - */ + * Same as [[liftF]], but expressed as a FunctionK for use with mapK + * {{{ + * scala> import cats._, data._, implicits._ + * scala> val a: OptionT[Eval, Int] = 1.pure[OptionT[Eval, ?]] + * scala> val b: OptionT[WriterT[Eval, String, ?], Int] = a.mapK(WriterT.liftK) + * scala> b.value.run.value + * res0: (String, Option[Int]) = ("",Some(1)) + * }}} + */ def liftK[F[_], L](implicit monoidL: Monoid[L], F: Applicative[F]): F ~> WriterT[F, L, ?] = λ[F ~> WriterT[F, L, ?]](WriterT.liftF(_)) @@ -105,8 +108,11 @@ object WriterT extends WriterTInstances with WriterTFunctions { } -private[data] sealed abstract class WriterTInstances extends WriterTInstances0 { - implicit def catsDataCommutativeMonadForWriterT[F[_], L](implicit F: CommutativeMonad[F], L: CommutativeMonoid[L]): CommutativeMonad[WriterT[F, L, ?]] = +sealed abstract private[data] class WriterTInstances extends WriterTInstances0 { + implicit def catsDataCommutativeMonadForWriterT[F[_], L]( + implicit F: CommutativeMonad[F], + L: CommutativeMonoid[L] + ): CommutativeMonad[WriterT[F, L, ?]] = new WriterTMonad[F, L] with CommutativeMonad[WriterT[F, L, ?]] { implicit val F0: Monad[F] = F implicit val L0: Monoid[L] = L @@ -122,7 +128,7 @@ private[data] sealed abstract class WriterTInstances extends WriterTInstances0 { } } -private[data] sealed abstract class WriterTInstances0 extends WriterTInstances1 { +sealed abstract private[data] class WriterTInstances0 extends WriterTInstances1 { implicit def catsDataTraverseForWriterT[F[_], L](implicit F: Traverse[F]): Traverse[WriterT[F, L, ?]] = new WriterTTraverse[F, L] { @@ -133,15 +139,17 @@ private[data] sealed abstract class WriterTInstances0 extends WriterTInstances1 catsDataFoldableForWriterT[Id, L](F) } -private[data] sealed abstract class WriterTInstances1 extends WriterTInstances2 { - implicit def catsDataMonadErrorForWriterT[F[_], L, E](implicit F: MonadError[F, E], L: Monoid[L]): MonadError[WriterT[F, L, ?], E] = +sealed abstract private[data] class WriterTInstances1 extends WriterTInstances2 { + implicit def catsDataMonadErrorForWriterT[F[_], L, E](implicit F: MonadError[F, E], + L: Monoid[L]): MonadError[WriterT[F, L, ?], E] = new WriterTMonadError[F, L, E] { implicit val F0: MonadError[F, E] = F implicit val L0: Monoid[L] = L } - implicit def catsDataParallelForWriterT[F[_], M[_], L: Monoid] - (implicit P: Parallel[M, F]): Parallel[WriterT[M, L, ?], WriterT[F, L, ?]] = new Parallel[WriterT[M, L, ?], WriterT[F, L, ?]]{ + implicit def catsDataParallelForWriterT[F[_], M[_], L: Monoid]( + implicit P: Parallel[M, F] + ): Parallel[WriterT[M, L, ?], WriterT[F, L, ?]] = new Parallel[WriterT[M, L, ?], WriterT[F, L, ?]] { implicit val appF = P.applicative implicit val monadM = P.monad @@ -158,40 +166,41 @@ private[data] sealed abstract class WriterTInstances1 extends WriterTInstances2 implicit def catsDataEqForWriterTId[L: Eq, V: Eq]: Eq[WriterT[Id, L, V]] = catsDataEqForWriterT[Id, L, V] - implicit def catsDataBifunctorForWriterT[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 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 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 catsDataMonoidForWriterTId[L:Monoid, V:Monoid]: Monoid[WriterT[Id, L, V]] = + implicit def catsDataMonoidForWriterTId[L: Monoid, V: Monoid]: Monoid[WriterT[Id, L, V]] = catsDataMonoidForWriterT[Id, L, V] implicit def catsDataFoldableForWriterT[F[_], L](implicit F: Foldable[F]): Foldable[WriterT[F, L, ?]] = - new WriterTFoldable[F, L]{ + new WriterTFoldable[F, L] { val F0: Foldable[F] = F } } -private[data] sealed abstract class WriterTInstances2 extends WriterTInstances3 { - implicit def catsDataMonadForWriterTId[L:Monoid]: Monad[WriterT[Id, L, ?]] = +sealed abstract private[data] class WriterTInstances2 extends WriterTInstances3 { + implicit def catsDataMonadForWriterTId[L: Monoid]: Monad[WriterT[Id, L, ?]] = catsDataMonadForWriterT[Id, L] implicit def catsDataEqForWriterT[F[_], L, V](implicit F: Eq[F[(L, V)]]): Eq[WriterT[F, L, V]] = Eq.by[WriterT[F, L, V], F[(L, V)]](_.run) - implicit def catsDataSemigroupForWriterTId[L:Semigroup, V:Semigroup]: Semigroup[WriterT[Id, L, V]] = + implicit def catsDataSemigroupForWriterTId[L: Semigroup, V: Semigroup]: Semigroup[WriterT[Id, L, V]] = catsDataSemigroupForWriterT[Id, L, V] implicit def catsDataComonadForWriterTId[L](implicit F: Comonad[Id]): Comonad[WriterT[Id, L, ?]] = catsDataComonadForWriterT[Id, L](F) } -private[data] sealed abstract class WriterTInstances3 extends WriterTInstances4 { +sealed abstract private[data] class WriterTInstances3 extends WriterTInstances4 { implicit def catsDataMonadForWriterT[F[_], L](implicit F: Monad[F], L: Monoid[L]): Monad[WriterT[F, L, ?]] = new WriterTMonad[F, L] { implicit val F0: Monad[F] = F @@ -207,12 +216,12 @@ private[data] sealed abstract class WriterTInstances3 extends WriterTInstances4 catsDataCoflatMapForWriterT[Id, L] } -private[data] sealed abstract class WriterTInstances4 extends WriterTInstances5 { - implicit def catsDataFlatMapForWriterTId[L:Semigroup]: FlatMap[WriterT[Id, L, ?]] = +sealed abstract private[data] class WriterTInstances4 extends WriterTInstances5 { + implicit def catsDataFlatMapForWriterTId[L: Semigroup]: FlatMap[WriterT[Id, L, ?]] = catsDataFlatMapForWriterT2[Id, L] } -private[data] sealed abstract class WriterTInstances5 extends WriterTInstances6 { +sealed abstract private[data] class WriterTInstances5 extends WriterTInstances6 { implicit def catsDataFlatMapForWriterT1[F[_], L](implicit F: FlatMap[F], L: Monoid[L]): FlatMap[WriterT[F, L, ?]] = new WriterTFlatMap1[F, L] { implicit val F0: FlatMap[F] = F @@ -225,28 +234,32 @@ private[data] sealed abstract class WriterTInstances5 extends WriterTInstances6 } } -private[data] sealed abstract class WriterTInstances6 extends WriterTInstances7 { - implicit def catsDataApplicativeErrorForWriterT[F[_], L, E](implicit F: ApplicativeError[F, E], L: Monoid[L]): ApplicativeError[WriterT[F, L, ?], E] = +sealed abstract private[data] class WriterTInstances6 extends WriterTInstances7 { + implicit def catsDataApplicativeErrorForWriterT[F[_], L, E](implicit F: ApplicativeError[F, E], + L: Monoid[L]): ApplicativeError[WriterT[F, L, ?], E] = new WriterTApplicativeError[F, L, E] { implicit val F0: ApplicativeError[F, E] = F implicit val L0: Monoid[L] = L } } -private[data] sealed abstract class WriterTInstances7 extends WriterTInstances8 { - implicit def catsDataAlternativeForWriterT[F[_], L](implicit F: Alternative[F], L: Monoid[L]): Alternative[WriterT[F, L, ?]] = +sealed abstract private[data] class WriterTInstances7 extends WriterTInstances8 { + 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 } - implicit def catsDataContravariantMonoidalForWriterT[F[_], L](implicit F: ContravariantMonoidal[F]): ContravariantMonoidal[WriterT[F, L, ?]] = + implicit def catsDataContravariantMonoidalForWriterT[F[_], L]( + implicit F: ContravariantMonoidal[F] + ): ContravariantMonoidal[WriterT[F, L, ?]] = new WriterTContravariantMonoidal[F, L] { implicit val F0: ContravariantMonoidal[F] = F } } -private[data] sealed abstract class WriterTInstances8 extends WriterTInstances9 { +sealed abstract private[data] class WriterTInstances8 extends WriterTInstances9 { implicit def catsDataMonoidKForWriterT[F[_], L](implicit F: MonoidK[F]): MonoidK[WriterT[F, L, ?]] = new WriterTMonoidK[F, L] { implicit val F0: MonoidK[F] = F @@ -264,13 +277,14 @@ private[data] sealed abstract class WriterTInstances8 extends WriterTInstances9 } } -private[data] sealed abstract class WriterTInstances9 extends WriterTInstances10 { +sealed abstract private[data] class WriterTInstances9 extends WriterTInstances10 { implicit def catsDataSemigroupKForWriterT[F[_], L](implicit F: SemigroupK[F]): SemigroupK[WriterT[F, L, ?]] = new WriterTSemigroupK[F, L] { implicit val F0: SemigroupK[F] = F } - implicit def catsDataApplicativeForWriterT[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 @@ -280,7 +294,7 @@ private[data] sealed abstract class WriterTInstances9 extends WriterTInstances10 new WriterTInvariant[F, L] { implicit val F = F0 } } -private[data] sealed abstract class WriterTInstances10 extends WriterTInstances11 { +sealed abstract private[data] class WriterTInstances10 extends WriterTInstances11 { 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 @@ -288,49 +302,50 @@ private[data] sealed abstract class WriterTInstances10 extends WriterTInstances1 } } -private[data] sealed abstract class WriterTInstances11 extends WriterTInstances12 { +sealed abstract private[data] class WriterTInstances11 extends WriterTInstances12 { implicit def catsDataComonadForWriterT[F[_], L](implicit F: Comonad[F]): Comonad[WriterT[F, L, ?]] = new WriterTComonad[F, L] { implicit val F0: Comonad[F] = F } } -private[data] sealed abstract class WriterTInstances12 { +sealed abstract private[data] class WriterTInstances12 { 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, ?]] { +sealed private[data] trait WriterTFunctor[F[_], L] extends Functor[WriterT[F, L, ?]] { implicit def F0: Functor[F] override def map[A, B](fa: WriterT[F, L, A])(f: A => B): WriterT[F, L, B] = fa.map(f) } -private[data] sealed trait WriterTContravariant[F[_], L] extends Contravariant[WriterT[F, L, ?]] { +sealed private[data] trait WriterTContravariant[F[_], L] extends Contravariant[WriterT[F, L, ?]] { implicit def F0: Contravariant[F] override def contramap[A, B](fa: WriterT[F, L, A])(f: B => A): WriterT[F, L, B] = fa.contramap(f) } -private[data] sealed trait WriterTInvariant[F[_], L] extends Invariant[WriterT[F, L, ?]] { +sealed private[data] trait WriterTInvariant[F[_], L] extends Invariant[WriterT[F, L, ?]] { implicit def F: Invariant[F] override def imap[A, B](fa: WriterT[F, L, A])(f: A => B)(g: B => A): WriterT[F, L, B] = fa.imap(f)(g) } -private[data] sealed trait WriterTApply[F[_], L] extends WriterTFunctor[F, L] with Apply[WriterT[F, L, ?]] { - override implicit def F0: Apply[F] +sealed private[data] trait WriterTApply[F[_], L] extends WriterTFunctor[F, L] with Apply[WriterT[F, L, ?]] { + implicit override def F0: Apply[F] implicit def L0: Semigroup[L] def ap[A, B](f: WriterT[F, L, A => B])(fa: WriterT[F, L, A]): WriterT[F, L, B] = - fa ap f + fa.ap(f) - override def map2Eval[A, B, Z](fa: WriterT[F, L, A], fb: Eval[WriterT[F, L, B]])(f: (A, B) => Z): Eval[WriterT[F, L, Z]] = + override def map2Eval[A, B, Z](fa: WriterT[F, L, A], + fb: Eval[WriterT[F, L, B]])(f: (A, B) => Z): Eval[WriterT[F, L, Z]] = F0.map2Eval(fa.run, fb.map(_.run)) { case ((la, a), (lb, b)) => (L0.combine(la, lb), f(a, b)) } .map(WriterT(_)) // F0 may have a lazy map2Eval @@ -338,8 +353,8 @@ private[data] sealed trait WriterTApply[F[_], L] extends WriterTFunctor[F, L] wi WriterT(F0.map(F0.product(fa.run, fb.run)) { case ((l1, a), (l2, b)) => (L0.combine(l1, l2), (a, b)) }) } -private[data] sealed trait WriterTFlatMap1[F[_], L] extends WriterTApply[F, L] with FlatMap[WriterT[F, L, ?]] { - override implicit def F0: FlatMap[F] +sealed private[data] trait WriterTFlatMap1[F[_], L] extends WriterTApply[F, L] with FlatMap[WriterT[F, L, ?]] { + implicit override def F0: FlatMap[F] implicit def L0: Monoid[L] def flatMap[A, B](fa: WriterT[F, L, A])(f: A => WriterT[F, L, B]): WriterT[F, L, B] = @@ -363,8 +378,8 @@ private[data] sealed trait WriterTFlatMap1[F[_], L] extends WriterTApply[F, L] w } } -private[data] sealed trait WriterTFlatMap2[F[_], L] extends WriterTApply[F, L] with FlatMap[WriterT[F, L, ?]] { - override implicit def F0: Monad[F] +sealed private[data] trait WriterTFlatMap2[F[_], L] extends WriterTApply[F, L] with FlatMap[WriterT[F, L, ?]] { + implicit override def F0: Monad[F] implicit def L0: Semigroup[L] def flatMap[A, B](fa: WriterT[F, L, A])(f: A => WriterT[F, L, B]): WriterT[F, L, B] = @@ -393,21 +408,26 @@ private[data] sealed trait WriterTFlatMap2[F[_], L] extends WriterTApply[F, L] w } } -private[data] sealed trait WriterTApplicative[F[_], L] extends WriterTApply[F, L] with Applicative[WriterT[F, L, ?]] { - override implicit def F0: Applicative[F] - override implicit def L0: Monoid[L] +sealed private[data] trait WriterTApplicative[F[_], L] extends WriterTApply[F, L] with Applicative[WriterT[F, L, ?]] { + implicit override def F0: Applicative[F] + implicit override def L0: Monoid[L] def pure[A](a: A): WriterT[F, L, A] = WriterT.value[F, L, A](a) } -private[data] sealed trait WriterTMonad[F[_], L] extends WriterTApplicative[F, L] with WriterTFlatMap1[F, L] with Monad[WriterT[F, L, ?]] { - override implicit def F0: Monad[F] - override implicit def L0: Monoid[L] +sealed private[data] trait WriterTMonad[F[_], L] + extends WriterTApplicative[F, L] + with WriterTFlatMap1[F, L] + with Monad[WriterT[F, L, ?]] { + implicit override def F0: Monad[F] + implicit override def L0: Monoid[L] } -private[data] sealed trait WriterTApplicativeError[F[_], L, E] extends ApplicativeError[WriterT[F, L, ?], E] with WriterTApplicative[F, L] { - override implicit def F0: ApplicativeError[F, E] +sealed private[data] trait WriterTApplicativeError[F[_], L, E] + extends ApplicativeError[WriterT[F, L, ?], E] + with WriterTApplicative[F, L] { + implicit override def F0: ApplicativeError[F, E] def raiseError[A](e: E): WriterT[F, L, A] = WriterT(F0.raiseError[(L, A)](e)) @@ -415,28 +435,34 @@ private[data] sealed trait WriterTApplicativeError[F[_], L, E] extends Applicati WriterT(F0.handleErrorWith(fa.run)(e => f(e).run)) } -private[data] sealed trait WriterTMonadError[F[_], L, E] extends MonadError[WriterT[F, L, ?], E] with WriterTMonad[F, L] with WriterTApplicativeError[F, L, E]{ - override implicit def F0: MonadError[F, E] +sealed private[data] trait WriterTMonadError[F[_], L, E] + extends MonadError[WriterT[F, L, ?], E] + with WriterTMonad[F, L] + with WriterTApplicativeError[F, L, E] { + implicit override def F0: MonadError[F, E] } -private[data] sealed trait WriterTSemigroupK[F[_], L] extends SemigroupK[WriterT[F, L, ?]] { +sealed private[data] trait WriterTSemigroupK[F[_], L] extends SemigroupK[WriterT[F, L, ?]] { implicit def F0: SemigroupK[F] def combineK[A](x: WriterT[F, L, A], y: WriterT[F, L, A]): WriterT[F, L, A] = WriterT(F0.combineK(x.run, y.run)) } -private[data] sealed trait WriterTMonoidK[F[_], L] extends MonoidK[WriterT[F, L, ?]] with WriterTSemigroupK[F, L] { - override implicit def F0: MonoidK[F] +sealed private[data] trait WriterTMonoidK[F[_], L] extends MonoidK[WriterT[F, L, ?]] with WriterTSemigroupK[F, L] { + implicit override def F0: MonoidK[F] def empty[A]: WriterT[F, L, A] = WriterT(F0.empty) } -private[data] sealed trait WriterTAlternative[F[_], L] extends Alternative[WriterT[F, L, ?]] with WriterTMonoidK[F, L] with WriterTApplicative[F, L] { - override implicit def F0: Alternative[F] +sealed private[data] trait WriterTAlternative[F[_], L] + extends Alternative[WriterT[F, L, ?]] + with WriterTMonoidK[F, L] + with WriterTApplicative[F, L] { + implicit override def F0: Alternative[F] } -private[data] sealed trait WriterTContravariantMonoidal[F[_], L] extends ContravariantMonoidal[WriterT[F, L, ?]] { +sealed private[data] trait WriterTContravariantMonoidal[F[_], L] extends ContravariantMonoidal[WriterT[F, L, ?]] { implicit def F0: ContravariantMonoidal[F] override def unit: WriterT[F, L, Unit] = WriterT(F0.trivial[(L, Unit)]) @@ -446,32 +472,34 @@ private[data] sealed trait WriterTContravariantMonoidal[F[_], L] extends Contrav override def product[A, B](fa: WriterT[F, L, A], fb: WriterT[F, L, B]): WriterT[F, L, (A, B)] = WriterT( - F0.contramap( - F0.product(fa.run, fb.run))( - (t: (L, (A, B))) => t match { + F0.contramap(F0.product(fa.run, fb.run))( + (t: (L, (A, B))) => + t match { case (l, (a, b)) => ((l, a), (l, b)) - })) + } + ) + ) } -private[data] sealed trait WriterTSemigroup[F[_], L, A] extends Semigroup[WriterT[F, L, A]] { +sealed private[data] trait WriterTSemigroup[F[_], L, A] extends Semigroup[WriterT[F, L, A]] { implicit def F0: Semigroup[F[(L, A)]] def combine(x: WriterT[F, L, A], y: WriterT[F, L, A]): WriterT[F, L, A] = 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] { - override implicit def F0: Monoid[F[(L, A)]] +sealed private[data] trait WriterTMonoid[F[_], L, A] extends Monoid[WriterT[F, L, A]] with WriterTSemigroup[F, L, A] { + implicit override 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] { +sealed private[data] 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)) } -private[data] sealed trait WriterTFoldable[F[_], L] extends Foldable[WriterT[F, L, ?]] { +sealed private[data] trait WriterTFoldable[F[_], L] extends Foldable[WriterT[F, L, ?]] { implicit def F0: Foldable[F] @@ -479,16 +507,19 @@ private[data] sealed trait WriterTFoldable[F[_], L] extends Foldable[WriterT[F, def foldRight[A, B](fa: WriterT[F, L, A], lb: Eval[B])(f: (A, Eval[B]) => Eval[B]): Eval[B] = fa.foldRight(lb)(f) } -private[data] sealed trait WriterTTraverse[F[_], L] extends Traverse[WriterT[F, L, ?]] with WriterTFoldable[F, L] with WriterTFunctor[F, L] { +sealed private[data] trait WriterTTraverse[F[_], L] + extends Traverse[WriterT[F, L, ?]] + with WriterTFoldable[F, L] + with WriterTFunctor[F, L] { - override implicit def F0: Traverse[F] + implicit override def F0: Traverse[F] def traverse[G[_]: Applicative, A, B](fa: WriterT[F, L, A])(f: A => G[B]): G[WriterT[F, L, B]] = fa.traverse(f) } -private[data] sealed trait WriterTComonad[F[_], L] extends Comonad[WriterT[F, L, ?]] with WriterTCoflatMap[F, L] { +sealed private[data] trait WriterTComonad[F[_], L] extends Comonad[WriterT[F, L, ?]] with WriterTCoflatMap[F, L] { - override implicit def F0: Comonad[F] + implicit override def F0: Comonad[F] def extract[A](fa: WriterT[F, L, A]): A = F0.extract(F0.map(fa.run)(_._2)) } diff --git a/core/src/main/scala/cats/data/ZipList.scala b/core/src/main/scala/cats/data/ZipList.scala index 603ab1acdb4..8bca9d7d310 100644 --- a/core/src/main/scala/cats/data/ZipList.scala +++ b/core/src/main/scala/cats/data/ZipList.scala @@ -15,7 +15,7 @@ object ZipList { ZipList(fa.value.map(f)) def ap[A, B](ff: ZipList[A => B])(fa: ZipList[A]): ZipList[B] = - ZipList((ff.value, fa.value).zipped.map(_ apply _)) + ZipList((ff.value, fa.value).zipped.map(_.apply(_))) override def product[A, B](fa: ZipList[A], fb: ZipList[B]): ZipList[(A, B)] = ZipList(fa.value.zip(fb.value)) diff --git a/core/src/main/scala/cats/data/ZipStream.scala b/core/src/main/scala/cats/data/ZipStream.scala index 9c3861a8288..775d870a58f 100644 --- a/core/src/main/scala/cats/data/ZipStream.scala +++ b/core/src/main/scala/cats/data/ZipStream.scala @@ -17,7 +17,7 @@ object ZipStream { ZipStream(fa.value.map(f)) def ap[A, B](ff: ZipStream[A => B])(fa: ZipStream[A]): ZipStream[B] = - ZipStream((ff.value, fa.value).zipped.map(_ apply _)) + ZipStream((ff.value, fa.value).zipped.map(_.apply(_))) override def product[A, B](fa: ZipStream[A], fb: ZipStream[B]): ZipStream[(A, B)] = ZipStream(fa.value.zip(fb.value)) diff --git a/core/src/main/scala/cats/data/ZipVector.scala b/core/src/main/scala/cats/data/ZipVector.scala index 74a0529adbf..02153b4973e 100644 --- a/core/src/main/scala/cats/data/ZipVector.scala +++ b/core/src/main/scala/cats/data/ZipVector.scala @@ -14,7 +14,7 @@ object ZipVector { override def map[A, B](fa: ZipVector[A])(f: (A) => B): ZipVector[B] = ZipVector(fa.value.map(f)) def ap[A, B](ff: ZipVector[A => B])(fa: ZipVector[A]): ZipVector[B] = - ZipVector((ff.value, fa.value).zipped.map(_ apply _)) + ZipVector((ff.value, fa.value).zipped.map(_.apply(_))) } diff --git a/core/src/main/scala/cats/data/package.scala b/core/src/main/scala/cats/data/package.scala index d60fa9756a0..4ec10f438f5 100644 --- a/core/src/main/scala/cats/data/package.scala +++ b/core/src/main/scala/cats/data/package.scala @@ -16,7 +16,6 @@ package object data { def NonEmptyStream[A](head: A, tail: A*): NonEmptyStream[A] = OneAnd(head, tail.toStream) - type NonEmptyMap[K, +A] = NonEmptyMapImpl.Type[K, A] val NonEmptyMap = NonEmptyMapImpl @@ -39,17 +38,17 @@ package object data { object Writer { def apply[L, V](l: L, v: V): WriterT[Id, L, V] = WriterT[Id, L, V]((l, v)) - def value[L:Monoid, V](v: V): Writer[L, V] = WriterT.value(v) + def value[L: Monoid, V](v: V): Writer[L, V] = WriterT.value(v) def tell[L](l: L): Writer[L, Unit] = WriterT.tell(l) } /** - * `StateT[F, S, A]` is similar to `Kleisli[F, S, A]` in that it takes an `S` - * argument and produces an `A` value wrapped in `F`. However, it also produces - * an `S` value representing the updated state (which is wrapped in the `F` - * context along with the `A` value. - */ + * `StateT[F, S, A]` is similar to `Kleisli[F, S, A]` in that it takes an `S` + * argument and produces an `A` value wrapped in `F`. However, it also produces + * an `S` value representing the updated state (which is wrapped in the `F` + * context along with the `A` value. + */ type StateT[F[_], S, A] = IndexedStateT[F, S, S, A] object StateT extends StateTFunctions with CommonStateTConstructors0 @@ -60,9 +59,9 @@ package object data { val IRWST = IndexedReaderWriterStateT /** - * Represents a stateful computation in a context `F[_]`, over state `S`, with an - * initial environment `E`, an accumulated log `L` and a result `A`. - */ + * Represents a stateful computation in a context `F[_]`, over state `S`, with an + * initial environment `E`, an accumulated log `L` and a result `A`. + */ type ReaderWriterStateT[F[_], E, L, S, A] = IndexedReaderWriterStateT[F, E, L, S, S, A] object ReaderWriterStateT extends RWSTFunctions diff --git a/core/src/main/scala/cats/evidence/As.scala b/core/src/main/scala/cats/evidence/As.scala index 13a4334b234..9813dab9d30 100644 --- a/core/src/main/scala/cats/evidence/As.scala +++ b/core/src/main/scala/cats/evidence/As.scala @@ -4,29 +4,30 @@ package evidence import arrow.Category /** - * As substitutability: A better `<:<` - * - * This class exists to aid in the capture proof of subtyping - * relationships, which can be applied in other context to widen other - * type - * - * `A As B` holds whenever `A` could be used in any negative context - * that expects a `B`. (e.g. if you could pass an `A` into any - * function that expects a `B` as input.) - * - * This code was ported directly from scalaz to cats using this version from scalaz: - * https://github.com/scalaz/scalaz/blob/a89b6d63/core/src/main/scala/scalaz/As.scala - * - * The original contribution to scalaz came from Jason Zaugg - */ + * As substitutability: A better `<:<` + * + * This class exists to aid in the capture proof of subtyping + * relationships, which can be applied in other context to widen other + * type + * + * `A As B` holds whenever `A` could be used in any negative context + * that expects a `B`. (e.g. if you could pass an `A` into any + * function that expects a `B` as input.) + * + * This code was ported directly from scalaz to cats using this version from scalaz: + * https://github.com/scalaz/scalaz/blob/a89b6d63/core/src/main/scala/scalaz/As.scala + * + * The original contribution to scalaz came from Jason Zaugg + */ sealed abstract class As[-A, +B] extends Serializable { + /** - * Use this subtyping relationship to replace B with a value of type - * A in a contravariant context. This would commonly be the input - * to a function, such as F in: `type F[-B] = B => String`. In this - * case, we could use A As B to turn an F[B] Into F[A]. - */ - def substitute[F[-_]](p: F[B]): F[A] + * Use this subtyping relationship to replace B with a value of type + * A in a contravariant context. This would commonly be the input + * to a function, such as F in: `type F[-B] = B => String`. In this + * case, we could use A As B to turn an F[B] Into F[A]. + */ + def substitute[F[- _]](p: F[B]): F[A] @inline final def andThen[C](that: (B As C)): (A As C) = As.compose(that, this) @@ -44,39 +45,41 @@ sealed abstract class AsInstances { implicit val liskov: Category[As] = new Category[As] { def id[A]: (A As A) = refl[A] - def compose[A, B, C](bc: B As C, ab: A As B): (A As C) = bc compose ab + def compose[A, B, C](bc: B As C, ab: A As B): (A As C) = bc.compose(ab) } } object As extends AsInstances { + /** - * In truth, "all values of `A Is B` are `refl`". `reflAny` is that - * single value. - */ + * In truth, "all values of `A Is B` are `refl`". `reflAny` is that + * single value. + */ private[this] val reflAny = new (Any As Any) { - def substitute[F[-_]](fa: F[Any]) = fa + def substitute[F[- _]](fa: F[Any]) = fa } + /** - * Subtyping is reflexive - */ + * Subtyping is reflexive + */ implicit def refl[A]: (A As A) = reflAny.asInstanceOf[A As A] /** - * We can witness the relationship by using it to make a substitution * - */ + * We can witness the relationship by using it to make a substitution * + */ implicit def witness[A, B](lt: A As B): A => B = lt.substitute[-? => B](identity) /** - * Subtyping is transitive - */ + * Subtyping is transitive + */ def compose[A, B, C](f: B As C, g: A As B): A As C = g.substitute[λ[`-α` => α As C]](f) /** - * reify a subtype relationship as a Liskov relationship - */ + * reify a subtype relationship as a Liskov relationship + */ @inline def reify[A, B >: A]: (A As B) = refl /** @@ -89,46 +92,46 @@ object As extends AsInstances { reflAny.asInstanceOf[A As B] /** - * We can lift subtyping into any covariant type constructor - */ - def co[T[+_], A, A2] (a: A As A2): (T[A] As T[A2]) = + * We can lift subtyping into any covariant type constructor + */ + def co[T[+ _], A, A2](a: A As A2): (T[A] As T[A2]) = a.substitute[λ[`-α` => T[α] As T[A2]]](refl) // Similarly, we can do this any time we find a covariant type // parameter. Here we provide the proof for what we expect to be the // most common shapes. - def co2[T[+_, _], Z, A, B](a: A As Z): T[A, B] As T[Z, B] = + def co2[T[+ _, _], Z, A, B](a: A As Z): T[A, B] As T[Z, B] = a.substitute[λ[`-α` => T[α, B] As T[Z, B]]](refl) /** - * Widen a F[X,+A] to a F[X,B] if (A As B). This can be used to widen - * the output of a Function1, for example. - */ - def co2_2[T[_, +_], Z, A, B](a: B As Z): T[A, B] As T[A, Z] = + * Widen a F[X,+A] to a F[X,B] if (A As B). This can be used to widen + * the output of a Function1, for example. + */ + def co2_2[T[_, + _], Z, A, B](a: B As Z): T[A, B] As T[A, Z] = a.substitute[λ[`-α` => T[A, α] As T[A, Z]]](refl) - def co3[T[+_, _, _], Z, A, B, C](a: A As Z): T[A, B, C] As T[Z, B, C] = + def co3[T[+ _, _, _], Z, A, B, C](a: A As Z): T[A, B, C] As T[Z, B, C] = a.substitute[λ[`-α` => T[α, B, C] As T[Z, B, C]]](refl) - def co3_2[T[_, +_, _], Z, A, B, C](a: B As Z): T[A, B, C] As T[A, Z, C] = + def co3_2[T[_, + _, _], Z, A, B, C](a: B As Z): T[A, B, C] As T[A, Z, C] = a.substitute[λ[`-α` => T[A, α, C] As T[A, Z, C]]](refl) - def co3_3[T[+_, _, +_], Z, A, B, C](a: C As Z): T[A, B, C] As T[A, B, Z] = + def co3_3[T[+ _, _, + _], Z, A, B, C](a: C As Z): T[A, B, C] As T[A, B, Z] = a.substitute[λ[`-α` => T[A, B, α] As T[A, B, Z]]](refl) /** - * Use this relationship to widen the output type of a Function1 - */ + * Use this relationship to widen the output type of a Function1 + */ def onF[X, A, B](ev: A As B)(fa: X => A): X => B = co2_2[Function1, B, X, A](ev).coerce(fa) /** - * widen two types for binary type constructors covariant in both - * parameters - * - * lift2(a,b) = co1_2(a) compose co2_2(b) - */ - def lift2[T[+_, +_], A, A2, B, B2]( + * widen two types for binary type constructors covariant in both + * parameters + * + * lift2(a,b) = co1_2(a) compose co2_2(b) + */ + def lift2[T[+ _, + _], A, A2, B, B2]( a: A As A2, b: B As B2 ): (T[A, B] As T[A2, B2]) = { @@ -138,43 +141,43 @@ object As extends AsInstances { } /** - * We can lift a subtyping relationship into a contravariant type - * constructor. - * - * Given that F has the shape: F[-_], we show that: - * (A As B) implies (F[B] As F[A]) - */ - def contra[T[-_], A, B](a: A As B): (T[B] As T[A]) = + * We can lift a subtyping relationship into a contravariant type + * constructor. + * + * Given that F has the shape: F[-_], we show that: + * (A As B) implies (F[B] As F[A]) + */ + def contra[T[- _], A, B](a: A As B): (T[B] As T[A]) = a.substitute[λ[`-α` => T[B] As T[α]]](refl) // Similarly, we can do this any time we find a contravariant type // parameter. Here we provide the proof for what we expect to be the // most common shapes. - def contra1_2[T[-_, _], Z, A, B](a: A As Z): (T[Z, B] As T[A, B]) = + def contra1_2[T[- _, _], Z, A, B](a: A As Z): (T[Z, B] As T[A, B]) = a.substitute[λ[`-α` => T[Z, B] As T[α, B]]](refl) - def contra2_2[T[_, -_], Z, A, B](a: B As Z): (T[A, Z] As T[A, B]) = + def contra2_2[T[_, - _], Z, A, B](a: B As Z): (T[A, Z] As T[A, B]) = a.substitute[λ[`-α` => T[A, Z] As T[A, α]]](refl) - def contra1_3[T[-_, _, _], Z, A, B, C](a: A As Z): (T[Z, B, C] As T[A, B, C]) = + def contra1_3[T[- _, _, _], Z, A, B, C](a: A As Z): (T[Z, B, C] As T[A, B, C]) = a.substitute[λ[`-α` => T[Z, B, C] As T[α, B, C]]](refl) - def contra2_3[T[_, -_, _], Z, A, B, C](a: B As Z): (T[A, Z, C] As T[A, B, C]) = + def contra2_3[T[_, - _, _], Z, A, B, C](a: B As Z): (T[A, Z, C] As T[A, B, C]) = a.substitute[λ[`-α` => T[A, Z, C] As T[A, α, C]]](refl) - def contra3_3[T[_, _, -_], Z, A, B, C](a: C As Z): (T[A, B, Z] As T[A, B, C]) = + def contra3_3[T[_, _, - _], Z, A, B, C](a: C As Z): (T[A, B, Z] As T[A, B, C]) = a.substitute[λ[`-α` => T[A, B, Z] As T[A, B, α]]](refl) /** - * Use this relationship to narrow the input type of a Function1 - */ + * Use this relationship to narrow the input type of a Function1 + */ def conF[A, B, C](ev: B As A)(fa: A => C): B => C = contra1_2[Function1, A, B, C](ev).coerce(fa) /** - * Use this relationship to widen the output type and narrow the input type of a Function1 - */ + * Use this relationship to widen the output type and narrow the input type of a Function1 + */ def invF[C, D, A, B](ev1: D As C, ev2: A As B)(fa: C => A): D => B = conF(ev1)(onF(ev2)(fa)) } diff --git a/core/src/main/scala/cats/evidence/Is.scala b/core/src/main/scala/cats/evidence/Is.scala index e27c7825247..1b48d732ae3 100644 --- a/core/src/main/scala/cats/evidence/Is.scala +++ b/core/src/main/scala/cats/evidence/Is.scala @@ -3,22 +3,22 @@ package cats.evidence import cats.Id /** - * A value of `A Is B` is proof that the types `A` and `B` are the same. More - * powerfully, it asserts that they have the same meaning in all type - * contexts. This can be a more powerful assertion than `A =:= B` and is more - * easily used in manipulation of types while avoiding (potentially - * erroneous) coercions. - * - * `A Is B` is also known as Leibniz equality. - */ + * A value of `A Is B` is proof that the types `A` and `B` are the same. More + * powerfully, it asserts that they have the same meaning in all type + * contexts. This can be a more powerful assertion than `A =:= B` and is more + * easily used in manipulation of types while avoiding (potentially + * erroneous) coercions. + * + * `A Is B` is also known as Leibniz equality. + */ abstract class Is[A, B] extends Serializable { /** - * To create an instance of `A Is B` you must show that for every choice - * of `F[_]` you can convert `F[A]` to `F[B]`. Loosely, this reads as - * saying that `B` must have the same effect as `A` in all contexts - * therefore allowing type substitution. - */ + * To create an instance of `A Is B` you must show that for every choice + * of `F[_]` you can convert `F[A]` to `F[B]`. Loosely, this reads as + * saying that `B` must have the same effect as `A` in all contexts + * therefore allowing type substitution. + */ def substitute[F[_]](fa: F[A]): F[B] /** @@ -33,7 +33,7 @@ abstract class Is[A, B] extends Serializable { * chain much like functions. See also `andThen`. */ @inline final def compose[C](prev: C Is A): C Is B = - prev andThen this + prev.andThen(this) /** * `Is` is symmetric and therefore can be flipped around. Flipping is its @@ -51,9 +51,9 @@ abstract class Is[A, B] extends Serializable { substitute[λ[α => F[A] Is F[α]]](Is.refl) /** - * Substitution on identity brings about a direct coercion function of the - * same form that `=:=` provides. - */ + * Substitution on identity brings about a direct coercion function of the + * same form that `=:=` provides. + */ @inline final def coerce(a: A): B = substitute[Id](a) @@ -68,33 +68,32 @@ abstract class Is[A, B] extends Serializable { object Is { /** - * In truth, "all values of `A Is B` are `refl`". `reflAny` is that - * single value. - */ + * In truth, "all values of `A Is B` are `refl`". `reflAny` is that + * single value. + */ private[this] val reflAny = new Is[Any, Any] { def substitute[F[_]](fa: F[Any]) = fa } /** - * In normal circumstances the only `Is` value which is available is the - * computational identity `A Is A` at all types `A`. These "self loops" - * generate all of the behavior of equality and also ensure that at its - * heart `A Is B` is always just an identity relation. - * - * Implementation note: all values of `refl` return the same (private) - * instance at whatever type is appropriate to save on allocations. - */ + * In normal circumstances the only `Is` value which is available is the + * computational identity `A Is A` at all types `A`. These "self loops" + * generate all of the behavior of equality and also ensure that at its + * heart `A Is B` is always just an identity relation. + * + * Implementation note: all values of `refl` return the same (private) + * instance at whatever type is appropriate to save on allocations. + */ @inline implicit def refl[A]: A Is A = reflAny.asInstanceOf[A Is A] /** - * It can be convenient to convert a `Predef.=:=` value into an `Is` value. - * This is not strictly valid as while it is almost certainly true that - * `A =:= B` implies `A Is B` it is not the case that you can create - * evidence of `A Is B` except via a coercion. Use responsibly. - */ + * It can be convenient to convert a `Predef.=:=` value into an `Is` value. + * This is not strictly valid as while it is almost certainly true that + * `A =:= B` implies `A Is B` it is not the case that you can create + * evidence of `A Is B` except via a coercion. Use responsibly. + */ @inline def unsafeFromPredef[A, B](eq: A =:= B): A Is B = reflAny.asInstanceOf[A Is B] } - diff --git a/core/src/main/scala/cats/evidence/package.scala b/core/src/main/scala/cats/evidence/package.scala index becac9b56e9..e14ae827cf4 100644 --- a/core/src/main/scala/cats/evidence/package.scala +++ b/core/src/main/scala/cats/evidence/package.scala @@ -1,36 +1,37 @@ package cats package object evidence { + /** - * A convenient type alias for Is, which declares that A is the same - * type as B. - */ + * A convenient type alias for Is, which declares that A is the same + * type as B. + */ type ===[A, B] = A Is B /** - * This type level equality represented by `Is` is referred to as - * "Leibniz equality", and it had the name "Leibniz" in the scalaz - * https://en.wikipedia.org/wiki/Gottfried_Wilhelm_Leibniz - */ + * This type level equality represented by `Is` is referred to as + * "Leibniz equality", and it had the name "Leibniz" in the scalaz + * https://en.wikipedia.org/wiki/Gottfried_Wilhelm_Leibniz + */ type Leibniz[A, B] = A Is B /** - * A convenient type alias for As, this declares that A is a - * subtype of B, and should be able to be a B is - * expected. - */ + * A convenient type alias for As, this declares that A is a + * subtype of B, and should be able to be a B is + * expected. + */ type <~<[-A, +B] = A As B /** - * A flipped alias, for those used to their arrows running left to right - */ + * A flipped alias, for those used to their arrows running left to right + */ type >~>[+B, -A] = A As B /** - * The property that a value of type A can be used in a context - * expecting a B if A <~< B is referred to as the "Liskov - * Substitution Principal", which is named for Barbara Liskov: - * https://en.wikipedia.org/wiki/Barbara_Liskov - */ + * The property that a value of type A can be used in a context + * expecting a B if A <~< B is referred to as the "Liskov + * Substitution Principal", which is named for Barbara Liskov: + * https://en.wikipedia.org/wiki/Barbara_Liskov + */ type Liskov[-A, +B] = A As B } diff --git a/core/src/main/scala/cats/instances/all.scala b/core/src/main/scala/cats/instances/all.scala index f270ec61f2c..3cc7339d9d3 100644 --- a/core/src/main/scala/cats/instances/all.scala +++ b/core/src/main/scala/cats/instances/all.scala @@ -2,40 +2,38 @@ package cats package instances trait AllInstances - extends AnyValInstances - with BigIntInstances - with BigDecimalInstances - with BitSetInstances - with EitherInstances - with EqInstances - with EquivInstances - with FunctionInstances - with FutureInstances - with HashInstances - with InvariantMonoidalInstances - with ListInstances - with MapInstances - with OptionInstances - with OrderInstances - with OrderingInstances - with ParallelInstances - with PartialOrderInstances - with PartialOrderingInstances - with QueueInstances - with SetInstances - with SortedMapInstances - with SortedSetInstances - with StreamInstances - with StringInstances - with SymbolInstances - with TryInstances - with TupleInstances - with UUIDInstances - with VectorInstances + extends AnyValInstances + with BigIntInstances + with BigDecimalInstances + with BitSetInstances + with EitherInstances + with EqInstances + with EquivInstances + with FunctionInstances + with FutureInstances + with HashInstances + with InvariantMonoidalInstances + with ListInstances + with MapInstances + with OptionInstances + with OrderInstances + with OrderingInstances + with ParallelInstances + with PartialOrderInstances + with PartialOrderingInstances + with QueueInstances + with SetInstances + with SortedMapInstances + with SortedSetInstances + with StreamInstances + with StringInstances + with SymbolInstances + with TryInstances + with TupleInstances + with UUIDInstances + with VectorInstances -trait AllInstancesBinCompat0 - extends FunctionInstancesBinCompat0 - with Tuple2InstancesBinCompat0 +trait AllInstancesBinCompat0 extends FunctionInstancesBinCompat0 with Tuple2InstancesBinCompat0 trait AllInstancesBinCompat1 extends OptionInstancesBinCompat0 @@ -45,6 +43,4 @@ trait AllInstancesBinCompat1 with MapInstancesBinCompat0 with SortedMapInstancesBinCompat0 -trait AllInstancesBinCompat2 - extends DurationInstances - with FiniteDurationInstances +trait AllInstancesBinCompat2 extends DurationInstances with FiniteDurationInstances diff --git a/core/src/main/scala/cats/instances/anyval.scala b/core/src/main/scala/cats/instances/anyval.scala index 05060c3da97..8f8827738f6 100644 --- a/core/src/main/scala/cats/instances/anyval.scala +++ b/core/src/main/scala/cats/instances/anyval.scala @@ -2,16 +2,16 @@ package cats package instances trait AnyValInstances - extends IntInstances - with ByteInstances - with CharInstances - with LongInstances - with ShortInstances - with FloatInstances - with DoubleInstances - with BooleanInstances - with UnitInstances - with TupleInstances + extends IntInstances + with ByteInstances + with CharInstances + with LongInstances + with ShortInstances + with FloatInstances + with DoubleInstances + with BooleanInstances + with UnitInstances + with TupleInstances trait IntInstances extends cats.kernel.instances.IntInstances { implicit val catsStdShowForInt: Show[Int] = Show.fromToString[Int] diff --git a/core/src/main/scala/cats/instances/either.scala b/core/src/main/scala/cats/instances/either.scala index c5adfab0992..79ae373c68b 100644 --- a/core/src/main/scala/cats/instances/either.scala +++ b/core/src/main/scala/cats/instances/either.scala @@ -8,21 +8,23 @@ import scala.annotation.tailrec trait EitherInstances extends cats.kernel.instances.EitherInstances { 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]] = + 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 { - case Left(a) => G.map(f(a))(Left(_)) + case Left(a) => G.map(f(a))(Left(_)) case Right(b) => G.map(g(b))(Right(_)) } def bifoldLeft[A, B, C](fab: Either[A, B], c: C)(f: (C, A) => C, g: (C, B) => C): C = fab match { - case Left(a) => f(c, a) + case Left(a) => f(c, a) case Right(b) => g(c, b) } - def bifoldRight[A, B, C](fab: Either[A, B], c: Eval[C])(f: (A, Eval[C]) => Eval[C], g: (B, Eval[C]) => Eval[C]): Eval[C] = + def bifoldRight[A, B, C](fab: Either[A, B], c: Eval[C])(f: (A, Eval[C]) => Eval[C], + g: (B, Eval[C]) => Eval[C]): Eval[C] = fab match { - case Left(a) => f(a, c) + case Left(a) => f(a, c) case Right(b) => g(b, c) } } @@ -37,7 +39,7 @@ trait EitherInstances extends cats.kernel.instances.EitherInstances { def handleErrorWith[B](fea: Either[A, B])(f: A => Either[A, B]): Either[A, B] = fea match { - case Left(e) => f(e) + case Left(e) => f(e) case r @ Right(_) => r } @@ -53,7 +55,7 @@ trait EitherInstances extends cats.kernel.instances.EitherInstances { left.rightCast[C] case Right(e) => e match { - case Left(b1) => tailRecM(b1)(f) + case Left(b1) => tailRecM(b1)(f) case right @ Right(_) => right.leftCast[A] } } @@ -61,7 +63,7 @@ trait EitherInstances extends cats.kernel.instances.EitherInstances { 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 { case l @ Left(_) => Now(EitherUtil.rightCast(l)) - case Right(b) => fc.map(_.right.map(f(b, _))) + case Right(b) => fc.map(_.right.map(f(b, _))) } def traverse[F[_], B, C](fa: Either[A, B])(f: B => F[C])(implicit F: Applicative[F]): F[Either[A, C]] = @@ -72,13 +74,13 @@ trait EitherInstances extends cats.kernel.instances.EitherInstances { def foldLeft[B, C](fa: Either[A, B], c: C)(f: (C, B) => C): C = fa match { - case Left(_) => c + case Left(_) => c case Right(b) => f(c, b) } def foldRight[B, C](fa: Either[A, B], lc: Eval[C])(f: (B, Eval[C]) => Eval[C]): Eval[C] = fa match { - case Left(_) => lc + case Left(_) => lc case Right(b) => f(b, lc) } @@ -86,10 +88,10 @@ trait EitherInstances extends cats.kernel.instances.EitherInstances { Right(fab) override def recover[B](fab: Either[A, B])(pf: PartialFunction[A, B]): Either[A, B] = - fab recover pf + fab.recover(pf) override def recoverWith[B](fab: Either[A, B])(pf: PartialFunction[A, Either[A, B]]): Either[A, B] = - fab recoverWith pf + fab.recoverWith(pf) override def fromEither[B](fab: Either[A, B]): Either[A, B] = fab @@ -103,7 +105,9 @@ trait EitherInstances extends cats.kernel.instances.EitherInstances { override def reduceLeftToOption[B, C](fab: Either[A, B])(f: B => C)(g: (C, B) => C): Option[C] = fab.right.map(f).toOption - override def reduceRightToOption[B, C](fab: Either[A, B])(f: B => C)(g: (B, Eval[C]) => Eval[C]): Eval[Option[C]] = + override def reduceRightToOption[B, C]( + fab: Either[A, B] + )(f: B => C)(g: (B, Eval[C]) => Eval[C]): Eval[Option[C]] = Now(fab.right.map(f).toOption) override def reduceLeftOption[B](fab: Either[A, B])(f: (B, B) => B): Option[B] = @@ -141,7 +145,7 @@ trait EitherInstances extends cats.kernel.instances.EitherInstances { implicit def catsStdSemigroupKForEither[L]: SemigroupK[Either[L, ?]] = new SemigroupK[Either[L, ?]] { def combineK[A](x: Either[L, A], y: Either[L, A]): Either[L, A] = x match { - case Left(_) => y + case Left(_) => y case Right(_) => x } } @@ -150,7 +154,7 @@ trait EitherInstances extends cats.kernel.instances.EitherInstances { new Show[Either[A, B]] { def show(x: Either[A, B]): String = x match { - case Left(a) => "Left(" + A.show(a) + ")" + case Left(a) => "Left(" + A.show(a) + ")" case Right(b) => "Right(" + B.show(b) + ")" } } diff --git a/core/src/main/scala/cats/instances/eq.scala b/core/src/main/scala/cats/instances/eq.scala index 310975db7e1..ab83be52ea0 100644 --- a/core/src/main/scala/cats/instances/eq.scala +++ b/core/src/main/scala/cats/instances/eq.scala @@ -4,16 +4,17 @@ package instances trait EqInstances extends kernel.instances.EqInstances { implicit val catsContravariantMonoidalForEq: ContravariantMonoidal[Eq] = new ContravariantMonoidal[Eq] { + /** - * Defaults to the trivial equivalence relation - * contracting the type to a point - */ + * Defaults to the trivial equivalence relation + * contracting the type to a point + */ def unit: Eq[Unit] = Eq.allEqual /** Derive an `Eq` for `B` given an `Eq[A]` and a function `B => A`. - * - * Note: resulting instances are law-abiding only when the functions used are injective (represent a one-to-one mapping) - */ + * + * Note: resulting instances are law-abiding only when the functions used are injective (represent a one-to-one mapping) + */ def contramap[A, B](fa: Eq[A])(f: B => A): Eq[B] = Eq.by(f)(fa) diff --git a/core/src/main/scala/cats/instances/equiv.scala b/core/src/main/scala/cats/instances/equiv.scala index 6ae653cf987..6819a46ecaa 100644 --- a/core/src/main/scala/cats/instances/equiv.scala +++ b/core/src/main/scala/cats/instances/equiv.scala @@ -4,18 +4,19 @@ package instances trait EquivInstances { implicit val catsContravariantMonoidalForEquiv: ContravariantMonoidal[Equiv] = new ContravariantMonoidal[Equiv] { + /** - * Defaults to trivially contracting the type - * to a point - */ + * Defaults to trivially contracting the type + * to a point + */ def unit: Equiv[Unit] = new Equiv[Unit] { def equiv(x: Unit, y: Unit): Boolean = true } /** Derive an `Equiv` for `B` given an `Equiv[A]` and a function `B => A`. - * - * Note: resulting instances are law-abiding only when the functions used are injective (represent a one-to-one mapping) - */ + * + * Note: resulting instances are law-abiding only when the functions used are injective (represent a one-to-one mapping) + */ def contramap[A, B](fa: Equiv[A])(f: B => A): Equiv[B] = new Equiv[B] { def equiv(l: B, r: B): Boolean = diff --git a/core/src/main/scala/cats/instances/function.scala b/core/src/main/scala/cats/instances/function.scala index 7cbfa937a84..f1e476a520e 100644 --- a/core/src/main/scala/cats/instances/function.scala +++ b/core/src/main/scala/cats/instances/function.scala @@ -2,24 +2,24 @@ package cats package instances import cats.Contravariant -import cats.arrow.{Category, ArrowChoice, CommutativeArrow} +import cats.arrow.{ArrowChoice, Category, CommutativeArrow} import annotation.tailrec - -trait FunctionInstances extends cats.kernel.instances.FunctionInstances - with Function0Instances with Function1Instances +trait FunctionInstances extends cats.kernel.instances.FunctionInstances with Function0Instances with Function1Instances trait FunctionInstancesBinCompat0 { + /** - * Witness for: E => A <-> E => A - */ - implicit def catsStdRepresentableForFunction1[E](implicit EF: Functor[E => ?]): Representable.Aux[E => ?, E] = new Representable[E => ?] { - override type Representation = E - override val F: Functor[E => ?] = EF - override def tabulate[A](f: E => A): E => A = f - override def index[A](f: E => A): E => A = f - } + * Witness for: E => A <-> E => A + */ + implicit def catsStdRepresentableForFunction1[E](implicit EF: Functor[E => ?]): Representable.Aux[E => ?, E] = + new Representable[E => ?] { + override type Representation = E + override val F: Functor[E => ?] = EF + override def tabulate[A](f: E => A): E => A = f + override def index[A](f: E => A): E => A = f + } implicit val catsSddDeferForFunction0: Defer[Function0] = new Defer[Function0] { @@ -29,7 +29,7 @@ trait FunctionInstancesBinCompat0 { def loop(f: () => Function0[A]): A = f() match { case Deferred(f) => loop(f) - case next => next() + case next => next() } loop(fa) } @@ -48,7 +48,7 @@ trait FunctionInstancesBinCompat0 { def loop(f: () => A => B): B = f() match { case Deferred(f) => loop(f) - case next => next(a) + case next => next(a) } loop(fa) } @@ -60,7 +60,7 @@ trait FunctionInstancesBinCompat0 { } } -private[instances] sealed trait Function0Instances extends Function0Instances0 { +sealed private[instances] trait Function0Instances extends Function0Instances0 { implicit val catsStdBimonadForFunction0: Bimonad[Function0] = new Bimonad[Function0] { def extract[A](x: () => A): A = x() @@ -77,7 +77,7 @@ private[instances] sealed trait Function0Instances extends Function0Instances0 { () => { @tailrec def loop(thisA: A): B = fn(thisA)() match { - case Right(b) => b + case Right(b) => b case Left(nextA) => loop(nextA) } loop(a) @@ -86,23 +86,26 @@ private[instances] sealed trait Function0Instances extends Function0Instances0 { } -private[instances] sealed trait Function0Instances0 { - implicit def function0Distributive: Distributive[Function0] = new Distributive[Function0] { - def distribute[F[_]: Functor, A, B](fa: F[A])(f: A => Function0[B]): Function0[F[B]] = {() => Functor[F].map(fa)(a => f(a)()) } +sealed private[instances] trait Function0Instances0 { + implicit def function0Distributive: Distributive[Function0] = new Distributive[Function0] { + def distribute[F[_]: Functor, A, B](fa: F[A])(f: A => Function0[B]): Function0[F[B]] = { () => + Functor[F].map(fa)(a => f(a)()) + } def map[A, B](fa: Function0[A])(f: A => B): Function0[B] = () => f(fa()) } } -private[instances] sealed trait Function1Instances extends Function1Instances0 { +sealed private[instances] trait Function1Instances extends Function1Instances0 { implicit def catsStdContravariantMonoidalForFunction1[R: Monoid]: ContravariantMonoidal[? => R] = new ContravariantMonoidal[? => R] { def unit: Unit => R = Function.const(Monoid[R].empty) def contramap[A, B](fa: A => R)(f: B => A): B => R = - fa compose f + fa.compose(f) def product[A, B](fa: A => R, fb: B => R): ((A, B)) => R = - (ab: (A, B)) => ab match { - case (a, b) => Monoid[R].combine(fa(a), fb(b)) + (ab: (A, B)) => + ab match { + case (a, b) => Monoid[R].combine(fa(a), fb(b)) } } @@ -120,7 +123,7 @@ private[instances] sealed trait Function1Instances extends Function1Instances0 { (t: T1) => { @tailrec def step(thisA: A): B = fn(thisA)(t) match { - case Right(b) => b + case Right(b) => b case Left(nextA) => step(nextA) } step(a) @@ -131,7 +134,7 @@ private[instances] sealed trait Function1Instances extends Function1Instances0 { new ArrowChoice[Function1] with CommutativeArrow[Function1] { def choose[A, B, C, D](f: A => C)(g: B => D): Either[A, B] => Either[C, D] = _ match { - case Left(a) => Left(f(a)) + case Left(a) => Left(f(a)) case Right(b) => Right(g(b)) } @@ -151,10 +154,9 @@ private[instances] sealed trait Function1Instances extends Function1Instances0 { implicit val catsStdMonoidKForFunction1: MonoidK[Endo] = Category[Function1].algebraK - } -private[instances] sealed trait Function1Instances0 { +sealed private[instances] trait Function1Instances0 { implicit def catsStdContravariantForFunction1[R]: Contravariant[? => R] = new Contravariant[? => R] { def contramap[T1, T0](fa: T1 => R)(f: T0 => T1): T0 => R = @@ -162,8 +164,12 @@ private[instances] sealed trait Function1Instances0 { } implicit def catsStdDistributiveForFunction1[T1]: Distributive[T1 => ?] = new Distributive[T1 => ?] { - def distribute[F[_]: Functor, A, B](fa: F[A])(f: A => (T1 => B)): T1 => F[B] = {t1 => Functor[F].map(fa)(a => f(a)(t1)) } + def distribute[F[_]: Functor, A, B](fa: F[A])(f: A => (T1 => B)): T1 => F[B] = { t1 => + Functor[F].map(fa)(a => f(a)(t1)) + } - def map[A, B](fa: T1 => A)(f: A => B): T1 => B = {t1 => f(fa(t1))} + def map[A, B](fa: T1 => A)(f: A => B): T1 => B = { t1 => + f(fa(t1)) + } } } diff --git a/core/src/main/scala/cats/instances/future.scala b/core/src/main/scala/cats/instances/future.scala index 2c629568165..0518529ed06 100644 --- a/core/src/main/scala/cats/instances/future.scala +++ b/core/src/main/scala/cats/instances/future.scala @@ -6,7 +6,9 @@ import scala.concurrent.{ExecutionContext, Future} trait FutureInstances extends FutureInstances1 { - implicit def catsStdInstancesForFuture(implicit ec: ExecutionContext): MonadError[Future, Throwable] with CoflatMap[Future] with Monad[Future] = + implicit def catsStdInstancesForFuture( + implicit ec: ExecutionContext + ): MonadError[Future, Throwable] with CoflatMap[Future] with Monad[Future] = new FutureCoflatMap with MonadError[Future, Throwable] with Monad[Future] with StackSafeMonad[Future] { def pure[A](x: A): Future[A] = Future.successful(x) @@ -18,11 +20,12 @@ trait FutureInstances extends FutureInstances1 { override def handleError[A](fea: Future[A])(f: Throwable => A): Future[A] = fea.recover { case t => f(t) } override def attempt[A](fa: Future[A]): Future[Either[Throwable, A]] = - (fa.map(a => Right[Throwable, A](a))) recover { case NonFatal(t) => Left(t) } + (fa.map(a => Right[Throwable, A](a))).recover { case NonFatal(t) => Left(t) } override def recover[A](fa: Future[A])(pf: PartialFunction[Throwable, A]): Future[A] = fa.recover(pf) - override def recoverWith[A](fa: Future[A])(pf: PartialFunction[Throwable, Future[A]]): Future[A] = fa.recoverWith(pf) + override def recoverWith[A](fa: Future[A])(pf: PartialFunction[Throwable, Future[A]]): Future[A] = + fa.recoverWith(pf) override def map[A, B](fa: Future[A])(f: A => B): Future[B] = fa.map(f) @@ -32,23 +35,23 @@ trait FutureInstances extends FutureInstances1 { } } -private[instances] sealed trait FutureInstances1 extends FutureInstances2 { +sealed private[instances] trait FutureInstances1 extends FutureInstances2 { implicit def catsStdMonoidForFuture[A: Monoid](implicit ec: ExecutionContext): Monoid[Future[A]] = new FutureMonoid[A] } -private[instances] sealed trait FutureInstances2 { +sealed private[instances] trait FutureInstances2 { implicit def catsStdSemigroupForFuture[A: Semigroup](implicit ec: ExecutionContext): Semigroup[Future[A]] = new FutureSemigroup[A] } -private[cats] abstract class FutureCoflatMap(implicit ec: ExecutionContext) extends CoflatMap[Future] { +abstract private[cats] class FutureCoflatMap(implicit ec: ExecutionContext) extends CoflatMap[Future] { def map[A, B](fa: Future[A])(f: A => B): Future[B] = fa.map(f) def coflatMap[A, B](fa: Future[A])(f: Future[A] => B): Future[B] = Future(f(fa)) } private[cats] class FutureSemigroup[A: Semigroup](implicit ec: ExecutionContext) - extends ApplySemigroup[Future, A](future.catsStdInstancesForFuture, implicitly) + extends ApplySemigroup[Future, A](future.catsStdInstancesForFuture, implicitly) private[cats] class FutureMonoid[A](implicit A: Monoid[A], ec: ExecutionContext) - extends ApplicativeMonoid[Future, A](future.catsStdInstancesForFuture, implicitly) + extends ApplicativeMonoid[Future, A](future.catsStdInstancesForFuture, implicitly) diff --git a/core/src/main/scala/cats/instances/hash.scala b/core/src/main/scala/cats/instances/hash.scala index 2401313148a..cd09ab78a96 100644 --- a/core/src/main/scala/cats/instances/hash.scala +++ b/core/src/main/scala/cats/instances/hash.scala @@ -1,14 +1,14 @@ package cats package instances - trait HashInstances extends kernel.instances.HashInstances { implicit val catsContravariantForHash: Contravariant[Hash] = new Contravariant[Hash] { + /** - * Derive a `Hash` for `B` given an `Hash[A]` and a function `B => A`. - */ + * Derive a `Hash` for `B` given an `Hash[A]` and a function `B => A`. + */ def contramap[A, B](ha: Hash[A])(f: B => A): Hash[B] = Hash.by(f)(ha) } diff --git a/core/src/main/scala/cats/instances/invariant.scala b/core/src/main/scala/cats/instances/invariant.scala index e6839415434..0479941cb1c 100644 --- a/core/src/main/scala/cats/instances/invariant.scala +++ b/core/src/main/scala/cats/instances/invariant.scala @@ -2,7 +2,7 @@ package cats.instances import cats.kernel._ import cats.kernel.instances.unit._ -import cats.{InvariantMonoidal, Monoid, InvariantSemigroupal} +import cats.{InvariantMonoidal, InvariantSemigroupal, Monoid} trait InvariantMonoidalInstances { @@ -31,16 +31,19 @@ trait InvariantMonoidalInstances { def unit: Semigroup[Unit] = implicitly } - implicit val catsInvariantMonoidalCommutativeSemigroup: InvariantMonoidal[CommutativeSemigroup] = new InvariantMonoidal[CommutativeSemigroup] { - def product[A, B](fa: CommutativeSemigroup[A], fb: CommutativeSemigroup[B]): CommutativeSemigroup[(A, B)] = new CommutativeSemigroup[(A, B)] { - def combine(x: (A, B), y: (A, B)): (A, B) = fa.combine(x._1, y._1) -> fb.combine(x._2, y._2) - } + implicit val catsInvariantMonoidalCommutativeSemigroup: InvariantMonoidal[CommutativeSemigroup] = + new InvariantMonoidal[CommutativeSemigroup] { + def product[A, B](fa: CommutativeSemigroup[A], fb: CommutativeSemigroup[B]): CommutativeSemigroup[(A, B)] = + new CommutativeSemigroup[(A, B)] { + def combine(x: (A, B), y: (A, B)): (A, B) = fa.combine(x._1, y._1) -> fb.combine(x._2, y._2) + } - def imap[A, B](fa: CommutativeSemigroup[A])(f: A => B)(g: B => A): CommutativeSemigroup[B] = new CommutativeSemigroup[B] { - def combine(x: B, y: B): B = f(fa.combine(g(x), g(y))) - } + def imap[A, B](fa: CommutativeSemigroup[A])(f: A => B)(g: B => A): CommutativeSemigroup[B] = + new CommutativeSemigroup[B] { + def combine(x: B, y: B): B = f(fa.combine(g(x), g(y))) + } - def unit: CommutativeSemigroup[Unit] = implicitly - } + def unit: CommutativeSemigroup[Unit] = implicitly + } } diff --git a/core/src/main/scala/cats/instances/list.scala b/core/src/main/scala/cats/instances/list.scala index 7ef2972a0b7..eaee73b5bfe 100644 --- a/core/src/main/scala/cats/instances/list.scala +++ b/core/src/main/scala/cats/instances/list.scala @@ -33,12 +33,13 @@ trait ListInstances extends cats.kernel.instances.ListInstances { def tailRecM[A, B](a: A)(f: A => List[Either[A, B]]): List[B] = { val buf = List.newBuilder[B] @tailrec def go(lists: List[List[Either[A, B]]]): Unit = lists match { - case (ab :: abs) :: tail => ab match { - case Right(b) => buf += b; go(abs :: tail) - case Left(a) => go(f(a) :: abs :: tail) - } + case (ab :: abs) :: tail => + ab match { + case Right(b) => buf += b; go(abs :: tail) + case Left(a) => go(f(a) :: abs :: tail) + } case Nil :: tail => go(tail) - case Nil => () + case Nil => () } go(f(a) :: Nil) buf.result @@ -47,7 +48,7 @@ trait ListInstances extends cats.kernel.instances.ListInstances { 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 { - case Nil => buf.toList + case Nil => buf.toList case _ :: rest => loop(buf += f(as), rest) } loop(ListBuffer.empty[B], fa) @@ -59,7 +60,7 @@ trait ListInstances extends cats.kernel.instances.ListInstances { def foldRight[A, B](fa: List[A], lb: Eval[B])(f: (A, Eval[B]) => Eval[B]): Eval[B] = { def loop(as: List[A]): Eval[B] = as match { - case Nil => lb + case Nil => lb case h :: t => f(h, Eval.defer(loop(t))) } Eval.defer(loop(fa)) @@ -69,7 +70,7 @@ trait ListInstances extends cats.kernel.instances.ListInstances { B.combineAll(fa.iterator.map(f)) def traverse[G[_], A, B](fa: List[A])(f: A => G[B])(implicit G: Applicative[G]): G[List[B]] = - foldRight[A, G[List[B]]](fa, Always(G.pure(List.empty))){ (a, lglb) => + foldRight[A, G[List[B]]](fa, Always(G.pure(List.empty))) { (a, lglb) => G.map2Eval(f(a), lglb)(_ :: _) }.value @@ -79,13 +80,16 @@ trait ListInstances extends cats.kernel.instances.ListInstances { override def zipWithIndex[A](fa: List[A]): List[(A, Int)] = fa.zipWithIndex - override def partitionEither[A, B, C](fa: List[A]) - (f: (A) => Either[B, C]) - (implicit A: Alternative[List]): (List[B], List[C]) = - fa.foldRight((List.empty[B], List.empty[C]))((a, acc) => f(a) match { - case Left(b) => (b :: acc._1, acc._2) - case Right(c) => (acc._1, c :: acc._2) - }) + override def partitionEither[A, B, C]( + fa: List[A] + )(f: (A) => Either[B, C])(implicit A: Alternative[List]): (List[B], List[C]) = + fa.foldRight((List.empty[B], List.empty[C]))( + (a, acc) => + f(a) match { + case Left(b) => (b :: acc._1, acc._2) + case Right(c) => (acc._1, c :: acc._2) + } + ) @tailrec override def get[A](fa: List[A])(idx: Long): Option[A] = @@ -108,7 +112,10 @@ trait ListInstances extends cats.kernel.instances.ListInstances { override def foldM[G[_], A, B](fa: List[A], z: B)(f: (B, A) => G[B])(implicit G: Monad[G]): G[B] = { def step(in: (List[A], B)): G[Either[(List[A], B), B]] = in match { case (Nil, b) => G.pure(Right(b)) - case (a :: tail, b) => G.map(f(b, a)) { bnext => Left((tail, bnext)) } + case (a :: tail, b) => + G.map(f(b, a)) { bnext => + Left((tail, bnext)) + } } G.tailRecM((fa, z))(step) @@ -133,11 +140,12 @@ trait ListInstances extends cats.kernel.instances.ListInstances { override def collectFirst[A, B](fa: List[A])(pf: PartialFunction[A, B]): Option[B] = fa.collectFirst(pf) - override def collectFirstSome[A, B](fa: List[A])(f: A => Option[B]): Option[B] = fa.collectFirst(Function.unlift(f)) + override def collectFirstSome[A, B](fa: List[A])(f: A => Option[B]): Option[B] = + fa.collectFirst(Function.unlift(f)) } - implicit def catsStdShowForList[A:Show]: Show[List[A]] = + implicit def catsStdShowForList[A: Show]: Show[List[A]] = new Show[List[A]] { def show(fa: List[A]): String = fa.iterator.map(_.show).mkString("List(", ", ", ")") @@ -158,14 +166,14 @@ trait ListInstancesBinCompat0 { def traverseFilter[G[_], A, B](fa: List[A])(f: (A) => G[Option[B]])(implicit G: Applicative[G]): G[List[B]] = fa.foldRight(Eval.now(G.pure(List.empty[B])))( - (x, xse) => - G.map2Eval(f(x), xse)((i, o) => i.fold(o)(_ :: o)) - ).value + (x, xse) => G.map2Eval(f(x), xse)((i, o) => i.fold(o)(_ :: o)) + ) + .value override def filterA[G[_], A](fa: List[A])(f: (A) => G[Boolean])(implicit G: Applicative[G]): G[List[A]] = fa.foldRight(Eval.now(G.pure(List.empty[A])))( - (x, xse) => - G.map2Eval(f(x), xse)((b, list) => if (b) x :: list else list) - ).value + (x, xse) => G.map2Eval(f(x), xse)((b, list) => if (b) x :: list else list) + ) + .value } } diff --git a/core/src/main/scala/cats/instances/map.scala b/core/src/main/scala/cats/instances/map.scala index fda0d300523..724773232b4 100644 --- a/core/src/main/scala/cats/instances/map.scala +++ b/core/src/main/scala/cats/instances/map.scala @@ -20,11 +20,17 @@ trait MapInstances extends cats.kernel.instances.MapInstances { implicit def catsStdInstancesForMap[K]: UnorderedTraverse[Map[K, ?]] with FlatMap[Map[K, ?]] = new UnorderedTraverse[Map[K, ?]] with FlatMap[Map[K, ?]] { - def unorderedTraverse[G[_], A, B](fa: Map[K, A])(f: A => G[B])(implicit G: CommutativeApplicative[G]): G[Map[K, B]] = { + def unorderedTraverse[G[_], A, B]( + fa: Map[K, A] + )(f: A => G[B])(implicit G: CommutativeApplicative[G]): G[Map[K, B]] = { val gba: Eval[G[Map[K, B]]] = Always(G.pure(Map.empty)) - val gbb = Foldable.iterateRight(fa, gba){ (kv, lbuf) => - G.map2Eval(f(kv._2), lbuf)({ (b, buf) => buf + (kv._1 -> b)}) - }.value + val gbb = Foldable + .iterateRight(fa, gba) { (kv, lbuf) => + G.map2Eval(f(kv._2), lbuf)({ (b, buf) => + buf + (kv._1 -> b) + }) + } + .value G.map(gbb)(_.toMap) } @@ -43,15 +49,16 @@ trait MapInstances extends cats.kernel.instances.MapInstances { fa.flatMap { case (k, a) => ff.get(k).map(f => (k, f(a))) } override def ap2[A, B, Z](f: Map[K, (A, B) => Z])(fa: Map[K, A], fb: Map[K, B]): Map[K, Z] = - f.flatMap { case (k, f) => - for { a <- fa.get(k); b <- fb.get(k) } yield (k, f(a, b)) + f.flatMap { + case (k, f) => + for { a <- fa.get(k); b <- fb.get(k) } yield (k, f(a, b)) } def flatMap[A, B](fa: Map[K, A])(f: (A) => Map[K, B]): Map[K, B] = fa.flatMap { case (k, a) => f(a).get(k).map((k, _)) } def unorderedFoldMap[A, B: CommutativeMonoid](fa: Map[K, A])(f: (A) => B) = - fa.foldLeft(Monoid[B].empty){ case (b, (k, a)) => Monoid[B].combine(b, f(a)) } + fa.foldLeft(Monoid[B].empty) { case (b, (k, a)) => Monoid[B].combine(b, f(a)) } def tailRecM[A, B](a: A)(f: A => Map[K, Either[A, B]]): Map[K, B] = { val bldr = Map.newBuilder[K, B] @@ -61,7 +68,7 @@ trait MapInstances extends cats.kernel.instances.MapInstances { case Left(a) => f(a).get(k) match { case Some(x) => descend(k, x) - case None => () + case None => () } case Right(b) => bldr += ((k, b)) @@ -72,7 +79,6 @@ trait MapInstances extends cats.kernel.instances.MapInstances { bldr.result } - override def isEmpty[A](fa: Map[K, A]): Boolean = fa.isEmpty override def unorderedFold[A](fa: Map[K, A])(implicit A: CommutativeMonoid[A]): A = @@ -98,18 +104,17 @@ trait MapInstancesBinCompat0 { * res0: Map[Int, Boolean] = Map(1 -> true, 2 -> false, 4 -> true) * }}} */ - def compose[A, B, C](f: Map[B, C], g: Map[A, B]): Map[A, C] = { + def compose[A, B, C](f: Map[B, C], g: Map[A, B]): Map[A, C] = g.foldLeft(Map.empty[A, C]) { case (acc, (key, value)) => f.get(value) match { case Some(other) => acc + (key -> other) - case _ => acc + case _ => acc } } - } } - implicit def catsStdFunctorFilterForMap[K]: FunctorFilter[Map[K, ?]] = { + implicit def catsStdFunctorFilterForMap[K]: FunctorFilter[Map[K, ?]] = new FunctorFilter[Map[K, ?]] { val functor: Functor[Map[K, ?]] = cats.instances.map.catsStdInstancesForMap[K] @@ -127,6 +132,5 @@ trait MapInstancesBinCompat0 { fa.filter { case (_, v) => f(v) } } - } } diff --git a/core/src/main/scala/cats/instances/option.scala b/core/src/main/scala/cats/instances/option.scala index 0a84a02a655..c8641d1cf42 100644 --- a/core/src/main/scala/cats/instances/option.scala +++ b/core/src/main/scala/cats/instances/option.scala @@ -5,12 +5,17 @@ import scala.annotation.tailrec trait OptionInstances extends cats.kernel.instances.OptionInstances { - implicit val catsStdInstancesForOption: Traverse[Option] with MonadError[Option, Unit] with Alternative[Option] with CommutativeMonad[Option] with CoflatMap[Option] = - new Traverse[Option] with MonadError[Option, Unit] with Alternative[Option] with CommutativeMonad[Option] with CoflatMap[Option] { + implicit val catsStdInstancesForOption: Traverse[Option] + with MonadError[Option, Unit] + with Alternative[Option] + with CommutativeMonad[Option] + with CoflatMap[Option] = + new Traverse[Option] with MonadError[Option, Unit] with Alternative[Option] with CommutativeMonad[Option] + with CoflatMap[Option] { def empty[A]: Option[A] = None - def combineK[A](x: Option[A], y: Option[A]): Option[A] = x orElse y + def combineK[A](x: Option[A], y: Option[A]): Option[A] = x.orElse(y) def pure[A](x: A): Option[A] = Some(x) @@ -23,7 +28,7 @@ trait OptionInstances extends cats.kernel.instances.OptionInstances { @tailrec def tailRecM[A, B](a: A)(f: A => Option[Either[A, B]]): Option[B] = f(a) match { - case None => None + case None => None case Some(Left(a1)) => tailRecM(a1)(f) case Some(Right(b)) => Some(b) } @@ -33,7 +38,7 @@ trait OptionInstances extends cats.kernel.instances.OptionInstances { override def map2Eval[A, B, Z](fa: Option[A], fb: Eval[Option[B]])(f: (A, B) => Z): Eval[Option[Z]] = fa match { - case None => Now(None) + case None => Now(None) case Some(a) => fb.map(_.map(f(a, _))) } @@ -42,23 +47,23 @@ trait OptionInstances extends cats.kernel.instances.OptionInstances { def foldLeft[A, B](fa: Option[A], b: B)(f: (B, A) => B): B = fa match { - case None => b + case None => b case Some(a) => f(b, a) } def foldRight[A, B](fa: Option[A], lb: Eval[B])(f: (A, Eval[B]) => Eval[B]): Eval[B] = fa match { - case None => lb + case None => lb case Some(a) => f(a, lb) } def raiseError[A](e: Unit): Option[A] = None - def handleErrorWith[A](fa: Option[A])(f: (Unit) => Option[A]): Option[A] = fa orElse f(()) + def handleErrorWith[A](fa: Option[A])(f: (Unit) => Option[A]): Option[A] = fa.orElse(f(())) def traverse[G[_]: Applicative, A, B](fa: Option[A])(f: A => G[B]): G[Option[B]] = fa match { - case None => Applicative[G].pure(None) + case None => Applicative[G].pure(None) case Some(a) => Applicative[G].map(f(a))(Some(_)) } @@ -117,7 +122,7 @@ trait OptionInstances extends cats.kernel.instances.OptionInstances { new Show[Option[A]] { def show(fa: Option[A]): String = fa match { case Some(a) => s"Some(${A.show(a)})" - case None => "None" + case None => "None" } } } @@ -136,13 +141,13 @@ trait OptionInstancesBinCompat0 { def traverseFilter[G[_], A, B](fa: Option[A])(f: (A) => G[Option[B]])(implicit G: Applicative[G]): G[Option[B]] = fa match { - case None => G.pure(Option.empty[B]) + case None => G.pure(Option.empty[B]) case Some(a) => f(a) } override def filterA[G[_], A](fa: Option[A])(f: (A) => G[Boolean])(implicit G: Applicative[G]): G[Option[A]] = fa match { - case None => G.pure(Option.empty[A]) + case None => G.pure(Option.empty[A]) case Some(a) => G.map(f(a))(b => if (b) Some(a) else None) } diff --git a/core/src/main/scala/cats/instances/order.scala b/core/src/main/scala/cats/instances/order.scala index 4cc59ac3126..7399e15f4f3 100644 --- a/core/src/main/scala/cats/instances/order.scala +++ b/core/src/main/scala/cats/instances/order.scala @@ -7,14 +7,16 @@ trait OrderInstances extends kernel.instances.OrderInstances { implicit val catsContravariantMonoidalForOrder: ContravariantMonoidal[Order] = new ContravariantMonoidal[Order] { + /** - * Provides trivial order - */ + * Provides trivial order + */ def unit: Order[Unit] = Order[Unit] + /** Derive an `Order` for `B` given an `Order[A]` and a function `B => A`. - * - * Note: resulting instances are law-abiding only when the functions used are injective (represent a one-to-one mapping) - */ + * + * Note: resulting instances are law-abiding only when the functions used are injective (represent a one-to-one mapping) + */ def contramap[A, B](fa: Order[A])(f: B => A): Order[B] = Order.by(f)(fa) @@ -27,4 +29,3 @@ trait OrderInstances extends kernel.instances.OrderInstances { } } } - diff --git a/core/src/main/scala/cats/instances/ordering.scala b/core/src/main/scala/cats/instances/ordering.scala index 69ef9203848..f0416a8f9b0 100644 --- a/core/src/main/scala/cats/instances/ordering.scala +++ b/core/src/main/scala/cats/instances/ordering.scala @@ -6,10 +6,10 @@ import cats.kernel.instances.unit._ trait OrderingInstances { implicit val catsContravariantMonoidalForOrdering: ContravariantMonoidal[Ordering] = new ContravariantMonoidal[Ordering] { - /** - * Note: resulting instances are law-abiding only when the functions used are injective (represent a one-to-one mapping) - */ + /** + * Note: resulting instances are law-abiding only when the functions used are injective (represent a one-to-one mapping) + */ def unit: Ordering[Unit] = Order[Unit].toOrdering def contramap[A, B](fa: Ordering[A])(f: B => A): Ordering[B] = fa.on(f) diff --git a/core/src/main/scala/cats/instances/package.scala b/core/src/main/scala/cats/instances/package.scala index 6085a858755..e32d519d53e 100644 --- a/core/src/main/scala/cats/instances/package.scala +++ b/core/src/main/scala/cats/instances/package.scala @@ -1,43 +1,43 @@ package cats package object instances { - object all extends AllInstances with AllInstancesBinCompat0 with AllInstancesBinCompat1 with AllInstancesBinCompat2 - object bigInt extends BigIntInstances - object bigDecimal extends BigDecimalInstances - object bitSet extends BitSetInstances - object boolean extends BooleanInstances - object byte extends ByteInstances - object char extends CharInstances - object double extends DoubleInstances - object duration extends DurationInstances - object either extends EitherInstances - object eq extends EqInstances - object equiv extends EquivInstances - object float extends FloatInstances - object finiteDuration extends FiniteDurationInstances - object function extends FunctionInstances with FunctionInstancesBinCompat0 - object future extends FutureInstances - object int extends IntInstances - object invariant extends InvariantMonoidalInstances - object list extends ListInstances with ListInstancesBinCompat0 - object long extends LongInstances - object option extends OptionInstances with OptionInstancesBinCompat0 - object map extends MapInstances with MapInstancesBinCompat0 - object order extends OrderInstances - object ordering extends OrderingInstances - object parallel extends ParallelInstances - object partialOrder extends PartialOrderInstances + object all extends AllInstances with AllInstancesBinCompat0 with AllInstancesBinCompat1 with AllInstancesBinCompat2 + object bigInt extends BigIntInstances + object bigDecimal extends BigDecimalInstances + object bitSet extends BitSetInstances + object boolean extends BooleanInstances + object byte extends ByteInstances + object char extends CharInstances + object double extends DoubleInstances + object duration extends DurationInstances + object either extends EitherInstances + object eq extends EqInstances + object equiv extends EquivInstances + object float extends FloatInstances + object finiteDuration extends FiniteDurationInstances + object function extends FunctionInstances with FunctionInstancesBinCompat0 + object future extends FutureInstances + object int extends IntInstances + object invariant extends InvariantMonoidalInstances + object list extends ListInstances with ListInstancesBinCompat0 + object long extends LongInstances + object option extends OptionInstances with OptionInstancesBinCompat0 + object map extends MapInstances with MapInstancesBinCompat0 + object order extends OrderInstances + object ordering extends OrderingInstances + object parallel extends ParallelInstances + object partialOrder extends PartialOrderInstances object partialOrdering extends PartialOrderingInstances - object queue extends QueueInstances - object set extends SetInstances - object short extends ShortInstances - object sortedMap extends SortedMapInstances - object sortedSet extends SortedSetInstances - object stream extends StreamInstances with StreamInstancesBinCompat0 - object string extends StringInstances - object try_ extends TryInstances - object tuple extends TupleInstances with Tuple2InstancesBinCompat0 - object unit extends UnitInstances - object uuid extends UUIDInstances - object vector extends VectorInstances with VectorInstancesBinCompat0 + object queue extends QueueInstances + object set extends SetInstances + object short extends ShortInstances + object sortedMap extends SortedMapInstances + object sortedSet extends SortedSetInstances + object stream extends StreamInstances with StreamInstancesBinCompat0 + object string extends StringInstances + object try_ extends TryInstances + object tuple extends TupleInstances with Tuple2InstancesBinCompat0 + object unit extends UnitInstances + object uuid extends UUIDInstances + object vector extends VectorInstances with VectorInstancesBinCompat0 } diff --git a/core/src/main/scala/cats/instances/parallel.scala b/core/src/main/scala/cats/instances/parallel.scala index e45f666fc14..5240b8c54b4 100644 --- a/core/src/main/scala/cats/instances/parallel.scala +++ b/core/src/main/scala/cats/instances/parallel.scala @@ -3,24 +3,25 @@ package cats.instances import cats.data._ import cats.kernel.Semigroup import cats.syntax.either._ -import cats.{Applicative, Apply, FlatMap, Functor, Monad, NonEmptyParallel, Parallel, ~>} - +import cats.{~>, Applicative, Apply, FlatMap, Functor, Monad, NonEmptyParallel, Parallel} trait ParallelInstances extends ParallelInstances1 { - implicit def catsParallelForEitherValidated[E: Semigroup]: Parallel[Either[E, ?], Validated[E, ?]] = new Parallel[Either[E, ?], Validated[E, ?]] { + implicit def catsParallelForEitherValidated[E: Semigroup]: Parallel[Either[E, ?], Validated[E, ?]] = + new Parallel[Either[E, ?], Validated[E, ?]] { - def applicative: Applicative[Validated[E, ?]] = Validated.catsDataApplicativeErrorForValidated - def monad: Monad[Either[E, ?]] = cats.instances.either.catsStdInstancesForEither + def applicative: Applicative[Validated[E, ?]] = Validated.catsDataApplicativeErrorForValidated + def monad: Monad[Either[E, ?]] = cats.instances.either.catsStdInstancesForEither - def sequential: Validated[E, ?] ~> Either[E, ?] = - λ[Validated[E, ?] ~> Either[E, ?]](_.toEither) + def sequential: Validated[E, ?] ~> Either[E, ?] = + λ[Validated[E, ?] ~> Either[E, ?]](_.toEither) - def parallel: Either[E, ?] ~> Validated[E, ?] = - λ[Either[E, ?] ~> Validated[E, ?]](_.toValidated) - } + def parallel: Either[E, ?] ~> Validated[E, ?] = + λ[Either[E, ?] ~> Validated[E, ?]](_.toValidated) + } - implicit def catsParallelForOptionTNestedOption[F[_], M[_]] - (implicit P: Parallel[M, F]): Parallel[OptionT[M, ?], Nested[F, Option, ?]] = new Parallel[OptionT[M, ?], Nested[F, Option, ?]] { + implicit def catsParallelForOptionTNestedOption[F[_], M[_]]( + implicit P: Parallel[M, F] + ): Parallel[OptionT[M, ?], Nested[F, Option, ?]] = new Parallel[OptionT[M, ?], Nested[F, Option, ?]] { implicit val appF: Applicative[F] = P.applicative implicit val monadM: Monad[M] = P.monad @@ -33,7 +34,7 @@ trait ParallelInstances extends ParallelInstances1 { def sequential: Nested[F, Option, ?] ~> OptionT[M, ?] = λ[Nested[F, Option, ?] ~> OptionT[M, ?]](nested => OptionT(P.sequential(nested.value))) - def parallel: OptionT[M, ?]~> Nested[F, Option, ?] = + def parallel: OptionT[M, ?] ~> Nested[F, Option, ?] = λ[OptionT[M, ?] ~> Nested[F, Option, ?]](optT => Nested(P.parallel(optT.value))) } @@ -76,42 +77,45 @@ trait ParallelInstances extends ParallelInstances1 { λ[Stream ~> ZipStream](v => new ZipStream(v)) } - - implicit def catsParallelForEitherTNestedParallelValidated[F[_], M[_], E: Semigroup] - (implicit P: Parallel[M, F]): Parallel[EitherT[M, E, ?], Nested[F, Validated[E, ?], ?]] = + implicit def catsParallelForEitherTNestedParallelValidated[F[_], M[_], E: Semigroup]( + implicit P: Parallel[M, F] + ): Parallel[EitherT[M, E, ?], Nested[F, Validated[E, ?], ?]] = new Parallel[EitherT[M, E, ?], Nested[F, Validated[E, ?], ?]] { - implicit val appF: Applicative[F] = P.applicative - implicit val monadM: Monad[M] = P.monad - implicit val appValidated: Applicative[Validated[E, ?]] = Validated.catsDataApplicativeErrorForValidated - implicit val monadEither: Monad[Either[E, ?]] = cats.instances.either.catsStdInstancesForEither + implicit val appF: Applicative[F] = P.applicative + implicit val monadM: Monad[M] = P.monad + implicit val appValidated: Applicative[Validated[E, ?]] = Validated.catsDataApplicativeErrorForValidated + implicit val monadEither: Monad[Either[E, ?]] = cats.instances.either.catsStdInstancesForEither - def applicative: Applicative[Nested[F, Validated[E, ?], ?]] = cats.data.Nested.catsDataApplicativeForNested[F, Validated[E, ?]] + def applicative: Applicative[Nested[F, Validated[E, ?], ?]] = + cats.data.Nested.catsDataApplicativeForNested[F, Validated[E, ?]] - def monad: Monad[EitherT[M, E, ?]] = cats.data.EitherT.catsDataMonadErrorForEitherT + def monad: Monad[EitherT[M, E, ?]] = cats.data.EitherT.catsDataMonadErrorForEitherT - def sequential: Nested[F, Validated[E, ?], ?] ~> EitherT[M, E, ?] = - λ[Nested[F, Validated[E, ?], ?] ~> EitherT[M, E, ?]] { nested => - val mva = P.sequential(nested.value) - EitherT(Functor[M].map(mva)(_.toEither)) - } + def sequential: Nested[F, Validated[E, ?], ?] ~> EitherT[M, E, ?] = + λ[Nested[F, Validated[E, ?], ?] ~> EitherT[M, E, ?]] { nested => + val mva = P.sequential(nested.value) + EitherT(Functor[M].map(mva)(_.toEither)) + } - def parallel: EitherT[M, E, ?]~> Nested[F, Validated[E, ?], ?] = - λ[EitherT[M, E, ?] ~> Nested[F, Validated[E, ?], ?]] { eitherT => - val fea = P.parallel(eitherT.value) - Nested(Functor[F].map(fea)(_.toValidated)) - } - } + def parallel: EitherT[M, E, ?] ~> Nested[F, Validated[E, ?], ?] = + λ[EitherT[M, E, ?] ~> Nested[F, Validated[E, ?], ?]] { eitherT => + val fea = P.parallel(eitherT.value) + Nested(Functor[F].map(fea)(_.toValidated)) + } + } } private[instances] trait ParallelInstances1 { - implicit def catsParallelForEitherTNestedValidated[M[_]: Monad, E: Semigroup]: Parallel[EitherT[M, E, ?], Nested[M, Validated[E, ?], ?]] = + implicit def catsParallelForEitherTNestedValidated[M[_]: Monad, E: Semigroup] + : Parallel[EitherT[M, E, ?], Nested[M, Validated[E, ?], ?]] = new Parallel[EitherT[M, E, ?], Nested[M, Validated[E, ?], ?]] { implicit val appValidated: Applicative[Validated[E, ?]] = Validated.catsDataApplicativeErrorForValidated implicit val monadEither: Monad[Either[E, ?]] = cats.instances.either.catsStdInstancesForEither - def applicative: Applicative[Nested[M, Validated[E, ?], ?]] = cats.data.Nested.catsDataApplicativeForNested[M, Validated[E, ?]] + def applicative: Applicative[Nested[M, Validated[E, ?], ?]] = + cats.data.Nested.catsDataApplicativeForNested[M, Validated[E, ?]] def monad: Monad[EitherT[M, E, ?]] = cats.data.EitherT.catsDataMonadErrorForEitherT @@ -120,7 +124,7 @@ private[instances] trait ParallelInstances1 { EitherT(Monad[M].map(nested.value)(_.toEither)) } - def parallel: EitherT[M, E, ?]~> Nested[M, Validated[E, ?], ?] = + def parallel: EitherT[M, E, ?] ~> Nested[M, Validated[E, ?], ?] = λ[EitherT[M, E, ?] ~> Nested[M, Validated[E, ?], ?]] { eitherT => Nested(Monad[M].map(eitherT.value)(_.toValidated)) } diff --git a/core/src/main/scala/cats/instances/partialOrder.scala b/core/src/main/scala/cats/instances/partialOrder.scala index 5f9949eb552..b3cb14e191b 100644 --- a/core/src/main/scala/cats/instances/partialOrder.scala +++ b/core/src/main/scala/cats/instances/partialOrder.scala @@ -2,14 +2,14 @@ package cats package instances import cats.kernel.instances.unit._ - trait PartialOrderInstances extends kernel.instances.PartialOrderInstances { implicit val catsContravariantMonoidalForPartialOrder: ContravariantMonoidal[PartialOrder] = new ContravariantMonoidal[PartialOrder] { + /** Derive a `PartialOrder` for `B` given a `PartialOrder[A]` and a function `B => A`. - * - * Note: resulting instances are law-abiding only when the functions used are injective (represent a one-to-one mapping) - */ + * + * Note: resulting instances are law-abiding only when the functions used are injective (represent a one-to-one mapping) + */ def contramap[A, B](fa: PartialOrder[A])(f: B => A): PartialOrder[B] = PartialOrder.by[B, A](f)(fa) def product[A, B](fa: PartialOrder[A], fb: PartialOrder[B]): PartialOrder[(A, B)] = diff --git a/core/src/main/scala/cats/instances/partialOrdering.scala b/core/src/main/scala/cats/instances/partialOrdering.scala index 3560286635a..4fb9364eea8 100644 --- a/core/src/main/scala/cats/instances/partialOrdering.scala +++ b/core/src/main/scala/cats/instances/partialOrdering.scala @@ -4,10 +4,11 @@ package instances trait PartialOrderingInstances { implicit val catsContravariantMonoidalForPartialOrdering: ContravariantMonoidal[PartialOrdering] = new ContravariantMonoidal[PartialOrdering] { + /** Derive a `PartialOrdering` for `B` given a `PartialOrdering[A]` and a function `B => A`. - * - * Note: resulting instances are law-abiding only when the functions used are injective (represent a one-to-one mapping) - */ + * + * Note: resulting instances are law-abiding only when the functions used are injective (represent a one-to-one mapping) + */ def contramap[A, B](fa: PartialOrdering[A])(f: B => A): PartialOrdering[B] = new PartialOrdering[B] { def lteq(x: B, y: B): Boolean = fa.lteq(f(x), f(y)) @@ -21,7 +22,7 @@ trait PartialOrderingInstances { def tryCompare(x: (A, B), y: (A, B)): Option[Int] = fa.tryCompare(x._1, y._1) match { case Some(0) => fb.tryCompare(x._2, y._2) - case option => option + case option => option } } diff --git a/core/src/main/scala/cats/instances/queue.scala b/core/src/main/scala/cats/instances/queue.scala index ca89bc8a248..aebedd10de2 100644 --- a/core/src/main/scala/cats/instances/queue.scala +++ b/core/src/main/scala/cats/instances/queue.scala @@ -8,7 +8,8 @@ import scala.util.Try trait QueueInstances extends cats.kernel.instances.QueueInstances { - implicit val catsStdInstancesForQueue: Traverse[Queue] with Alternative[Queue] with Monad[Queue] with CoflatMap[Queue] = + implicit val catsStdInstancesForQueue + : Traverse[Queue] with Alternative[Queue] with Monad[Queue] with CoflatMap[Queue] = new Traverse[Queue] with Alternative[Queue] with Monad[Queue] with CoflatMap[Queue] { def empty[A]: Queue[A] = Queue.empty @@ -40,7 +41,7 @@ trait QueueInstances extends cats.kernel.instances.QueueInstances { val (e, es) = q.dequeue e match { case Right(b) => bldr += b; go(es :: tail) - case Left(a) => go(f(a) :: es :: tail) + case Left(a) => go(f(a) :: es :: tail) } } case Nil => @@ -78,7 +79,7 @@ trait QueueInstances extends cats.kernel.instances.QueueInstances { B.combineAll(fa.iterator.map(f)) def traverse[G[_], A, B](fa: Queue[A])(f: A => G[B])(implicit G: Applicative[G]): G[Queue[B]] = - foldRight[A, G[Queue[B]]](fa, Always(G.pure(Queue.empty))){ (a, lglb) => + foldRight[A, G[Queue[B]]](fa, Always(G.pure(Queue.empty))) { (a, lglb) => G.map2Eval(f(a), lglb)(_ +: _) }.value @@ -109,7 +110,9 @@ trait QueueInstances extends cats.kernel.instances.QueueInstances { if (xs.isEmpty) G.pure(Right(b)) else { val (a, tail) = xs.dequeue - G.map(f(b, a)) { bnext => Left((tail, bnext)) } + G.map(f(b, a)) { bnext => + Left((tail, bnext)) + } } } @@ -140,10 +143,11 @@ trait QueueInstances extends cats.kernel.instances.QueueInstances { override def collectFirst[A, B](fa: Queue[A])(pf: PartialFunction[A, B]): Option[B] = fa.collectFirst(pf) - override def collectFirstSome[A, B](fa: Queue[A])(f: A => Option[B]): Option[B] = fa.collectFirst(Function.unlift(f)) + override def collectFirstSome[A, B](fa: Queue[A])(f: A => Option[B]): Option[B] = + fa.collectFirst(Function.unlift(f)) } - implicit def catsStdShowForQueue[A:Show]: Show[Queue[A]] = + implicit def catsStdShowForQueue[A: Show]: Show[Queue[A]] = new Show[Queue[A]] { def show(fa: Queue[A]): String = fa.iterator.map(_.show).mkString("Queue(", ", ", ")") diff --git a/core/src/main/scala/cats/instances/set.scala b/core/src/main/scala/cats/instances/set.scala index 0343f5ae978..ba62b96b632 100644 --- a/core/src/main/scala/cats/instances/set.scala +++ b/core/src/main/scala/cats/instances/set.scala @@ -35,7 +35,7 @@ trait SetInstances extends cats.kernel.instances.SetInstances { override def isEmpty[A](fa: Set[A]): Boolean = fa.isEmpty } - implicit def catsStdShowForSet[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/instances/sortedMap.scala b/core/src/main/scala/cats/instances/sortedMap.scala index b3d83a4e92f..37239fb8cc2 100644 --- a/core/src/main/scala/cats/instances/sortedMap.scala +++ b/core/src/main/scala/cats/instances/sortedMap.scala @@ -12,7 +12,8 @@ trait SortedMapInstances extends SortedMapInstances2 { implicit def catsStdHashForSortedMap[K: Hash: Order, V: Hash]: Hash[SortedMap[K, V]] = new SortedMapHash[K, V] - implicit def catsStdCommutativeMonoidForSortedMap[K: Order, V: CommutativeSemigroup]: CommutativeMonoid[SortedMap[K, V]] = + implicit def catsStdCommutativeMonoidForSortedMap[K: Order, V: CommutativeSemigroup] + : CommutativeMonoid[SortedMap[K, V]] = new SortedMapCommutativeMonoid[K, V] implicit def catsStdShowForSortedMap[A: Order, B](implicit showA: Show[A], showB: Show[B]): Show[SortedMap[A, B]] = @@ -31,9 +32,13 @@ trait SortedMapInstances extends SortedMapInstances2 { def traverse[G[_], A, B](fa: SortedMap[K, A])(f: A => G[B])(implicit G: Applicative[G]): G[SortedMap[K, B]] = { val gba: Eval[G[SortedMap[K, B]]] = Always(G.pure(SortedMap.empty(Order[K].toOrdering))) - Foldable.iterateRight(fa, gba){ (kv, lbuf) => - G.map2Eval(f(kv._2), lbuf)({ (b, buf) => buf + (kv._1 -> b)}) - }.value + Foldable + .iterateRight(fa, gba) { (kv, lbuf) => + G.map2Eval(f(kv._2), lbuf)({ (b, buf) => + buf + (kv._1 -> b) + }) + } + .value } def flatMap[A, B](fa: SortedMap[K, A])(f: A => SortedMap[K, B]): SortedMap[K, B] = @@ -42,18 +47,20 @@ trait SortedMapInstances extends SortedMapInstances2 { override def map[A, B](fa: SortedMap[K, A])(f: A => B): SortedMap[K, B] = fa.map { case (k, a) => (k, f(a)) } - - override def map2Eval[A, B, Z](fa: SortedMap[K, A], fb: Eval[SortedMap[K, B]])(f: (A, B) => Z): Eval[SortedMap[K, Z]] = + override def map2Eval[A, B, Z](fa: SortedMap[K, A], + fb: Eval[SortedMap[K, B]])(f: (A, B) => Z): Eval[SortedMap[K, Z]] = if (fa.isEmpty) Eval.now(SortedMap.empty(Order[K].toOrdering)) // no need to evaluate fb else fb.map(fb => map2(fa, fb)(f)) - override def ap2[A, B, Z](f: SortedMap[K, (A, B) => Z])(fa: SortedMap[K, A], fb: SortedMap[K, B]): SortedMap[K, Z] = - f.flatMap { case (k, f) => - for { a <- fa.get(k); b <- fb.get(k) } yield (k, f(a, b)) + override def ap2[A, B, Z](f: SortedMap[K, (A, B) => Z])(fa: SortedMap[K, A], + fb: SortedMap[K, B]): SortedMap[K, Z] = + f.flatMap { + case (k, f) => + for { a <- fa.get(k); b <- fb.get(k) } yield (k, f(a, b)) } def foldLeft[A, B](fa: SortedMap[K, A], b: B)(f: (B, A) => B): B = - fa.foldLeft(b) { case (x, (k, a)) => f(x, a)} + fa.foldLeft(b) { case (x, (k, a)) => f(x, a) } def foldRight[A, B](fa: SortedMap[K, A], lb: Eval[B])(f: (A, Eval[B]) => Eval[B]): Eval[B] = Foldable.iterateRight(fa.values, lb)(f) @@ -66,7 +73,7 @@ trait SortedMapInstances extends SortedMapInstances2 { case Left(a) => f(a).get(k) match { case Some(x) => descend(k, x) - case None => () + case None => () } case Right(b) => bldr += ((k, b)) @@ -94,12 +101,14 @@ trait SortedMapInstances extends SortedMapInstances2 { override def toList[A](fa: SortedMap[K, A]): List[A] = fa.values.toList - override def collectFirst[A, B](fa: SortedMap[K, A])(pf: PartialFunction[A, B]): Option[B] = fa.collectFirst(new PartialFunction[(K, A), B] { - override def isDefinedAt(x: (K, A)) = pf.isDefinedAt(x._2) - override def apply(v1: (K, A)) = pf(v1._2) - }) + override def collectFirst[A, B](fa: SortedMap[K, A])(pf: PartialFunction[A, B]): Option[B] = + fa.collectFirst(new PartialFunction[(K, A), B] { + override def isDefinedAt(x: (K, A)) = pf.isDefinedAt(x._2) + override def apply(v1: (K, A)) = pf(v1._2) + }) - override def collectFirstSome[A, B](fa: SortedMap[K, A])(f: A => Option[B]): Option[B] = collectFirst(fa)(Function.unlift(f)) + override def collectFirstSome[A, B](fa: SortedMap[K, A])(f: A => Option[B]): Option[B] = + collectFirst(fa)(Function.unlift(f)) } } @@ -114,19 +123,22 @@ trait SortedMapInstances2 extends SortedMapInstances1 { new SortedMapMonoid[K, V] } -class SortedMapHash[K, V](implicit V: Hash[V], O: Order[K], K: Hash[K]) extends SortedMapEq[K, V]()(V, O) with Hash[SortedMap[K, V]] { +class SortedMapHash[K, V](implicit V: Hash[V], O: Order[K], K: Hash[K]) + extends SortedMapEq[K, V]()(V, O) + with Hash[SortedMap[K, V]] { // adapted from [[scala.util.hashing.MurmurHash3]], // but modified standard `Any#hashCode` to `ev.hash`. import scala.util.hashing.MurmurHash3._ def hash(x: SortedMap[K, V]): Int = { var a, b, n = 0 var c = 1 - x foreach { case (k, v) => - val h = StaticMethods.product2Hash(K.hash(k), V.hash(v)) - a += h - b ^= h - if (h != 0) c *= h - n += 1 + x.foreach { + case (k, v) => + val h = StaticMethods.product2Hash(K.hash(k), V.hash(v)) + a += h + b ^= h + if (h != 0) c *= h + n += 1 } var h = mapSeed h = mix(h, a) @@ -139,29 +151,34 @@ class SortedMapHash[K, V](implicit V: Hash[V], O: Order[K], K: Hash[K]) extends class SortedMapEq[K, V](implicit V: Eq[V], O: Order[K]) extends Eq[SortedMap[K, V]] { def eqv(x: SortedMap[K, V], y: SortedMap[K, V]): Boolean = if (x eq y) true - else x.size == y.size && x.forall { case (k, v1) => - y.get(k) match { - case Some(v2) => V.eqv(v1, v2) - case None => false + else + x.size == y.size && x.forall { + case (k, v1) => + y.get(k) match { + case Some(v2) => V.eqv(v1, v2) + case None => false + } } - } } class SortedMapCommutativeMonoid[K, V](implicit V: CommutativeSemigroup[V], O: Order[K]) - extends SortedMapMonoid[K, V] with CommutativeMonoid[SortedMap[K, V]] + extends SortedMapMonoid[K, V] + with CommutativeMonoid[SortedMap[K, V]] -class SortedMapMonoid[K, V](implicit V: Semigroup[V], O: Order[K]) extends Monoid[SortedMap[K, V]] { +class SortedMapMonoid[K, V](implicit V: Semigroup[V], O: Order[K]) extends Monoid[SortedMap[K, V]] { def empty: SortedMap[K, V] = SortedMap.empty(O.toOrdering) def combine(xs: SortedMap[K, V], ys: SortedMap[K, V]): SortedMap[K, V] = if (xs.size <= ys.size) { - xs.foldLeft(ys) { case (my, (k, x)) => - my.updated(k, Semigroup.maybeCombine(x, my.get(k))) + xs.foldLeft(ys) { + case (my, (k, x)) => + my.updated(k, Semigroup.maybeCombine(x, my.get(k))) } } else { - ys.foldLeft(xs) { case (mx, (k, y)) => - mx.updated(k, Semigroup.maybeCombine(mx.get(k), y)) + ys.foldLeft(xs) { + case (mx, (k, y)) => + mx.updated(k, Semigroup.maybeCombine(mx.get(k), y)) } } @@ -175,14 +192,17 @@ trait SortedMapInstancesBinCompat0 { val traverse: Traverse[SortedMap[K, ?]] = cats.instances.sortedMap.catsStdInstancesForSortedMap[K] - override def traverseFilter[G[_], A, B] - (fa: SortedMap[K, A]) - (f: A => G[Option[B]]) - (implicit G: Applicative[G]): G[SortedMap[K, B]] = { + override def traverseFilter[G[_], A, B]( + fa: SortedMap[K, A] + )(f: A => G[Option[B]])(implicit G: Applicative[G]): G[SortedMap[K, B]] = { val gba: Eval[G[SortedMap[K, B]]] = Always(G.pure(SortedMap.empty)) - Foldable.iterateRight(fa, gba) { (kv, lbuf) => - G.map2Eval(f(kv._2), lbuf)({ (ob, buf) => ob.fold(buf)(b => buf + (kv._1 -> b)) }) - }.value + Foldable + .iterateRight(fa, gba) { (kv, lbuf) => + G.map2Eval(f(kv._2), lbuf)({ (ob, buf) => + ob.fold(buf)(b => buf + (kv._1 -> b)) + }) + } + .value } override def mapFilter[A, B](fa: SortedMap[K, A])(f: (A) => Option[B]): SortedMap[K, B] = @@ -197,11 +217,9 @@ trait SortedMapInstancesBinCompat0 { override def filter[A](fa: SortedMap[K, A])(f: (A) => Boolean): SortedMap[K, A] = fa.filter { case (_, v) => f(v) } - - override def filterA[G[_], A] - (fa: SortedMap[K, A]) - (f: (A) => G[Boolean]) - (implicit G: Applicative[G]): G[SortedMap[K, A]] = + override def filterA[G[_], A]( + fa: SortedMap[K, A] + )(f: (A) => G[Boolean])(implicit G: Applicative[G]): G[SortedMap[K, A]] = traverseFilter(fa)(a => G.map(f(a))(if (_) Some(a) else None)) } } diff --git a/core/src/main/scala/cats/instances/sortedSet.scala b/core/src/main/scala/cats/instances/sortedSet.scala index f30aff1ec9a..dce7fe8359a 100644 --- a/core/src/main/scala/cats/instances/sortedSet.scala +++ b/core/src/main/scala/cats/instances/sortedSet.scala @@ -24,15 +24,15 @@ trait SortedSetInstances extends SortedSetInstances1 { override def get[A](fa: SortedSet[A])(idx: Long): Option[A] = { @tailrec - def go(idx: Int, it: Iterator[A]): Option[A] = { + def go(idx: Int, it: Iterator[A]): Option[A] = if (it.hasNext) { - if (idx == 0) Some(it.next) else { + if (idx == 0) Some(it.next) + else { it.next go(idx - 1, it) } } else None - } - if (idx < Int.MaxValue && idx >= 0L) go(idx.toInt, fa.toIterator) else None + if (idx < Int.MaxValue && idx >= 0L) go(idx.toInt, fa.toIterator) else None } override def size[A](fa: SortedSet[A]): Long = fa.size.toLong @@ -79,13 +79,11 @@ trait SortedSetInstances1 { } class SortedSetOrder[A: Order] extends Order[SortedSet[A]] { - def compare(a1: SortedSet[A], a2: SortedSet[A]): Int = { - + def compare(a1: SortedSet[A], a2: SortedSet[A]): Int = Order[Int].compare(a1.size, a2.size) match { case 0 => Order.compare(a1.toStream, a2.toStream) case x => x } - } override def eqv(s1: SortedSet[A], s2: SortedSet[A]): Boolean = { implicit val x = Order[A].toOrdering @@ -101,7 +99,7 @@ class SortedSetHash[A: Order: Hash] extends Hash[SortedSet[A]] { def hash(xs: SortedSet[A]): Int = { var a, b, n = 0 var c = 1 - xs foreach { x => + xs.foreach { x => val h = Hash[A].hash(x) a += h b ^= h @@ -124,4 +122,3 @@ class SortedSetSemilattice[A: Order] extends BoundedSemilattice[SortedSet[A]] { def empty: SortedSet[A] = SortedSet.empty(implicitly[Order[A]].toOrdering) def combine(x: SortedSet[A], y: SortedSet[A]): SortedSet[A] = x | y } - diff --git a/core/src/main/scala/cats/instances/stream.scala b/core/src/main/scala/cats/instances/stream.scala index 1d97c90fb03..e8c38a50acc 100644 --- a/core/src/main/scala/cats/instances/stream.scala +++ b/core/src/main/scala/cats/instances/stream.scala @@ -6,7 +6,8 @@ import cats.syntax.show._ import scala.annotation.tailrec trait StreamInstances extends cats.kernel.instances.StreamInstances { - implicit val catsStdInstancesForStream: Traverse[Stream] with Alternative[Stream] with Monad[Stream] with CoflatMap[Stream] = + implicit val catsStdInstancesForStream + : Traverse[Stream] with Alternative[Stream] with Monad[Stream] with CoflatMap[Stream] = new Traverse[Stream] with Alternative[Stream] with Monad[Stream] with CoflatMap[Stream] { def empty[A]: Stream[A] = Stream.Empty @@ -45,14 +46,13 @@ trait StreamInstances extends cats.kernel.instances.StreamInstances { override def foldMap[A, B](fa: Stream[A])(f: A => B)(implicit B: Monoid[B]): B = B.combineAll(fa.iterator.map(f)) - def traverse[G[_], A, B](fa: Stream[A])(f: A => G[B])(implicit G: Applicative[G]): G[Stream[B]] = { + def traverse[G[_], A, B](fa: Stream[A])(f: A => G[B])(implicit G: Applicative[G]): G[Stream[B]] = // We use foldRight to avoid possible stack overflows. Since // we don't want to return a Eval[_] instance, we call .value // at the end. - foldRight(fa, Always(G.pure(Stream.empty[B]))){ (a, lgsb) => + foldRight(fa, Always(G.pure(Stream.empty[B]))) { (a, lgsb) => G.map2Eval(f(a), lgsb)(_ #:: _) }.value - } override def mapWithIndex[A, B](fa: Stream[A])(f: (A, Int) => B): Stream[B] = fa.zipWithIndex.map(ai => f(ai._1, ai._2)) @@ -122,11 +122,13 @@ trait StreamInstances extends cats.kernel.instances.StreamInstances { override def foldM[G[_], A, B](fa: Stream[A], z: B)(f: (B, A) => G[B])(implicit G: Monad[G]): G[B] = { def step(in: (Stream[A], B)): G[Either[(Stream[A], B), B]] = { - val (s, b) = in + val (s, b) = in if (s.isEmpty) G.pure(Right(b)) else - G.map(f(b, s.head)) { bnext => Left((s.tail, bnext)) } + G.map(f(b, s.head)) { bnext => + Left((s.tail, bnext)) + } } G.tailRecM((fa, z))(step) @@ -145,7 +147,8 @@ trait StreamInstances extends cats.kernel.instances.StreamInstances { override def collectFirst[A, B](fa: Stream[A])(pf: PartialFunction[A, B]): Option[B] = fa.collectFirst(pf) - override def collectFirstSome[A, B](fa: Stream[A])(f: A => Option[B]): Option[B] = fa.collectFirst(Function.unlift(f)) + override def collectFirstSome[A, B](fa: Stream[A])(f: A => Option[B]): Option[B] = + fa.collectFirst(Function.unlift(f)) } implicit def catsStdShowForStream[A: Show]: Show[Stream[A]] = @@ -158,9 +161,8 @@ trait StreamInstancesBinCompat0 { implicit val catsStdTraverseFilterForStream: TraverseFilter[Stream] = new TraverseFilter[Stream] { val traverse: Traverse[Stream] = cats.instances.stream.catsStdInstancesForStream - override def mapFilter[A, B](fa: Stream[A])(f: (A) => Option[B]): Stream[B] = { + override def mapFilter[A, B](fa: Stream[A])(f: (A) => Option[B]): Stream[B] = fa.collect(Function.unlift(f)) - } override def filter[A](fa: Stream[A])(f: (A) => Boolean): Stream[A] = fa.filter(f) @@ -168,17 +170,17 @@ trait StreamInstancesBinCompat0 { override def flattenOption[A](fa: Stream[Option[A]]): Stream[A] = fa.flatten - def traverseFilter[G[_], A, B](fa: Stream[A])(f: (A) => G[Option[B]])(implicit G: Applicative[G]): G[Stream[B]] = { + def traverseFilter[G[_], A, B](fa: Stream[A])(f: (A) => G[Option[B]])(implicit G: Applicative[G]): G[Stream[B]] = fa.foldRight(Eval.now(G.pure(Stream.empty[B])))( - (x, xse) => G.map2Eval(f(x), xse)((i, o) => i.fold(o)(_ +: o)) - ).value - } + (x, xse) => G.map2Eval(f(x), xse)((i, o) => i.fold(o)(_ +: o)) + ) + .value - override def filterA[G[_], A](fa: Stream[A])(f: (A) => G[Boolean])(implicit G: Applicative[G]): G[Stream[A]] = { + override def filterA[G[_], A](fa: Stream[A])(f: (A) => G[Boolean])(implicit G: Applicative[G]): G[Stream[A]] = fa.foldRight(Eval.now(G.pure(Stream.empty[A])))( - (x, xse) => G.map2Eval(f(x), xse)((b, as) => if (b) x +: as else as) - ).value - } + (x, xse) => G.map2Eval(f(x), xse)((b, as) => if (b) x +: as else as) + ) + .value } } diff --git a/core/src/main/scala/cats/instances/try.scala b/core/src/main/scala/cats/instances/try.scala index 31f86985525..ce01ef1c5c4 100644 --- a/core/src/main/scala/cats/instances/try.scala +++ b/core/src/main/scala/cats/instances/try.scala @@ -10,26 +10,27 @@ import scala.annotation.tailrec trait TryInstances extends TryInstances1 { // scalastyle:off method.length - implicit def catsStdInstancesForTry: MonadError[Try, Throwable] with CoflatMap[Try] with Traverse[Try] with Monad[Try] = + implicit def catsStdInstancesForTry + : MonadError[Try, Throwable] with CoflatMap[Try] with Traverse[Try] with Monad[Try] = new TryCoflatMap with MonadError[Try, Throwable] with Traverse[Try] with Monad[Try] { def pure[A](x: A): Try[A] = Success(x) 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[_], _) => castFailure[(A, B)](f) - case (_, f: Failure[_]) => castFailure[(A, B)](f) + case (f: Failure[_], _) => castFailure[(A, B)](f) + case (_, f: Failure[_]) => castFailure[(A, B)](f) } 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[_], _) => castFailure[Z](f) - case (_, f: Failure[_]) => castFailure[Z](f) + case (f: Failure[_], _) => castFailure[Z](f) + case (_, f: Failure[_]) => castFailure[Z](f) } 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(castFailure[Z](f)) - case Success(a) => tb.map(_.map(f(a, _))) + case Success(a) => tb.map(_.map(f(a, _))) } def flatMap[A, B](ta: Try[A])(f: A => Try[B]): Try[B] = ta.flatMap(f) @@ -48,13 +49,13 @@ trait TryInstances extends TryInstances1 { def traverse[G[_], A, B](fa: Try[A])(f: A => G[B])(implicit G: Applicative[G]): G[Try[B]] = fa match { - case Success(a) => G.map(f(a))(Success(_)) + case Success(a) => G.map(f(a))(Success(_)) case f: Failure[_] => G.pure(castFailure[B](f)) } @tailrec final def tailRecM[B, C](b: B)(f: B => Try[Either[B, C]]): Try[C] = f(b) match { - case f: Failure[_] => castFailure[C](f) + case f: Failure[_] => castFailure[C](f) case Success(Left(b1)) => tailRecM(b1)(f) case Success(Right(c)) => Success(c) } @@ -68,7 +69,7 @@ trait TryInstances extends TryInstances1 { ta.recover { case t => f(t) } override def attempt[A](ta: Try[A]): Try[Either[Throwable, A]] = - (ta.map(a => Right[Throwable, A](a))) recover { case NonFatal(t) => Left(t) } + (ta.map(a => Right[Throwable, A](a))).recover { case NonFatal(t) => Left(t) } override def recover[A](ta: Try[A])(pf: PartialFunction[Throwable, A]): Try[A] = ta.recover(pf) @@ -138,44 +139,47 @@ trait TryInstances extends TryInstances1 { case Failure(e) => s"Failure($e)" } } + /** - * 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 - */ + * you may wish to do equality by making `implicit val eqT: Eq[Throwable] = Eq.allEqual` + * doing a fine grained equality on Throwable can make the code very execution + * order dependent + */ implicit def catsStdEqForTry[A, T](implicit A: Eq[A], T: Eq[Throwable]): Eq[Try[A]] = new Eq[Try[A]] { def eqv(x: Try[A], y: Try[A]): Boolean = (x, y) match { case (Success(a), Success(b)) => A.eqv(a, b) case (Failure(a), Failure(b)) => T.eqv(a, b) - case _ => false + case _ => false } } } private[instances] object TryInstances { + /** - * A `Failure` can be statically typed as `Try[A]` for all `A`, because it - * does not actually contain an `A` value (as `Success[A]` does). - */ + * A `Failure` can be statically typed as `Try[A]` for all `A`, because it + * does not actually contain an `A` value (as `Success[A]` does). + */ @inline final def castFailure[A](f: Failure[_]): Try[A] = f.asInstanceOf[Try[A]] } -private[instances] sealed trait TryInstances1 extends TryInstances2 { +sealed private[instances] trait TryInstances1 extends TryInstances2 { implicit def catsStdMonoidForTry[A: Monoid]: Monoid[Try[A]] = new TryMonoid[A] } -private[instances] sealed trait TryInstances2 { +sealed private[instances] trait TryInstances2 { implicit def catsStdSemigroupForTry[A: Semigroup]: Semigroup[Try[A]] = new TrySemigroup[A] } -private[cats] abstract class TryCoflatMap extends CoflatMap[Try] { +abstract private[cats] 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 ApplySemigroup[Try, A](try_.catsStdInstancesForTry, implicitly) -private[cats] class TryMonoid[A](implicit A: Monoid[A]) extends ApplicativeMonoid[Try, A](try_.catsStdInstancesForTry, implicitly) +private[cats] class TryMonoid[A](implicit A: Monoid[A]) + extends ApplicativeMonoid[Try, A](try_.catsStdInstancesForTry, implicitly) diff --git a/core/src/main/scala/cats/instances/tuple.scala b/core/src/main/scala/cats/instances/tuple.scala index 53cd07a3c49..3a20ab88bd9 100644 --- a/core/src/main/scala/cats/instances/tuple.scala +++ b/core/src/main/scala/cats/instances/tuple.scala @@ -10,16 +10,18 @@ trait TupleInstances extends Tuple2Instances with cats.kernel.instances.TupleIns trait Tuple2InstancesBinCompat0 { /** - * Witness for: (A, A) <-> Boolean => A - */ - implicit def catsDataRepresentableForPair(implicit PF: Functor[λ[P => (P, P)]]): Representable.Aux[λ[P => (P, P)], Boolean] = new Representable[λ[P => (P, P)]] { + * Witness for: (A, A) <-> Boolean => A + */ + implicit def catsDataRepresentableForPair( + implicit PF: Functor[λ[P => (P, P)]] + ): Representable.Aux[λ[P => (P, P)], Boolean] = new Representable[λ[P => (P, P)]] { override type Representation = Boolean override val F: Functor[λ[P => (P, P)]] = PF override def tabulate[A](f: Boolean => A): (A, A) = (f(true), f(false)) override def index[A](pair: (A, A)): Boolean => A = { - case true => pair._1 + case true => pair._1 case false => pair._2 } } @@ -38,14 +40,14 @@ sealed trait Tuple2Instances extends Tuple2Instances1 { def bifoldLeft[A, B, C](fab: (A, B), c: C)(f: (C, A) => C, g: (C, B) => C): C = g(f(c, fab._1), fab._2) - def bifoldRight[A, B, C](fab: (A, B), c: Eval[C])(f: (A, Eval[C]) => Eval[C], g: (B, Eval[C]) => Eval[C]): Eval[C] = + def bifoldRight[A, B, C](fab: (A, B), c: Eval[C])(f: (A, Eval[C]) => Eval[C], + g: (B, Eval[C]) => Eval[C]): Eval[C] = g(fab._2, f(fab._1, c)) } 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 = { + override def show(f: (A, B)): String = s"(${aShow.show(f._1)},${bShow.show(f._2)})" - } } implicit def catsStdInstancesForTuple2[X]: Traverse[(X, ?)] with Comonad[(X, ?)] with Reducible[(X, ?)] = @@ -163,10 +165,10 @@ private[instances] class FlatMapTuple2[X](s: Semigroup[X]) extends FlatMap[(X, ? def loop(x: X, aa: A): (X, B) = f(aa) match { case (nextX, Left(nextA)) => loop(s.combine(x, nextX), nextA) - case (nextX, Right(b)) => (s.combine(x, nextX), b) + case (nextX, Right(b)) => (s.combine(x, nextX), b) } f(a) match { - case (x, Right(b)) => (x, b) + case (x, Right(b)) => (x, b) case (x, Left(nextA)) => loop(x, nextA) } } diff --git a/core/src/main/scala/cats/instances/vector.scala b/core/src/main/scala/cats/instances/vector.scala index 1cdb90f8898..d518353f213 100644 --- a/core/src/main/scala/cats/instances/vector.scala +++ b/core/src/main/scala/cats/instances/vector.scala @@ -8,7 +8,8 @@ import scala.collection.+: import scala.collection.immutable.VectorBuilder trait VectorInstances extends cats.kernel.instances.VectorInstances { - implicit val catsStdInstancesForVector: Traverse[Vector] with Monad[Vector] with Alternative[Vector] with CoflatMap[Vector] = + implicit val catsStdInstancesForVector + : Traverse[Vector] with Monad[Vector] with Alternative[Vector] with CoflatMap[Vector] = new Traverse[Vector] with Monad[Vector] with Alternative[Vector] with CoflatMap[Vector] { def empty[A]: Vector[A] = Vector.empty[A] @@ -27,7 +28,7 @@ trait VectorInstances extends cats.kernel.instances.VectorInstances { @tailrec def loop(builder: VectorBuilder[B], as: Vector[A]): Vector[B] = as match { case _ +: rest => loop(builder += f(as), rest) - case _ => builder.result() + case _ => builder.result() } loop(new VectorBuilder[B], fa) } @@ -73,7 +74,7 @@ trait VectorInstances extends cats.kernel.instances.VectorInstances { if (idx < Int.MaxValue && fa.size > idx && idx >= 0) Some(fa(idx.toInt)) else None override def traverse[G[_], A, B](fa: Vector[A])(f: A => G[B])(implicit G: Applicative[G]): G[Vector[B]] = - foldRight[A, G[Vector[B]]](fa, Always(G.pure(Vector.empty))){ (a, lgvb) => + foldRight[A, G[Vector[B]]](fa, Always(G.pure(Vector.empty))) { (a, lgvb) => G.map2Eval(f(a), lgvb)(_ +: _) }.value @@ -90,9 +91,10 @@ trait VectorInstances extends cats.kernel.instances.VectorInstances { override def foldM[G[_], A, B](fa: Vector[A], z: B)(f: (B, A) => G[B])(implicit G: Monad[G]): G[B] = { val length = fa.length - G.tailRecM((z, 0)) { case (b, i) => - if (i < length) G.map(f(b, fa(i)))(b => Left((b, i + 1))) - else G.pure(Right(b)) + G.tailRecM((z, 0)) { + case (b, i) => + if (i < length) G.map(f(b, fa(i)))(b => Left((b, i + 1))) + else G.pure(Right(b)) } } @@ -109,10 +111,11 @@ trait VectorInstances extends cats.kernel.instances.VectorInstances { override def collectFirst[A, B](fa: Vector[A])(pf: PartialFunction[A, B]): Option[B] = fa.collectFirst(pf) - override def collectFirstSome[A, B](fa: Vector[A])(f: A => Option[B]): Option[B] = fa.collectFirst(Function.unlift(f)) + override def collectFirstSome[A, B](fa: Vector[A])(f: A => Option[B]): Option[B] = + fa.collectFirst(Function.unlift(f)) } - implicit def catsStdShowForVector[A:Show]: Show[Vector[A]] = + implicit def catsStdShowForVector[A: Show]: Show[Vector[A]] = new Show[Vector[A]] { def show(fa: Vector[A]): String = fa.iterator.map(_.show).mkString("Vector(", ", ", ")") @@ -134,13 +137,14 @@ trait VectorInstancesBinCompat0 { def traverseFilter[G[_], A, B](fa: Vector[A])(f: (A) => G[Option[B]])(implicit G: Applicative[G]): G[Vector[B]] = fa.foldRight(Eval.now(G.pure(Vector.empty[B])))( - (x, xse) => G.map2Eval(f(x), xse)((i, o) => i.fold(o)(_ +: o)) - ).value + (x, xse) => G.map2Eval(f(x), xse)((i, o) => i.fold(o)(_ +: o)) + ) + .value override def filterA[G[_], A](fa: Vector[A])(f: (A) => G[Boolean])(implicit G: Applicative[G]): G[Vector[A]] = fa.foldRight(Eval.now(G.pure(Vector.empty[A])))( - (x, xse) => - G.map2Eval(f(x), xse)((b, vec) => if (b) x +: vec else vec) - ).value + (x, xse) => G.map2Eval(f(x), xse)((b, vec) => if (b) x +: vec else vec) + ) + .value } } diff --git a/core/src/main/scala/cats/package.scala b/core/src/main/scala/cats/package.scala index 308e5480b2a..380ab10d656 100644 --- a/core/src/main/scala/cats/package.scala +++ b/core/src/main/scala/cats/package.scala @@ -1,8 +1,8 @@ import scala.annotation.tailrec /** - * Symbolic aliases for various types are defined here. - */ + * Symbolic aliases for various types are defined here. + */ package object cats { type ~>[F[_], G[_]] = arrow.FunctionK[F, G] @@ -16,24 +16,25 @@ package object cats { /** [[cats.InjectK]][F, G] */ type :≺:[F[_], G[_]] = InjectK[F, G] -/** - * Identity, encoded as `type Id[A] = A`, a convenient alias to make - * identity instances well-kinded. - * - * The identity monad can be seen as the ambient monad that encodes - * the effect of having no effect. It is ambient in the sense that - * plain pure values are values of `Id`. - * - * For instance, the [[cats.Functor]] instance for `[[cats.Id]]` - * allows us to apply a function `A => B` to an `Id[A]` and get an - * `Id[B]`. However, an `Id[A]` is the same as `A`, so all we're doing - * is applying a pure function of type `A => B` to a pure value of - * type `A` to get a pure value of type `B`. That is, the instance - * encodes pure unary function application. - */ + /** + * Identity, encoded as `type Id[A] = A`, a convenient alias to make + * identity instances well-kinded. + * + * The identity monad can be seen as the ambient monad that encodes + * the effect of having no effect. It is ambient in the sense that + * plain pure values are values of `Id`. + * + * For instance, the [[cats.Functor]] instance for `[[cats.Id]]` + * allows us to apply a function `A => B` to an `Id[A]` and get an + * `Id[B]`. However, an `Id[A]` is the same as `A`, so all we're doing + * is applying a pure function of type `A => B` to a pure value of + * type `A` to get a pure value of type `B`. That is, the instance + * encodes pure unary function application. + */ type Id[A] = A type Endo[A] = A => A - implicit val catsInstancesForId: Bimonad[Id] with CommutativeMonad[Id] with Comonad[Id] with NonEmptyTraverse[Id] with Distributive[Id] = + implicit val catsInstancesForId + : Bimonad[Id] with CommutativeMonad[Id] with Comonad[Id] with NonEmptyTraverse[Id] with Distributive[Id] = new Bimonad[Id] with CommutativeMonad[Id] with Comonad[Id] with NonEmptyTraverse[Id] with Distributive[Id] { def pure[A](a: A): A = a def extract[A](a: A): A = a @@ -75,11 +76,11 @@ package object cats { override def get[A](fa: Id[A])(idx: Long): Option[A] = if (idx == 0L) Some(fa) else None override def isEmpty[A](fa: Id[A]): Boolean = false - } + } /** - * Witness for: Id[A] <-> Unit => A - */ + * Witness for: Id[A] <-> Unit => A + */ implicit val catsRepresentableForId: Representable.Aux[Id, Unit] = new Representable[Id] { override type Representation = Unit override val F: Functor[Id] = Functor[Id] diff --git a/core/src/main/scala/cats/syntax/DistributiveSyntax.scala b/core/src/main/scala/cats/syntax/DistributiveSyntax.scala index abdba5b236a..25b67b2cc0e 100644 --- a/core/src/main/scala/cats/syntax/DistributiveSyntax.scala +++ b/core/src/main/scala/cats/syntax/DistributiveSyntax.scala @@ -4,11 +4,13 @@ package syntax import cats.evidence.=== trait DistributiveSyntax extends Distributive.ToDistributiveOps { - implicit final def catsSyntaxDistributiveOps[F[_]: Functor, A](fa: F[A]): DistributiveOps[F, A] = new DistributiveOps[F, A](fa) + implicit final def catsSyntaxDistributiveOps[F[_]: Functor, A](fa: F[A]): DistributiveOps[F, A] = + new DistributiveOps[F, A](fa) } // Add syntax to functor as part of importing distributive syntax. final class DistributiveOps[F[_], A](val fa: F[A]) extends AnyVal { def distribute[G[_], B](f: A => G[B])(implicit G: Distributive[G], F: Functor[F]): G[F[B]] = G.distribute(fa)(f) - def cosequence[G[_], B](implicit G: Distributive[G], F: Functor[F], ev: A === G[B]): G[F[B]] = G.cosequence(ev.substitute(fa)) + def cosequence[G[_], B](implicit G: Distributive[G], F: Functor[F], ev: A === G[B]): G[F[B]] = + G.cosequence(ev.substitute(fa)) } diff --git a/core/src/main/scala/cats/syntax/TrySyntax.scala b/core/src/main/scala/cats/syntax/TrySyntax.scala index 29c786c229b..8ef443b6916 100644 --- a/core/src/main/scala/cats/syntax/TrySyntax.scala +++ b/core/src/main/scala/cats/syntax/TrySyntax.scala @@ -7,7 +7,6 @@ trait TrySyntax { implicit final def catsSyntaxTry[A](t: Try[A]): TryOps[A] = new TryOps(t) } - final class TryOps[A](val self: Try[A]) extends AnyVal { /** diff --git a/core/src/main/scala/cats/syntax/all.scala b/core/src/main/scala/cats/syntax/all.scala index 749e4a8619b..4dadad5a536 100644 --- a/core/src/main/scala/cats/syntax/all.scala +++ b/core/src/main/scala/cats/syntax/all.scala @@ -56,13 +56,10 @@ trait AllSyntax with VectorSyntax with WriterSyntax -trait AllSyntaxBinCompat0 - extends UnorderedTraverseSyntax - with ApplicativeErrorExtension - with TrySyntax +trait AllSyntaxBinCompat0 extends UnorderedTraverseSyntax with ApplicativeErrorExtension with TrySyntax trait AllSyntaxBinCompat1 - extends FlatMapOptionSyntax + extends FlatMapOptionSyntax with ChoiceSyntax with NestedSyntax with BinestedSyntax @@ -72,12 +69,11 @@ trait AllSyntaxBinCompat1 with RepresentableSyntax trait AllSyntaxBinCompat2 - extends ParallelTraverseSyntax + extends ParallelTraverseSyntax with TraverseFilterSyntax with FunctorFilterSyntax with EitherSyntaxBinCompat0 with ListSyntaxBinCompat0 with ValidatedSyntaxBincompat0 -trait AllSyntaxBinCompat3 - extends UnorderedFoldableSyntax +trait AllSyntaxBinCompat3 extends UnorderedFoldableSyntax diff --git a/core/src/main/scala/cats/syntax/alternative.scala b/core/src/main/scala/cats/syntax/alternative.scala index 04e241e357e..da362695fec 100644 --- a/core/src/main/scala/cats/syntax/alternative.scala +++ b/core/src/main/scala/cats/syntax/alternative.scala @@ -16,16 +16,16 @@ trait AlternativeSyntax { final class UniteOps[F[_], G[_], A](val fga: F[G[A]]) extends AnyVal { /** - * @see [[Alternative.unite]] - * - * Example: - * {{{ - * scala> import cats.implicits._ - * scala> val x: List[Vector[Int]] = List(Vector(1, 2), Vector(3, 4)) - * scala> x.unite - * res0: List[Int] = List(1, 2, 3, 4) - * }}} - */ + * @see [[Alternative.unite]] + * + * Example: + * {{{ + * scala> import cats.implicits._ + * scala> val x: List[Vector[Int]] = List(Vector(1, 2), Vector(3, 4)) + * scala> x.unite + * res0: List[Int] = List(1, 2, 3, 4) + * }}} + */ def unite(implicit F: Monad[F], A: Alternative[F], @@ -35,16 +35,16 @@ final class UniteOps[F[_], G[_], A](val fga: F[G[A]]) extends AnyVal { final class SeparateOps[F[_], G[_, _], A, B](val fgab: F[G[A, B]]) extends AnyVal { /** - * @see [[Alternative.separate]] - * - * Example: - * {{{ - * scala> import cats.implicits._ - * scala> val l: List[Either[String, Int]] = List(Right(1), Left("error")) - * scala> l.separate - * res0: (List[String], List[Int]) = (List(error),List(1)) - * }}} - */ + * @see [[Alternative.separate]] + * + * Example: + * {{{ + * scala> import cats.implicits._ + * scala> val l: List[Either[String, Int]] = List(Right(1), Left("error")) + * scala> l.separate + * res0: (List[String], List[Int]) = (List(error),List(1)) + * }}} + */ def separate(implicit F: Monad[F], A: Alternative[F], @@ -54,17 +54,17 @@ final class SeparateOps[F[_], G[_, _], A, B](val fgab: F[G[A, B]]) extends AnyVa final class GuardOps(val condition: Boolean) extends AnyVal { /** - * @see [[Alternative.guard]] - * - * Example: - * {{{ - * scala> import cats.implicits._ - * scala> def even(i: Int): Option[String] = (i % 2 == 0).guard[Option].as("even") - * scala> even(2) - * res0: Option[String] = Some(even) - * scala> even(3) - * res1: Option[String] = None - * }}} - */ + * @see [[Alternative.guard]] + * + * Example: + * {{{ + * scala> import cats.implicits._ + * scala> def even(i: Int): Option[String] = (i % 2 == 0).guard[Option].as("even") + * scala> even(2) + * res0: Option[String] = Some(even) + * scala> even(3) + * res1: Option[String] = None + * }}} + */ def guard[F[_]](implicit F: Alternative[F]): F[Unit] = F.guard(condition) } diff --git a/core/src/main/scala/cats/syntax/applicativeError.scala b/core/src/main/scala/cats/syntax/applicativeError.scala index 5d2f0882353..12092f854fb 100644 --- a/core/src/main/scala/cats/syntax/applicativeError.scala +++ b/core/src/main/scala/cats/syntax/applicativeError.scala @@ -8,7 +8,9 @@ trait ApplicativeErrorSyntax { implicit final def catsSyntaxApplicativeErrorId[E](e: E): ApplicativeErrorIdOps[E] = new ApplicativeErrorIdOps(e) - implicit final def catsSyntaxApplicativeError[F[_], E, A](fa: F[A])(implicit F: ApplicativeError[F, E]): ApplicativeErrorOps[F, E, A] = + implicit final def catsSyntaxApplicativeError[F[_], E, A]( + fa: F[A] + )(implicit F: ApplicativeError[F, E]): ApplicativeErrorOps[F, E, A] = new ApplicativeErrorOps[F, E, A](fa) } @@ -16,14 +18,14 @@ trait ApplicativeErrorSyntax { * Extension to ApplicativeError in a binary compat way */ trait ApplicativeErrorExtension { - implicit final def catsSyntaxApplicativeErrorExtension[F[_], E](F: ApplicativeError[F, E]): - ApplicativeErrorExtensionOps[F, E] = - new ApplicativeErrorExtensionOps(F) + implicit final def catsSyntaxApplicativeErrorExtension[F[_], E]( + F: ApplicativeError[F, E] + ): ApplicativeErrorExtensionOps[F, E] = + new ApplicativeErrorExtensionOps(F) } final class ApplicativeErrorExtensionOps[F[_], E](F: ApplicativeError[F, E]) { - /** * Convert from scala.Option * @@ -44,24 +46,24 @@ final class ApplicativeErrorExtensionOps[F[_], E](F: ApplicativeError[F, E]) { ApplicativeError.liftFromOption(oa, ifEmpty)(F) /** - * Convert from cats.data.Validated - * - * Example: - * {{{ - * scala> import cats.implicits._ - * scala> import cats.ApplicativeError - * - * scala> ApplicativeError[Option, Unit].fromValidated(1.valid[Unit]) - * res0: scala.Option[Int] = Some(1) - * - * scala> ApplicativeError[Option, Unit].fromValidated(().invalid[Int]) - * res1: scala.Option[Int] = None - * }}} - */ + * Convert from cats.data.Validated + * + * Example: + * {{{ + * scala> import cats.implicits._ + * scala> import cats.ApplicativeError + * + * scala> ApplicativeError[Option, Unit].fromValidated(1.valid[Unit]) + * res0: scala.Option[Int] = Some(1) + * + * scala> ApplicativeError[Option, Unit].fromValidated(().invalid[Int]) + * res1: scala.Option[Int] = None + * }}} + */ def fromValidated[A](x: Validated[E, A]): F[A] = x match { case Invalid(e) => F.raiseError(e) - case Valid(a) => F.pure(a) + case Valid(a) => F.pure(a) } } diff --git a/core/src/main/scala/cats/syntax/apply.scala b/core/src/main/scala/cats/syntax/apply.scala index 9c9abd38bd8..9a5999e3a01 100644 --- a/core/src/main/scala/cats/syntax/apply.scala +++ b/core/src/main/scala/cats/syntax/apply.scala @@ -15,6 +15,7 @@ trait ApplySyntax extends TupleSemigroupalSyntax { } final class ApplyOps[F[_], A](val fa: F[A]) extends AnyVal { + /** Alias for [[Apply.productR]]. */ @deprecated("Use *> or productR instead.", "1.0.0-RC2") @inline def followedBy[B](fb: F[B])(implicit F: Apply[F]): F[B] = diff --git a/core/src/main/scala/cats/syntax/binested.scala b/core/src/main/scala/cats/syntax/binested.scala index 32a8016fbc8..eeb07527dbb 100644 --- a/core/src/main/scala/cats/syntax/binested.scala +++ b/core/src/main/scala/cats/syntax/binested.scala @@ -4,7 +4,9 @@ package syntax import cats.data.Binested trait BinestedSyntax { - implicit final def catsSyntaxBinestedId[F[_, _], G[_], H[_], A, B](value: F[G[A], H[B]]): BinestedIdOps[F, G, H, A, B] = + implicit final def catsSyntaxBinestedId[F[_, _], G[_], H[_], A, B]( + value: F[G[A], H[B]] + ): BinestedIdOps[F, G, H, A, B] = new BinestedIdOps(value) } diff --git a/core/src/main/scala/cats/syntax/bitraverse.scala b/core/src/main/scala/cats/syntax/bitraverse.scala index d24049def74..35fe8833135 100644 --- a/core/src/main/scala/cats/syntax/bitraverse.scala +++ b/core/src/main/scala/cats/syntax/bitraverse.scala @@ -7,7 +7,9 @@ trait BitraverseSyntax extends BitraverseSyntax1 { } private[syntax] trait BitraverseSyntax1 { - implicit final def catsSyntaxNestedBitraverse[F[_, _]: Bitraverse, G[_], A, B](fgagb: F[G[A], G[B]]): NestedBitraverseOps[F, G, A, B] = + implicit final def catsSyntaxNestedBitraverse[F[_, _]: Bitraverse, G[_], A, B]( + fgagb: F[G[A], G[B]] + ): NestedBitraverseOps[F, G, A, B] = new NestedBitraverseOps[F, G, A, B](fgagb) } diff --git a/core/src/main/scala/cats/syntax/comonad.scala b/core/src/main/scala/cats/syntax/comonad.scala index 77d413ebcca..1229e10dd18 100644 --- a/core/src/main/scala/cats/syntax/comonad.scala +++ b/core/src/main/scala/cats/syntax/comonad.scala @@ -2,4 +2,3 @@ package cats package syntax trait ComonadSyntax extends Comonad.ToComonadOps - diff --git a/core/src/main/scala/cats/syntax/contravariant.scala b/core/src/main/scala/cats/syntax/contravariant.scala index 40b26eb99d3..e721094822e 100644 --- a/core/src/main/scala/cats/syntax/contravariant.scala +++ b/core/src/main/scala/cats/syntax/contravariant.scala @@ -4,4 +4,3 @@ package syntax import cats.Contravariant trait ContravariantSyntax extends Contravariant.ToContravariantOps - diff --git a/core/src/main/scala/cats/syntax/contravariantMonoidal.scala b/core/src/main/scala/cats/syntax/contravariantMonoidal.scala index 2e4f62a5c36..122f7830656 100644 --- a/core/src/main/scala/cats/syntax/contravariantMonoidal.scala +++ b/core/src/main/scala/cats/syntax/contravariantMonoidal.scala @@ -4,7 +4,9 @@ package syntax import cats.ContravariantMonoidal trait ContravariantMonoidalSyntax { - implicit final def catsSyntaxContravariantMonoidal[F[_], A](fa: F[A])(implicit F: ContravariantMonoidal[F]): ContravariantMonoidalOps[F, A] = + implicit final def catsSyntaxContravariantMonoidal[F[_], A]( + fa: F[A] + )(implicit F: ContravariantMonoidal[F]): ContravariantMonoidalOps[F, A] = new ContravariantMonoidalOps[F, A] { type TypeClassType = ContravariantMonoidal[F] diff --git a/core/src/main/scala/cats/syntax/contravariantSemigroupal.scala b/core/src/main/scala/cats/syntax/contravariantSemigroupal.scala index 1c583d14679..0fc66f49998 100644 --- a/core/src/main/scala/cats/syntax/contravariantSemigroupal.scala +++ b/core/src/main/scala/cats/syntax/contravariantSemigroupal.scala @@ -4,7 +4,9 @@ package syntax import cats.ContravariantSemigroupal trait ContravariantSemigroupalSyntax extends TupleSemigroupalSyntax { - implicit final def catsSyntaxContravariantSemigroupal[F[_], A](fa: F[A])(implicit F: ContravariantSemigroupal[F]): ContravariantSemigroupal.Ops[F, A] = + implicit final def catsSyntaxContravariantSemigroupal[F[_], A]( + fa: F[A] + )(implicit F: ContravariantSemigroupal[F]): ContravariantSemigroupal.Ops[F, A] = new ContravariantSemigroupal.Ops[F, A] { type TypeClassType = ContravariantSemigroupal[F] diff --git a/core/src/main/scala/cats/syntax/either.scala b/core/src/main/scala/cats/syntax/either.scala index 8039a03cfe3..bc64e20d980 100644 --- a/core/src/main/scala/cats/syntax/either.scala +++ b/core/src/main/scala/cats/syntax/either.scala @@ -10,7 +10,8 @@ import EitherSyntax._ trait EitherSyntax { implicit final def catsSyntaxEither[A, B](eab: Either[A, B]): EitherOps[A, B] = new EitherOps(eab) - implicit final def catsSyntaxEitherObject(either: Either.type): EitherObjectOps = new EitherObjectOps(either) // scalastyle:off ensure.single.space.after.token + implicit final def catsSyntaxEitherObject(either: Either.type): EitherObjectOps = + new EitherObjectOps(either) // scalastyle:off ensure.single.space.after.token implicit final def catsSyntaxLeft[A, B](left: Left[A, B]): LeftOps[A, B] = new LeftOps(left) @@ -22,9 +23,9 @@ trait EitherSyntax { object EitherSyntax { /** - * Uses the [[http://typelevel.org/cats/guidelines.html#partially-applied-type-params Partially Applied Type Params technique]] for ergonomics. - */ - private[syntax] final class CatchOnlyPartiallyApplied[T](val dummy: Boolean = true ) extends AnyVal { + * Uses the [[http://typelevel.org/cats/guidelines.html#partially-applied-type-params Partially Applied Type Params technique]] for ergonomics. + */ + final private[syntax] class CatchOnlyPartiallyApplied[T](val dummy: Boolean = true) extends AnyVal { def apply[A](f: => A)(implicit CT: ClassTag[T], NT: NotNull[T]): Either[T, A] = try { Right(f) @@ -109,7 +110,7 @@ final class EitherOps[A, B](val eab: Either[A, B]) extends AnyVal { } /** Returns a [[cats.data.ValidatedNel]] representation of this disjunction with the `Left` value - * as a single element on the `Invalid` side of the [[cats.data.NonEmptyList]]. */ + * as a single element on the `Invalid` side of the [[cats.data.NonEmptyList]]. */ def toValidatedNel[AA >: A]: ValidatedNel[AA, B] = eab match { case Left(a) => Validated.invalidNel(a) case Right(b) => Validated.valid(b) @@ -155,7 +156,7 @@ final class EitherOps[A, B](val eab: Either[A, B]) extends AnyVal { } def compare[AA >: A, BB >: B](that: Either[AA, BB])(implicit AA: Order[AA], BB: Order[BB]): Int = eab match { - case Left(a1) => + case Left(a1) => that match { case Left(a2) => AA.compare(a1, a2) case Right(_) => -1 @@ -167,8 +168,9 @@ final class EitherOps[A, B](val eab: Either[A, B]) extends AnyVal { } } - def partialCompare[AA >: A, BB >: B](that: Either[AA, BB])(implicit AA: PartialOrder[AA], BB: PartialOrder[BB]): Double = eab match { - case Left(a1) => + def partialCompare[AA >: A, BB >: B](that: Either[AA, BB])(implicit AA: PartialOrder[AA], + BB: PartialOrder[BB]): Double = eab match { + case Left(a1) => that match { case Left(a2) => AA.partialCompare(a1, a2) case Right(_) => -1 @@ -181,7 +183,7 @@ final class EitherOps[A, B](val eab: Either[A, B]) extends AnyVal { } def ===[AA >: A, BB >: B](that: Either[AA, BB])(implicit AA: Eq[AA], BB: Eq[BB]): Boolean = eab match { - case Left(a1) => + case Left(a1) => that match { case Left(a2) => AA.eqv(a1, a2) case Right(_) => false @@ -209,43 +211,44 @@ final class EitherOps[A, B](val eab: Either[A, B]) extends AnyVal { } /** - * Combine with another `Either` value. - * - * If this `Either` is a `Left` then it will be returned as-is. - * If this `Either` is a `Right` and `that` `Either` is a left, then `that` will be - * returned. - * If both `Either`s are `Right`s, then the `Semigroup[BB]` instance will be used - * to combine both values and return them as a `Right`. - * Note: If both `Either`s are `Left`s then their values are not combined. Use - * `Validated` if you prefer to combine `Left` values. - * - * Examples: - * {{{ - * scala> import cats.implicits._ - * scala> val l1: Either[String, Int] = Either.left("error 1") - * scala> val l2: Either[String, Int] = Either.left("error 2") - * scala> val r3: Either[String, Int] = Either.right(3) - * scala> val r4: Either[String, Int] = Either.right(4) - * - * scala> l1 combine l2 - * res0: Either[String, Int] = Left(error 1) - * - * scala> l1 combine r3 - * res1: Either[String, Int] = Left(error 1) - * - * scala> r3 combine l1 - * res2: Either[String, Int] = Left(error 1) - * - * scala> r3 combine r4 - * res3: Either[String, Int] = Right(7) - * }}} - */ + * Combine with another `Either` value. + * + * If this `Either` is a `Left` then it will be returned as-is. + * If this `Either` is a `Right` and `that` `Either` is a left, then `that` will be + * returned. + * If both `Either`s are `Right`s, then the `Semigroup[BB]` instance will be used + * to combine both values and return them as a `Right`. + * Note: If both `Either`s are `Left`s then their values are not combined. Use + * `Validated` if you prefer to combine `Left` values. + * + * Examples: + * {{{ + * scala> import cats.implicits._ + * scala> val l1: Either[String, Int] = Either.left("error 1") + * scala> val l2: Either[String, Int] = Either.left("error 2") + * scala> val r3: Either[String, Int] = Either.right(3) + * scala> val r4: Either[String, Int] = Either.right(4) + * + * scala> l1 combine l2 + * res0: Either[String, Int] = Left(error 1) + * + * scala> l1 combine r3 + * res1: Either[String, Int] = Left(error 1) + * + * scala> r3 combine l1 + * res2: Either[String, Int] = Left(error 1) + * + * scala> r3 combine r4 + * res3: Either[String, Int] = Right(7) + * }}} + */ final def combine[AA >: A, BB >: B](that: Either[AA, BB])(implicit BB: Semigroup[BB]): Either[AA, BB] = eab match { case left @ Left(_) => left - case Right(b1) => that match { - case left @ Left(_) => left - case Right(b2) => Right(BB.combine(b1, b2)) - } + case Right(b1) => + that match { + case left @ Left(_) => left + case Right(b2) => Right(BB.combine(b1, b2)) + } } def show[AA >: A, BB >: B](implicit AA: Show[AA], BB: Show[BB]): String = eab match { @@ -256,15 +259,15 @@ final class EitherOps[A, B](val eab: Either[A, B]) extends AnyVal { def ap[AA >: A, BB >: B, C](that: Either[AA, BB => C]): Either[AA, C] = new EitherOps(that).flatMap(this.map) /** - * Transform the `Either` into a [[cats.data.EitherT]] while lifting it into the specified Applicative. - * - * {{{ - * scala> import cats.implicits._ - * scala> val e: Either[String, Int] = Right(3) - * scala> e.toEitherT[Option] - * res0: cats.data.EitherT[Option, String, Int] = EitherT(Some(Right(3))) - * }}} - */ + * Transform the `Either` into a [[cats.data.EitherT]] while lifting it into the specified Applicative. + * + * {{{ + * scala> import cats.implicits._ + * scala> val e: Either[String, Int] = Right(3) + * scala> e.toEitherT[Option] + * res0: cats.data.EitherT[Option, String, Int] = EitherT(Some(Right(3))) + * }}} + */ def toEitherT[F[_]: Applicative]: EitherT[F, A, B] = EitherT.fromEither(eab) def toEitherNec[AA >: A]: EitherNec[AA, B] = leftMap(NonEmptyChain.one) @@ -290,7 +293,6 @@ final class EitherOps[A, B](val eab: Either[A, B]) extends AnyVal { def liftTo[F[_]](implicit F: ApplicativeError[F, _ >: A]): F[B] = F.fromEither(eab) } - final class EitherObjectOps(val either: Either.type) extends AnyVal { // scalastyle:off ensure.single.space.after.token def left[A, B](a: A): Either[A, B] = Left(a) @@ -309,16 +311,16 @@ final class EitherObjectOps(val either: Either.type) extends AnyVal { // scalast def rightNel[A, B](b: B): EitherNel[A, B] = Right(b) /** - * Evaluates the specified block, catching exceptions of the specified type and returning them on the left side of - * the resulting `Either`. Uncaught exceptions are propagated. - * - * For example: - * {{{ - * scala> import cats.implicits._ // get syntax for Either - * scala> Either.catchOnly[NumberFormatException] { "foo".toInt } - * res0: Either[NumberFormatException, Int] = Left(java.lang.NumberFormatException: For input string: "foo") - * }}} - */ + * Evaluates the specified block, catching exceptions of the specified type and returning them on the left side of + * the resulting `Either`. Uncaught exceptions are propagated. + * + * For example: + * {{{ + * scala> import cats.implicits._ // get syntax for Either + * scala> Either.catchOnly[NumberFormatException] { "foo".toInt } + * res0: Either[NumberFormatException, Int] = Left(java.lang.NumberFormatException: For input string: "foo") + * }}} + */ def catchOnly[T >: Null <: Throwable]: CatchOnlyPartiallyApplied[T] = new CatchOnlyPartiallyApplied[T] @@ -330,8 +332,8 @@ final class EitherObjectOps(val either: Either.type) extends AnyVal { // scalast } /** - * Converts a `Try[A]` to a `Either[Throwable, A]`. - */ + * Converts a `Try[A]` to a `Either[Throwable, A]`. + */ def fromTry[A](t: Try[A]): Either[Throwable, A] = t match { case Failure(e) => left(e) @@ -339,28 +341,29 @@ final class EitherObjectOps(val either: Either.type) extends AnyVal { // scalast } /** - * Converts an `Option[B]` to an `Either[A, B]`, where the provided `ifNone` values is returned on - * the left of the `Either` when the specified `Option` is `None`. - */ + * Converts an `Option[B]` to an `Either[A, B]`, where the provided `ifNone` values is returned on + * the left of the `Either` when the specified `Option` is `None`. + */ def fromOption[A, B](o: Option[B], ifNone: => A): Either[A, B] = o match { case None => left[A, B](ifNone) case Some(a) => right(a) } } - - final class LeftOps[A, B](val left: Left[A, B]) extends AnyVal { + /** Cast the right type parameter of the `Left`. */ def rightCast[C]: Either[A, C] = left.asInstanceOf[Either[A, C]] } final class RightOps[A, B](val right: Right[A, B]) extends AnyVal { + /** Cast the left type parameter of the `Right`. */ def leftCast[C]: Either[C, B] = right.asInstanceOf[Either[C, B]] } final class EitherIdOps[A](val obj: A) extends AnyVal { + /** Wrap a value in `Left`. */ def asLeft[B]: Either[A, B] = Left(obj) @@ -368,27 +371,27 @@ final class EitherIdOps[A](val obj: A) extends AnyVal { def asRight[B]: Either[B, A] = Right(obj) /** - * Wrap a value to a left EitherNel - * - * For example: - * {{{ - * scala> import cats.implicits._, cats.data.NonEmptyList - * scala> "Err".leftNel[Int] - * res0: Either[NonEmptyList[String], Int] = Left(NonEmptyList(Err)) - * }}} - */ + * Wrap a value to a left EitherNel + * + * For example: + * {{{ + * scala> import cats.implicits._, cats.data.NonEmptyList + * scala> "Err".leftNel[Int] + * res0: Either[NonEmptyList[String], Int] = Left(NonEmptyList(Err)) + * }}} + */ def leftNel[B]: Either[NonEmptyList[A], B] = Left(NonEmptyList.one(obj)) /** - * Wrap a value to a right EitherNel - * - * For example: - * {{{ - * scala> import cats.implicits._, cats.data.NonEmptyList - * scala> 1.rightNel[String] - * res0: Either[NonEmptyList[String], Int] = Right(1) - * }}} - */ + * Wrap a value to a right EitherNel + * + * For example: + * {{{ + * scala> import cats.implicits._, cats.data.NonEmptyList + * scala> 1.rightNel[String] + * res0: Either[NonEmptyList[String], Int] = Right(1) + * }}} + */ def rightNel[B]: Either[NonEmptyList[B], A] = Right(obj) } @@ -402,34 +405,36 @@ trait EitherSyntaxBinCompat0 { } final class EitherIdOpsBinCompat0[A](val value: A) extends AnyVal { + /** - * Wrap a value to a left EitherNec - * - * For example: - * {{{ - * scala> import cats.implicits._, cats.data.NonEmptyChain - * scala> "Err".leftNec[Int] - * res0: Either[NonEmptyChain[String], Int] = Left(Chain(Err)) - * }}} - */ + * Wrap a value to a left EitherNec + * + * For example: + * {{{ + * scala> import cats.implicits._, cats.data.NonEmptyChain + * scala> "Err".leftNec[Int] + * res0: Either[NonEmptyChain[String], Int] = Left(Chain(Err)) + * }}} + */ def leftNec[B]: Either[NonEmptyChain[A], B] = Left(NonEmptyChain.one(value)) /** - * Wrap a value to a right EitherNec - * - * For example: - * {{{ - * scala> import cats.implicits._, cats.data.NonEmptyChain - * scala> 1.rightNec[String] - * res0: Either[NonEmptyChain[String], Int] = Right(1) - * }}} - */ + * Wrap a value to a right EitherNec + * + * For example: + * {{{ + * scala> import cats.implicits._, cats.data.NonEmptyChain + * scala> 1.rightNec[String] + * res0: Either[NonEmptyChain[String], Int] = Right(1) + * }}} + */ def rightNec[B]: Either[NonEmptyChain[B], A] = Right(value) } final class EitherOpsBinCompat0[A, B](val value: Either[A, B]) extends AnyVal { + /** Returns a [[cats.data.ValidatedNec]] representation of this disjunction with the `Left` value - * as a single element on the `Invalid` side of the [[cats.data.NonEmptyList]]. */ + * as a single element on the `Invalid` side of the [[cats.data.NonEmptyList]]. */ def toValidatedNec: ValidatedNec[A, B] = value match { case Left(a) => Validated.invalidNec(a) case Right(b) => Validated.valid(b) diff --git a/core/src/main/scala/cats/syntax/eitherK.scala b/core/src/main/scala/cats/syntax/eitherK.scala index d9f3f0ecb8a..78ab703cef1 100644 --- a/core/src/main/scala/cats/syntax/eitherK.scala +++ b/core/src/main/scala/cats/syntax/eitherK.scala @@ -10,34 +10,34 @@ trait EitherKSyntax { final class EitherKOps[F[_], A](val fa: F[A]) extends AnyVal { /** - * Lift an `F[A]` into a `EitherK[F, G, A]` for any type constructor `G[_]`. - * - * @see [[rightc]] to swap the order of `F` and `G` in the result type. - * - * Example: - * {{{ - * scala> import cats.data.EitherK - * scala> import cats.Eval - * scala> import cats.implicits._ - * scala> List(1, 2, 3).leftc[Eval] - * res0: EitherK[List, Eval, Int] = EitherK(Left(List(1, 2, 3))) - * }}} - */ + * Lift an `F[A]` into a `EitherK[F, G, A]` for any type constructor `G[_]`. + * + * @see [[rightc]] to swap the order of `F` and `G` in the result type. + * + * Example: + * {{{ + * scala> import cats.data.EitherK + * scala> import cats.Eval + * scala> import cats.implicits._ + * scala> List(1, 2, 3).leftc[Eval] + * res0: EitherK[List, Eval, Int] = EitherK(Left(List(1, 2, 3))) + * }}} + */ def leftc[G[_]]: EitherK[F, G, A] = EitherK.leftc(fa) /** - * Lift an `F[A]` into a `EitherK[G, F, A]` for any type constructor `G[_]`. - * - * @see [[leftc]] to swap the order of `F` and `G` in the result type. - * - * Example: - * {{{ - * scala> import cats.data.EitherK - * scala> import cats.Eval - * scala> import cats.implicits._ - * scala> List(1, 2, 3).rightc[Eval] - * res0: EitherK[Eval, List, Int] = EitherK(Right(List(1, 2, 3))) - * }}} - */ + * Lift an `F[A]` into a `EitherK[G, F, A]` for any type constructor `G[_]`. + * + * @see [[leftc]] to swap the order of `F` and `G` in the result type. + * + * Example: + * {{{ + * scala> import cats.data.EitherK + * scala> import cats.Eval + * scala> import cats.implicits._ + * scala> List(1, 2, 3).rightc[Eval] + * res0: EitherK[Eval, List, Int] = EitherK(Right(List(1, 2, 3))) + * }}} + */ def rightc[G[_]]: EitherK[G, F, A] = EitherK.rightc(fa) } diff --git a/core/src/main/scala/cats/syntax/eq.scala b/core/src/main/scala/cats/syntax/eq.scala index 7b40bad96a5..fed77872a72 100644 --- a/core/src/main/scala/cats/syntax/eq.scala +++ b/core/src/main/scala/cats/syntax/eq.scala @@ -4,6 +4,7 @@ package syntax import cats.macros.Ops trait EqSyntax { + /** not final so it can be disabled in favor of scalactic equality in tests */ implicit def catsSyntaxEq[A: Eq](a: A): EqOps[A] = new EqOps[A](a) diff --git a/core/src/main/scala/cats/syntax/flatMap.scala b/core/src/main/scala/cats/syntax/flatMap.scala index 4bf1398bedb..ac0a96dda56 100644 --- a/core/src/main/scala/cats/syntax/flatMap.scala +++ b/core/src/main/scala/cats/syntax/flatMap.scala @@ -19,23 +19,21 @@ trait FlatMapSyntax extends FlatMap.ToFlatMapOps { final class FlatMapOps[F[_], A](val fa: F[A]) extends AnyVal { /** - * Alias for [[flatMap]]. - */ + * Alias for [[flatMap]]. + */ def >>=[B](f: A => F[B])(implicit F: FlatMap[F]): F[B] = F.flatMap(fa)(f) /** - * Alias for `fa.flatMap(_ => fb)`. - * - * Unlike `*>`, `fb` is defined as a by-name parameter, allowing this - * method to be used in cases where computing `fb` is not stack safe - * unless suspended in a `flatMap`. - */ + * Alias for `fa.flatMap(_ => fb)`. + * + * Unlike `*>`, `fb` is defined as a by-name parameter, allowing this + * method to be used in cases where computing `fb` is not stack safe + * unless suspended in a `flatMap`. + */ def >>[B](fb: => F[B])(implicit F: FlatMap[F]): F[B] = F.flatMap(fa)(_ => fb) @deprecated("Use <* instead", "1.0.0-RC1") def <<[B](fb: F[B])(implicit F: FlatMap[F]): F[A] = F.productL(fa)(fb) - - @deprecated("Use productREval instead.", "1.0.0-RC2") def followedByEval[B](fb: Eval[F[B]])(implicit F: FlatMap[F]): F[B] = F.productREval(fa)(fb) @@ -45,17 +43,17 @@ final class FlatMapOps[F[_], A](val fa: F[A]) extends AnyVal { F.productLEval(fa)(fb) /** - * Like an infinite loop of >> calls. This is most useful effect loops - * that you want to run forever in for instance a server. - * - * This will be an infinite loop, or it will return an F[Nothing]. - * - * Be careful using this. - * For instance, a List of length k will produce a list of length k^n at iteration - * n. This means if k = 0, we return an empty list, if k = 1, we loop forever - * allocating single element lists, but if we have a k > 1, we will allocate - * exponentially increasing memory and very quickly OOM. - */ + * Like an infinite loop of >> calls. This is most useful effect loops + * that you want to run forever in for instance a server. + * + * This will be an infinite loop, or it will return an F[Nothing]. + * + * Be careful using this. + * For instance, a List of length k will produce a list of length k^n at iteration + * n. This means if k = 0, we return an empty list, if k = 1, we loop forever + * allocating single element lists, but if we have a k > 1, we will allocate + * exponentially increasing memory and very quickly OOM. + */ def foreverM[B](implicit F: FlatMap[F]): F[B] = { // allocate two things once for efficiency. val leftUnit = Left(()) @@ -68,67 +66,68 @@ final class FlatMapOps[F[_], A](val fa: F[A]) extends AnyVal { final class FlattenOps[F[_], A](val ffa: F[F[A]]) extends AnyVal { /** - * Flatten nested `F` values. - * - * Example: - * {{{ - * scala> import cats.implicits._ - * scala> type ErrorOr[A] = Either[String, A] - * scala> val x: ErrorOr[ErrorOr[Int]] = Right(Right(3)) - * scala> x.flatten - * res0: ErrorOr[Int] = Right(3) - * }}} - */ + * Flatten nested `F` values. + * + * Example: + * {{{ + * scala> import cats.implicits._ + * scala> type ErrorOr[A] = Either[String, A] + * scala> val x: ErrorOr[ErrorOr[Int]] = Right(Right(3)) + * scala> x.flatten + * res0: ErrorOr[Int] = Right(3) + * }}} + */ def flatten(implicit F: FlatMap[F]): F[A] = F.flatten(ffa) } final class IfMOps[F[_]](val fa: F[Boolean]) extends AnyVal { /** - * A conditional lifted into the `F` context. - * - * Example: - * {{{ - * scala> import cats.{Eval, Now} - * scala> import cats.implicits._ - * - * scala> val b1: Eval[Boolean] = Now(true) - * scala> val asInt1: Eval[Int] = b1.ifM(Now(1), Now(0)) - * scala> asInt1.value - * res0: Int = 1 - * - * scala> val b2: Eval[Boolean] = Now(false) - * scala> val asInt2: Eval[Int] = b2.ifM(Now(1), Now(0)) - * scala> asInt2.value - * res1: Int = 0 - * }}} - */ + * A conditional lifted into the `F` context. + * + * Example: + * {{{ + * scala> import cats.{Eval, Now} + * scala> import cats.implicits._ + * + * scala> val b1: Eval[Boolean] = Now(true) + * scala> val asInt1: Eval[Int] = b1.ifM(Now(1), Now(0)) + * scala> asInt1.value + * res0: Int = 1 + * + * scala> val b2: Eval[Boolean] = Now(false) + * scala> val asInt2: Eval[Int] = b2.ifM(Now(1), Now(0)) + * scala> asInt2.value + * res1: Int = 0 + * }}} + */ def ifM[B](ifTrue: => F[B], ifFalse: => F[B])(implicit F: FlatMap[F]): F[B] = F.ifM(fa)(ifTrue, ifFalse) } - final class FlatMapIdOps[A](val a: A) extends AnyVal { /** - * Example: - * {{{ - * scala> import cats.implicits._ - * - * scala> val a: Int = 10 - * scala> a.tailRecM[Option,String](i => if (i == 20) Some(Right("done")) else Some(Left(i+1))) - * res0: Option[String] = Some(done) - * - *}}} - */ + * Example: + * {{{ + * scala> import cats.implicits._ + * + * scala> val a: Int = 10 + * scala> a.tailRecM[Option,String](i => if (i == 20) Some(Right("done")) else Some(Left(i+1))) + * res0: Option[String] = Some(done) + * + *}}} + */ def tailRecM[F[_], B](f: A => F[Either[A, B]])(implicit F: FlatMap[F]): F[B] = F.tailRecM(a)(f) /** - * iterateForeverM is almost exclusively useful for effect types. For instance, - * A may be some state, we may take the current state, run some effect to get - * a new state and repeat. - */ + * iterateForeverM is almost exclusively useful for effect types. For instance, + * A may be some state, we may take the current state, run some effect to get + * a new state and repeat. + */ def iterateForeverM[F[_], B](f: A => F[A])(implicit F: FlatMap[F]): F[B] = - tailRecM[F, B](f.andThen { fa => F.map(fa)(Left(_): Either[A, B]) }) + tailRecM[F, B](f.andThen { fa => + F.map(fa)(Left(_): Either[A, B]) + }) } trait FlatMapOptionSyntax { @@ -137,15 +136,16 @@ trait FlatMapOptionSyntax { } final class FlatMapOptionOps[F[_], A](val fopta: F[Option[A]]) extends AnyVal { + /** - * This repeats an F until we get defined values. This can be useful - * for polling type operations on State (or RNG) Monads, or in effect - * monads. - */ + * This repeats an F until we get defined values. This can be useful + * for polling type operations on State (or RNG) Monads, or in effect + * monads. + */ def untilDefinedM(implicit F: FlatMap[F]): F[A] = { val leftUnit: Either[Unit, A] = Left(()) val feither: F[Either[Unit, A]] = F.map(fopta) { - case None => leftUnit + case None => leftUnit case Some(a) => Right(a) } F.tailRecM(())(_ => feither) diff --git a/core/src/main/scala/cats/syntax/foldable.scala b/core/src/main/scala/cats/syntax/foldable.scala index b54004a0d6f..4573369c4a4 100644 --- a/core/src/main/scala/cats/syntax/foldable.scala +++ b/core/src/main/scala/cats/syntax/foldable.scala @@ -13,17 +13,17 @@ final class NestedFoldableOps[F[_], G[_], A](val fga: F[G[A]]) extends AnyVal { def sequence_(implicit F: Foldable[F], G: Applicative[G]): G[Unit] = F.sequence_(fga) /** - * @see [[Foldable.foldK]]. - * - * Example: - * {{{ - * scala> import cats.implicits._ - * - * scala> val l: List[Set[Int]] = List(Set(1, 2), Set(2, 3), Set(3, 4)) - * scala> l.foldK - * res0: Set[Int] = Set(1, 2, 3, 4) - * }}} - */ + * @see [[Foldable.foldK]]. + * + * Example: + * {{{ + * scala> import cats.implicits._ + * + * scala> val l: List[Set[Int]] = List(Set(1, 2), Set(2, 3), Set(3, 4)) + * scala> l.foldK + * res0: Set[Int] = Set(1, 2, 3, 4) + * }}} + */ def foldK(implicit F: Foldable[F], G: MonoidK[G]): G[A] = F.foldK(fga) } @@ -34,56 +34,56 @@ final class FoldableOps[F[_], A](val fa: F[A]) extends AnyVal { def foldr[B](b: Eval[B])(f: (A, Eval[B]) => Eval[B])(implicit F: Foldable[F]): Eval[B] = F.foldRight(fa, b)(f) - /** - * test if `F[A]` contains an `A`, named contains_ to avoid conflict with existing contains which uses universal equality - * - * Example: - * {{{ - * scala> import cats.implicits._ - * - * scala> val l: List[Int] = List(1, 2, 3, 4) - * scala> l.contains_(1) - * res0: Boolean = true - * scala> l.contains_(5) - * res1: Boolean = false - * }}} - */ + /** + * test if `F[A]` contains an `A`, named contains_ to avoid conflict with existing contains which uses universal equality + * + * Example: + * {{{ + * scala> import cats.implicits._ + * + * scala> val l: List[Int] = List(1, 2, 3, 4) + * scala> l.contains_(1) + * res0: Boolean = true + * scala> l.contains_(5) + * res1: Boolean = false + * }}} + */ def contains_(v: A)(implicit ev: Eq[A], F: Foldable[F]): Boolean = F.exists(fa)(ev.eqv(_, v)) - /** - * Intercalate with a prefix and a suffix - * - * Example: - * {{{ - * scala> import cats.implicits._ - * - * scala> val l: List[String] = List("1", "2", "3") - * scala> l.foldSmash("List(", ",", ")") - * res0: String = List(1,2,3) - * }}} - */ + /** + * Intercalate with a prefix and a suffix + * + * Example: + * {{{ + * scala> import cats.implicits._ + * + * scala> val l: List[String] = List("1", "2", "3") + * scala> l.foldSmash("List(", ",", ")") + * res0: String = List(1,2,3) + * }}} + */ def foldSmash(prefix: A, delim: A, suffix: A)(implicit A: Monoid[A], F: Foldable[F]): A = A.combine(prefix, A.combine(F.intercalate(fa, delim), suffix)) - /** - * Make a string using `Show`, named as `mkString_` to avoid conflict - * - * Example: - * {{{ - * scala> import cats.implicits._ - * - * scala> val l: List[Int] = List(1, 2, 3) - * scala> l.mkString_("L[", ";", "]") - * res0: String = L[1;2;3] - * scala> val el: List[Int] = List() - * scala> el.mkString_("L[", ";", "]") - * res1: String = L[] - * }}} - */ + /** + * Make a string using `Show`, named as `mkString_` to avoid conflict + * + * Example: + * {{{ + * scala> import cats.implicits._ + * + * scala> val l: List[Int] = List(1, 2, 3) + * scala> l.mkString_("L[", ";", "]") + * res0: String = L[1;2;3] + * scala> val el: List[Int] = List() + * scala> el.mkString_("L[", ";", "]") + * res1: String = L[] + * }}} + */ def mkString_(prefix: String, delim: String, suffix: String)(implicit A: Show[A], F: Foldable[F]): String = { - val b = F.foldLeft(fa, new StringBuilder){ (builder, a) => - builder append A.show(a) append delim + val b = F.foldLeft(fa, new StringBuilder) { (builder, a) => + builder.append(A.show(a)).append(delim) } prefix + { if (b.isEmpty) @@ -123,10 +123,11 @@ final class FoldableOps[F[_], A](val fa: F[A]) extends AnyVal { */ def collectFirstSomeM[G[_], B](f: A => G[Option[B]])(implicit F: Foldable[F], G: Monad[G]): G[Option[B]] = G.tailRecM(Foldable.Source.fromFoldable(fa))(_.uncons match { - case Some((a, src)) => G.map(f(a)) { - case None => Left(src.value) - case s => Right(s) - } + case Some((a, src)) => + G.map(f(a)) { + case None => Left(src.value) + case s => Right(s) + } case None => G.pure(Right(None)) }) @@ -156,7 +157,7 @@ final class FoldableOps[F[_], A](val fa: F[A]) extends AnyVal { def findM[G[_]](p: A => G[Boolean])(implicit F: Foldable[F], G: Monad[G]): G[Option[A]] = G.tailRecM(Foldable.Source.fromFoldable(fa))(_.uncons match { case Some((a, src)) => G.map(p(a))(if (_) Right(Some(a)) else Left(src.value)) - case None => G.pure(Right(None)) + case None => G.pure(Right(None)) }) /** @@ -182,9 +183,12 @@ final class FoldableOps[F[_], A](val fa: F[A]) extends AnyVal { *}}} */ def collectSomeFold[M](f: A ⇒ Option[M])(implicit F: Foldable[F], M: Monoid[M]): M = - F.foldLeft(fa, M.empty)((acc, a) ⇒ f(a) match { - case Some(x) ⇒ M.combine(acc, x) - case None ⇒ acc - }) + F.foldLeft(fa, M.empty)( + (acc, a) ⇒ + f(a) match { + case Some(x) ⇒ M.combine(acc, x) + case None ⇒ acc + } + ) } diff --git a/core/src/main/scala/cats/syntax/functor.scala b/core/src/main/scala/cats/syntax/functor.scala index f8f4fb9fe72..fcb9d1ce468 100644 --- a/core/src/main/scala/cats/syntax/functor.scala +++ b/core/src/main/scala/cats/syntax/functor.scala @@ -2,4 +2,3 @@ package cats package syntax trait FunctorSyntax extends Functor.ToFunctorOps - diff --git a/core/src/main/scala/cats/syntax/hash.scala b/core/src/main/scala/cats/syntax/hash.scala index 57adf774c4b..9ff263ff819 100644 --- a/core/src/main/scala/cats/syntax/hash.scala +++ b/core/src/main/scala/cats/syntax/hash.scala @@ -11,8 +11,9 @@ trait HashSyntax { } final class HashOps[A: Hash](a: A) { + /** - * Gets the hash code of this object given an implicit `Hash` instance. - */ + * Gets the hash code of this object given an implicit `Hash` instance. + */ def hash: Int = macro Ops.unop0[Int] } diff --git a/core/src/main/scala/cats/syntax/ior.scala b/core/src/main/scala/cats/syntax/ior.scala index 41ab0bca1ba..0fc702d8802 100644 --- a/core/src/main/scala/cats/syntax/ior.scala +++ b/core/src/main/scala/cats/syntax/ior.scala @@ -7,6 +7,7 @@ trait IorSyntax { } final class IorIdOps[A](val a: A) extends AnyVal { + /** * Wrap a value in `Ior.Right`. * diff --git a/core/src/main/scala/cats/syntax/list.scala b/core/src/main/scala/cats/syntax/list.scala index 820c9061682..bc5be75f79c 100644 --- a/core/src/main/scala/cats/syntax/list.scala +++ b/core/src/main/scala/cats/syntax/list.scala @@ -57,20 +57,20 @@ trait ListSyntaxBinCompat0 { final class ListOpsBinCompat0[A](val la: List[A]) extends AnyVal { /** - * Groups elements inside this `List` according to the `Order` of the keys - * produced by the given mapping function. - * - * {{{ - * scala> import cats.data.NonEmptyChain - * scala> import scala.collection.immutable.SortedMap - * scala> import cats.implicits._ - * - * scala> val list = List(12, -2, 3, -5) - * - * scala> list.groupByNec(_ >= 0) - * res0: SortedMap[Boolean, NonEmptyChain[Int]] = Map(false -> Chain(-2, -5), true -> Chain(12, 3)) - * }}} - */ + * Groups elements inside this `List` according to the `Order` of the keys + * produced by the given mapping function. + * + * {{{ + * scala> import cats.data.NonEmptyChain + * scala> import scala.collection.immutable.SortedMap + * scala> import cats.implicits._ + * + * scala> val list = List(12, -2, 3, -5) + * + * scala> list.groupByNec(_ >= 0) + * res0: SortedMap[Boolean, NonEmptyChain[Int]] = Map(false -> Chain(-2, -5), true -> Chain(12, 3)) + * }}} + */ def groupByNec[B](f: A => B)(implicit B: Order[B]): SortedMap[B, NonEmptyChain[A]] = { implicit val ordering = B.toOrdering NonEmptyChain.fromSeq(la).fold(SortedMap.empty[B, NonEmptyChain[A]])(_.groupBy(f).toSortedMap) diff --git a/core/src/main/scala/cats/syntax/monadError.scala b/core/src/main/scala/cats/syntax/monadError.scala index 19f2c58432f..fd374464e91 100644 --- a/core/src/main/scala/cats/syntax/monadError.scala +++ b/core/src/main/scala/cats/syntax/monadError.scala @@ -5,7 +5,9 @@ trait MonadErrorSyntax { implicit final def catsSyntaxMonadError[F[_], E, A](fa: F[A])(implicit F: MonadError[F, E]): MonadErrorOps[F, E, A] = new MonadErrorOps(fa) - implicit final def catsSyntaxMonadErrorRethrow[F[_], E, A](fea: F[Either[E, A]])(implicit F: MonadError[F, E]): MonadErrorRethrowOps[F, E, A] = + implicit final def catsSyntaxMonadErrorRethrow[F[_], E, A]( + fea: F[Either[E, A]] + )(implicit F: MonadError[F, E]): MonadErrorRethrowOps[F, E, A] = new MonadErrorRethrowOps(fea) } diff --git a/core/src/main/scala/cats/syntax/nested.scala b/core/src/main/scala/cats/syntax/nested.scala index f0fadbc9604..6821f3819ba 100644 --- a/core/src/main/scala/cats/syntax/nested.scala +++ b/core/src/main/scala/cats/syntax/nested.scala @@ -9,6 +9,7 @@ trait NestedSyntax { } final class NestedIdOps[F[_], G[_], A](private[syntax] val value: F[G[A]]) extends AnyVal { + /** * Wrap a value in `Nested`. * @@ -23,5 +24,3 @@ final class NestedIdOps[F[_], G[_], A](private[syntax] val value: F[G[A]]) exten */ def nested: Nested[F, G, A] = Nested[F, G, A](value) } - - diff --git a/core/src/main/scala/cats/syntax/option.scala b/core/src/main/scala/cats/syntax/option.scala index 5bd23b9b03c..a6728d9c0ce 100644 --- a/core/src/main/scala/cats/syntax/option.scala +++ b/core/src/main/scala/cats/syntax/option.scala @@ -1,7 +1,7 @@ package cats package syntax -import cats.data.{Ior, OptionT, Validated, ValidatedNel, ValidatedNec} +import cats.data.{Ior, OptionT, Validated, ValidatedNec, ValidatedNel} import cats.syntax.OptionOps.LiftToPartiallyApplied trait OptionSyntax { @@ -11,65 +11,68 @@ trait OptionSyntax { } final class OptionIdOps[A](val a: A) extends AnyVal { + /** - * Wrap a value in `Some`. - * - * `3.some` is equivalent to `Some(3)`, but the former will have an inferred - * return type of `Option[Int]` while the latter will have `Some[Int]`. - * - * Example: - * {{{ - * scala> import cats.implicits._ - * scala> 3.some - * res0: Option[Int] = Some(3) - * }}} - */ + * Wrap a value in `Some`. + * + * `3.some` is equivalent to `Some(3)`, but the former will have an inferred + * return type of `Option[Int]` while the latter will have `Some[Int]`. + * + * Example: + * {{{ + * scala> import cats.implicits._ + * scala> 3.some + * res0: Option[Int] = Some(3) + * }}} + */ def some: Option[A] = Some(a) } final class OptionOps[A](val oa: Option[A]) extends AnyVal { + /** - * If the `Option` is a `Some`, return its value in a [[cats.data.Validated.Invalid]]. - * If the `Option` is `None`, return the provided `B` value in a - * [[cats.data.Validated.Valid]]. - * - * Example: - * {{{ - * scala> import cats.data.Validated - * scala> import cats.implicits._ - * - * scala> val error1: Option[String] = Some("error!") - * scala> error1.toInvalid(3) - * res0: Validated[String, Int] = Invalid(error!) - * - * scala> val error2: Option[String] = None - * scala> error2.toInvalid(3) - * res1: Validated[String, Int] = Valid(3) - * }}} - */ + * If the `Option` is a `Some`, return its value in a [[cats.data.Validated.Invalid]]. + * If the `Option` is `None`, return the provided `B` value in a + * [[cats.data.Validated.Valid]]. + * + * Example: + * {{{ + * scala> import cats.data.Validated + * scala> import cats.implicits._ + * + * scala> val error1: Option[String] = Some("error!") + * scala> error1.toInvalid(3) + * res0: Validated[String, Int] = Invalid(error!) + * + * scala> val error2: Option[String] = None + * scala> error2.toInvalid(3) + * res1: Validated[String, Int] = Valid(3) + * }}} + */ def toInvalid[B](b: => B): Validated[A, B] = oa.fold[Validated[A, B]](Validated.Valid(b))(Validated.Invalid(_)) /** - * If the `Option` is a `Some`, wrap its value in a [[cats.data.NonEmptyList]] - * and return it in a [[cats.data.Validated.Invalid]]. - * If the `Option` is `None`, return the provided `B` value in a - * [[cats.data.Validated.Valid]]. - * - * Example: - * {{{ - * scala> import cats.data.ValidatedNel - * scala> import cats.implicits._ - * - * scala> val error1: Option[String] = Some("error!") - * scala> error1.toInvalidNel(3) - * res0: ValidatedNel[String, Int] = Invalid(NonEmptyList(error!)) - * - * scala> val error2: Option[String] = None - * scala> error2.toInvalidNel(3) - * res1: ValidatedNel[String, Int] = Valid(3) - * }}} - */ - def toInvalidNel[B](b: => B): ValidatedNel[A, B] = oa.fold[ValidatedNel[A, B]](Validated.Valid(b))(Validated.invalidNel) + * If the `Option` is a `Some`, wrap its value in a [[cats.data.NonEmptyList]] + * and return it in a [[cats.data.Validated.Invalid]]. + * If the `Option` is `None`, return the provided `B` value in a + * [[cats.data.Validated.Valid]]. + * + * Example: + * {{{ + * scala> import cats.data.ValidatedNel + * scala> import cats.implicits._ + * + * scala> val error1: Option[String] = Some("error!") + * scala> error1.toInvalidNel(3) + * res0: ValidatedNel[String, Int] = Invalid(NonEmptyList(error!)) + * + * scala> val error2: Option[String] = None + * scala> error2.toInvalidNel(3) + * res1: ValidatedNel[String, Int] = Valid(3) + * }}} + */ + def toInvalidNel[B](b: => B): ValidatedNel[A, B] = + oa.fold[ValidatedNel[A, B]](Validated.Valid(b))(Validated.invalidNel) /** * If the `Option` is a `Some`, wrap its value in a [[cats.data.Chain]] @@ -91,49 +94,51 @@ final class OptionOps[A](val oa: Option[A]) extends AnyVal { * res1: ValidatedNec[String, Int] = Valid(3) * }}} */ - def toInvalidNec[B](b: => B): ValidatedNec[A, B] = oa.fold[ValidatedNec[A, B]](Validated.Valid(b))(Validated.invalidNec) + def toInvalidNec[B](b: => B): ValidatedNec[A, B] = + oa.fold[ValidatedNec[A, B]](Validated.Valid(b))(Validated.invalidNec) /** - * If the `Option` is a `Some`, return its value in a [[cats.data.Validated.Valid]]. - * If the `Option` is `None`, return the provided `B` value in a - * [[cats.data.Validated.Invalid]]. - * - * Example: - * {{{ - * scala> import cats.data.Validated - * scala> import cats.implicits._ - * - * scala> val result1: Option[Int] = Some(3) - * scala> result1.toValid("error!") - * res0: Validated[String, Int] = Valid(3) - * - * scala> val result2: Option[Int] = None - * scala> result2.toValid("error!") - * res1: Validated[String, Int] = Invalid(error!) - * }}} - */ + * If the `Option` is a `Some`, return its value in a [[cats.data.Validated.Valid]]. + * If the `Option` is `None`, return the provided `B` value in a + * [[cats.data.Validated.Invalid]]. + * + * Example: + * {{{ + * scala> import cats.data.Validated + * scala> import cats.implicits._ + * + * scala> val result1: Option[Int] = Some(3) + * scala> result1.toValid("error!") + * res0: Validated[String, Int] = Valid(3) + * + * scala> val result2: Option[Int] = None + * scala> result2.toValid("error!") + * res1: Validated[String, Int] = Invalid(error!) + * }}} + */ def toValid[B](b: => B): Validated[B, A] = oa.fold[Validated[B, A]](Validated.Invalid(b))(Validated.Valid(_)) /** - * If the `Option` is a `Some`, return its value in a [[cats.data.Validated.Valid]]. - * If the `Option` is `None`, wrap the provided `B` value in a [[cats.data.NonEmptyList]] - * and return the result in a [[cats.data.Validated.Invalid]]. - * - * Example: - * {{{ - * scala> import cats.data.ValidatedNel - * scala> import cats.implicits._ - * - * scala> val result1: Option[Int] = Some(3) - * scala> result1.toValidNel("error!") - * res0: ValidatedNel[String, Int] = Valid(3) - * - * scala> val result2: Option[Int] = None - * scala> result2.toValidNel("error!") - * res1: ValidatedNel[String, Int] = Invalid(NonEmptyList(error!)) - * }}} - */ - def toValidNel[B](b: => B): ValidatedNel[B, A] = oa.fold[ValidatedNel[B, A]](Validated.invalidNel(b))(Validated.Valid(_)) + * If the `Option` is a `Some`, return its value in a [[cats.data.Validated.Valid]]. + * If the `Option` is `None`, wrap the provided `B` value in a [[cats.data.NonEmptyList]] + * and return the result in a [[cats.data.Validated.Invalid]]. + * + * Example: + * {{{ + * scala> import cats.data.ValidatedNel + * scala> import cats.implicits._ + * + * scala> val result1: Option[Int] = Some(3) + * scala> result1.toValidNel("error!") + * res0: ValidatedNel[String, Int] = Valid(3) + * + * scala> val result2: Option[Int] = None + * scala> result2.toValidNel("error!") + * res1: ValidatedNel[String, Int] = Invalid(NonEmptyList(error!)) + * }}} + */ + def toValidNel[B](b: => B): ValidatedNel[B, A] = + oa.fold[ValidatedNel[B, A]](Validated.invalidNel(b))(Validated.Valid(_)) /** * If the `Option` is a `Some`, return its value in a [[cats.data.Validated.Valid]]. @@ -154,7 +159,8 @@ final class OptionOps[A](val oa: Option[A]) extends AnyVal { * res1: ValidatedNec[String, Int] = Invalid(Chain(error!)) * }}} */ - def toValidNec[B](b: => B): ValidatedNec[B, A] = oa.fold[ValidatedNec[B, A]](Validated.invalidNec(b))(Validated.Valid(_)) + def toValidNec[B](b: => B): ValidatedNec[B, A] = + oa.fold[ValidatedNec[B, A]](Validated.invalidNec(b))(Validated.Valid(_)) /** * If the `Option` is a `Some`, return its value in a [[cats.data.Ior.Right]]. @@ -197,22 +203,22 @@ final class OptionOps[A](val oa: Option[A]) extends AnyVal { def toLeftIor[B](b: => B): Ior[A, B] = oa.fold[Ior[A, B]](Ior.Right(b))(Ior.Left(_)) /** - * If the `Option` is a `Some`, return its value. If the `Option` is `None`, - * return the `empty` value for `Monoid[A]`. - * - * Example: - * {{{ - * scala> import cats.implicits._ - * - * scala> val someString: Option[String] = Some("hello") - * scala> someString.orEmpty - * res0: String = hello - * - * scala> val noneString: Option[String] = None - * scala> noneString.orEmpty - * res1: String = "" - * }}} - */ + * If the `Option` is a `Some`, return its value. If the `Option` is `None`, + * return the `empty` value for `Monoid[A]`. + * + * Example: + * {{{ + * scala> import cats.implicits._ + * + * scala> val someString: Option[String] = Some("hello") + * scala> someString.orEmpty + * res0: String = hello + * + * scala> val noneString: Option[String] = None + * scala> noneString.orEmpty + * res1: String = "" + * }}} + */ def orEmpty(implicit A: Monoid[A]): A = oa.getOrElse(A.empty) /** @@ -244,7 +250,7 @@ final class OptionOps[A](val oa: Option[A]) extends AnyVal { } object OptionOps { - private[syntax] final class LiftToPartiallyApplied[F[_], A](oa: Option[A]) { + final private[syntax] class LiftToPartiallyApplied[F[_], A](oa: Option[A]) { def apply[E](ifEmpty: => E)(implicit F: ApplicativeError[F, _ >: E]): F[A] = ApplicativeError.liftFromOption(oa, ifEmpty) } diff --git a/core/src/main/scala/cats/syntax/parallel.scala b/core/src/main/scala/cats/syntax/parallel.scala index 494dcf728df..b7782f5d912 100644 --- a/core/src/main/scala/cats/syntax/parallel.scala +++ b/core/src/main/scala/cats/syntax/parallel.scala @@ -1,13 +1,14 @@ package cats.syntax -import cats.{Monad, Parallel, Traverse, FlatMap, Foldable} +import cats.{FlatMap, Foldable, Monad, Parallel, Traverse} trait ParallelSyntax extends TupleParallelSyntax { - implicit final def catsSyntaxParallelTraverse[T[_]: Traverse, A] - (ta: T[A]): ParallelTraversableOps[T, A] = new ParallelTraversableOps[T, A](ta) + implicit final def catsSyntaxParallelTraverse[T[_]: Traverse, A](ta: T[A]): ParallelTraversableOps[T, A] = + new ParallelTraversableOps[T, A](ta) - implicit final def catsSyntaxParallelSequence[T[_]: Traverse, M[_]: Monad, A] - (tma: T[M[A]]): ParallelSequenceOps[T, M, A] = new ParallelSequenceOps[T, M, A](tma) + implicit final def catsSyntaxParallelSequence[T[_]: Traverse, M[_]: Monad, A]( + tma: T[M[A]] + ): ParallelSequenceOps[T, M, A] = new ParallelSequenceOps[T, M, A](tma) implicit final def catsSyntaxParallelAp[M[_]: FlatMap, A](ma: M[A]): ParallelApOps[M, A] = new ParallelApOps[M, A](ma) @@ -15,24 +16,25 @@ trait ParallelSyntax extends TupleParallelSyntax { } trait ParallelFlatSyntax { - implicit final def catsSyntaxParallelFlatTraverse[T[_]: Traverse: FlatMap, A] - (ta: T[A]): ParallelFlatTraversableOps[T, A] = new ParallelFlatTraversableOps[T, A](ta) + implicit final def catsSyntaxParallelFlatTraverse[T[_]: Traverse: FlatMap, A]( + ta: T[A] + ): ParallelFlatTraversableOps[T, A] = new ParallelFlatTraversableOps[T, A](ta) - implicit final def catsSyntaxParallelFlatSequence[T[_]: Traverse: FlatMap, M[_]: Monad, A] - (tmta: T[M[T[A]]]): ParallelFlatSequenceOps[T, M, A] = new ParallelFlatSequenceOps[T, M, A](tmta) + implicit final def catsSyntaxParallelFlatSequence[T[_]: Traverse: FlatMap, M[_]: Monad, A]( + tmta: T[M[T[A]]] + ): ParallelFlatSequenceOps[T, M, A] = new ParallelFlatSequenceOps[T, M, A](tmta) } trait ParallelTraverseSyntax { - implicit final def catsSyntaxParallelTraverse_[T[_]: Foldable, A] - (ta: T[A]): ParallelTraversable_Ops[T, A] = new ParallelTraversable_Ops[T, A](ta) + implicit final def catsSyntaxParallelTraverse_[T[_]: Foldable, A](ta: T[A]): ParallelTraversable_Ops[T, A] = + new ParallelTraversable_Ops[T, A](ta) - implicit final def catsSyntaxParallelSequence_[T[_]: Foldable, M[_], A] - (tma: T[M[A]]): ParallelSequence_Ops[T, M, A] = new ParallelSequence_Ops[T, M, A](tma) + implicit final def catsSyntaxParallelSequence_[T[_]: Foldable, M[_], A](tma: T[M[A]]): ParallelSequence_Ops[T, M, A] = + new ParallelSequence_Ops[T, M, A](tma) } final class ParallelTraversableOps[T[_], A](val ta: T[A]) extends AnyVal { - def parTraverse[M[_]: Monad, F[_], B] - (f: A => M[B])(implicit T: Traverse[T], P: Parallel[M, F]): M[T[B]] = + def parTraverse[M[_]: Monad, F[_], B](f: A => M[B])(implicit T: Traverse[T], P: Parallel[M, F]): M[T[B]] = Parallel.parTraverse(ta)(f) } @@ -43,26 +45,24 @@ final class ParallelTraversable_Ops[T[_], A](val ta: T[A]) extends AnyVal { } final class ParallelFlatTraversableOps[T[_], A](val ta: T[A]) extends AnyVal { - def parFlatTraverse[M[_]: Monad, F[_], B] - (f: A => M[T[B]])(implicit T0: Traverse[T], T1 : FlatMap[T], P: Parallel[M, F]): M[T[B]] = + def parFlatTraverse[M[_]: Monad, F[_], B]( + f: A => M[T[B]] + )(implicit T0: Traverse[T], T1: FlatMap[T], P: Parallel[M, F]): M[T[B]] = Parallel.parFlatTraverse(ta)(f) } final class ParallelSequenceOps[T[_], M[_], A](val tma: T[M[A]]) extends AnyVal { - def parSequence[F[_]] - (implicit M: Monad[M], T: Traverse[T], P: Parallel[M, F]): M[T[A]] = + def parSequence[F[_]](implicit M: Monad[M], T: Traverse[T], P: Parallel[M, F]): M[T[A]] = Parallel.parSequence(tma) } final class ParallelSequence_Ops[T[_], M[_], A](val tma: T[M[A]]) extends AnyVal { - def parSequence_[F[_]] - (implicit T: Foldable[T], P: Parallel[M, F]): M[Unit] = + def parSequence_[F[_]](implicit T: Foldable[T], P: Parallel[M, F]): M[Unit] = Parallel.parSequence_(tma) } final class ParallelFlatSequenceOps[T[_], M[_], A](val tmta: T[M[T[A]]]) extends AnyVal { - def parFlatSequence[F[_]] - (implicit M: Monad[M], T0: Traverse[T], T1 : FlatMap[T], P: Parallel[M, F]): M[T[A]] = + def parFlatSequence[F[_]](implicit M: Monad[M], T0: Traverse[T], T1: FlatMap[T], P: Parallel[M, F]): M[T[A]] = Parallel.parFlatSequence(tmta) } diff --git a/core/src/main/scala/cats/syntax/reducible.scala b/core/src/main/scala/cats/syntax/reducible.scala index 5a062a802ab..10f44874107 100644 --- a/core/src/main/scala/cats/syntax/reducible.scala +++ b/core/src/main/scala/cats/syntax/reducible.scala @@ -1,7 +1,6 @@ package cats package syntax - trait ReducibleSyntax extends Reducible.ToReducibleOps { implicit final def catsSyntaxNestedReducible[F[_]: Reducible, G[_], A](fga: F[G[A]]): NestedReducibleOps[F, G, A] = new NestedReducibleOps[F, G, A](fga) @@ -10,4 +9,3 @@ trait ReducibleSyntax extends Reducible.ToReducibleOps { final class NestedReducibleOps[F[_], G[_], A](val fga: F[G[A]]) extends AnyVal { def reduceK(implicit F: Reducible[F], G: SemigroupK[G]): G[A] = F.reduceK(fga) } - diff --git a/core/src/main/scala/cats/syntax/set.scala b/core/src/main/scala/cats/syntax/set.scala index 0fa5323537f..a4d3a4d26fc 100644 --- a/core/src/main/scala/cats/syntax/set.scala +++ b/core/src/main/scala/cats/syntax/set.scala @@ -1,6 +1,6 @@ package cats.syntax -import scala.collection.immutable.{SortedSet, SortedMap} +import scala.collection.immutable.{SortedMap, SortedSet} import cats.data.NonEmptySet import cats.Order diff --git a/core/src/main/scala/cats/syntax/unorderedFoldable.scala b/core/src/main/scala/cats/syntax/unorderedFoldable.scala index cde4104c915..c0fd0713a5b 100644 --- a/core/src/main/scala/cats/syntax/unorderedFoldable.scala +++ b/core/src/main/scala/cats/syntax/unorderedFoldable.scala @@ -9,6 +9,7 @@ trait UnorderedFoldableSyntax extends UnorderedFoldable.ToUnorderedFoldableOps { } final class UnorderedFoldableOps[F[_], A](val fa: F[A]) extends AnyVal { + /** * Count the number of elements in the structure that satisfy the given predicate. * diff --git a/core/src/main/scala/cats/syntax/validated.scala b/core/src/main/scala/cats/syntax/validated.scala index 8b12f636b25..393519e29c2 100644 --- a/core/src/main/scala/cats/syntax/validated.scala +++ b/core/src/main/scala/cats/syntax/validated.scala @@ -30,27 +30,28 @@ trait ValidatedSyntaxBincompat0 { } final class ValidatedIdOpsBinCompat0[A](val a: A) extends AnyVal { + /** - * Wrap a value to a valid ValidatedNec - * - * For example: - * {{{ - * scala> import cats.implicits._, cats.data._ - * scala> 1.validNec[String] - * res0: Validated[NonEmptyChain[String], Int] = Valid(1) - * }}} - */ + * Wrap a value to a valid ValidatedNec + * + * For example: + * {{{ + * scala> import cats.implicits._, cats.data._ + * scala> 1.validNec[String] + * res0: Validated[NonEmptyChain[String], Int] = Valid(1) + * }}} + */ def validNec[B]: ValidatedNec[B, A] = Validated.Valid(a) /** - * Wrap a value to an invalid ValidatedNec - * - * For example: - * {{{ - * scala> import cats.implicits._, cats.data._ - * scala> "Err".invalidNec[Int] - * res0: Validated[NonEmptyChain[String], Int] = Invalid(Chain(Err)) - * }}} - */ + * Wrap a value to an invalid ValidatedNec + * + * For example: + * {{{ + * scala> import cats.implicits._, cats.data._ + * scala> "Err".invalidNec[Int] + * res0: Validated[NonEmptyChain[String], Int] = Invalid(Chain(Err)) + * }}} + */ def invalidNec[B]: ValidatedNec[A, B] = Validated.invalidNec(a) } diff --git a/free/src/main/scala/cats/free/Cofree.scala b/free/src/main/scala/cats/free/Cofree.scala index 344d68dd74f..66ca02280e7 100644 --- a/free/src/main/scala/cats/free/Cofree.scala +++ b/free/src/main/scala/cats/free/Cofree.scala @@ -73,7 +73,7 @@ object Cofree extends CofreeInstances { private def mapSemilazy[A, B](fa: Eval[A])(f: A => B): Eval[B] = fa match { case Now(a) => Now(f(a)) - case other => other.map(f) + case other => other.map(f) } /** @@ -85,9 +85,12 @@ object Cofree extends CofreeInstances { /** * A monadic recursive fold out of the cofree comonad into a monad which can express Eval's stack-safety. */ - def cataM[F[_], M[_], A, B](cof: Cofree[F, A])(folder: (A, F[B]) => M[B])(inclusion: Eval ~> M)(implicit F: Traverse[F], M: Monad[M]): M[B] = { + def cataM[F[_], M[_], A, B]( + cof: Cofree[F, A] + )(folder: (A, F[B]) => M[B])(inclusion: Eval ~> M)(implicit F: Traverse[F], M: Monad[M]): M[B] = { def loop(fr: Cofree[F, A]): Eval[M[B]] = { - val looped: M[F[B]] = F.traverse[M, Cofree[F, A], B](fr.tailForced)(fr => M.flatten(inclusion(Eval.defer(loop(fr))))) + val looped: M[F[B]] = + F.traverse[M, Cofree[F, A], B](fr.tailForced)(fr => M.flatten(inclusion(Eval.defer(loop(fr))))) val folded: M[B] = M.flatMap(looped)(fb => folder(fr.head, fb)) Eval.now(folded) } @@ -96,22 +99,22 @@ object Cofree extends CofreeInstances { } -sealed private[free] abstract class CofreeInstances2 { - implicit def catsReducibleForCofree[F[_] : Foldable]: Reducible[Cofree[F, ?]] = - new CofreeReducible[F] { - def F = implicitly - } +sealed abstract private[free] class CofreeInstances2 { + implicit def catsReducibleForCofree[F[_]: Foldable]: Reducible[Cofree[F, ?]] = + new CofreeReducible[F] { + def F = implicitly + } } -sealed private[free] abstract class CofreeInstances1 extends CofreeInstances2 { - implicit def catsTraverseForCofree[F[_] : Traverse]: Traverse[Cofree[F, ?]] = - new CofreeTraverse[F] { - def F = implicitly - } +sealed abstract private[free] class CofreeInstances1 extends CofreeInstances2 { + implicit def catsTraverseForCofree[F[_]: Traverse]: Traverse[Cofree[F, ?]] = + new CofreeTraverse[F] { + def F = implicitly + } } -sealed private[free] abstract class CofreeInstances extends CofreeInstances1 { - implicit def catsFreeComonadForCofree[S[_] : Functor]: Comonad[Cofree[S, ?]] = new CofreeComonad[S] { +sealed abstract private[free] class CofreeInstances extends CofreeInstances1 { + implicit def catsFreeComonadForCofree[S[_]: Functor]: Comonad[Cofree[S, ?]] = new CofreeComonad[S] { def F = implicitly } } @@ -119,45 +122,45 @@ sealed private[free] abstract class CofreeInstances extends CofreeInstances1 { private trait CofreeComonad[S[_]] extends Comonad[Cofree[S, ?]] { implicit def F: Functor[S] - override final def extract[A](p: Cofree[S, A]): A = p.extract + final override def extract[A](p: Cofree[S, A]): A = p.extract - override final def coflatMap[A, B](a: Cofree[S, A])(f: Cofree[S, A] => B): Cofree[S, B] = a.coflatMap(f) + final override def coflatMap[A, B](a: Cofree[S, A])(f: Cofree[S, A] => B): Cofree[S, B] = a.coflatMap(f) - override final def coflatten[A](a: Cofree[S, A]): Cofree[S, Cofree[S, A]] = a.coflatten + final override def coflatten[A](a: Cofree[S, A]): Cofree[S, Cofree[S, A]] = a.coflatten - override final def map[A, B](a: Cofree[S, A])(f: A => B): Cofree[S, B] = a.map(f) + final override def map[A, B](a: Cofree[S, A])(f: A => B): Cofree[S, B] = a.map(f) } private trait CofreeReducible[F[_]] extends Reducible[Cofree[F, ?]] { implicit def F: Foldable[F] - override final def foldMap[A, B](fa: Cofree[F, A])(f: A => B)(implicit M: Monoid[B]): B = + final override def foldMap[A, B](fa: Cofree[F, A])(f: A => B)(implicit M: Monoid[B]): B = M.combine(f(fa.head), F.foldMap(fa.tailForced)(foldMap(_)(f))) - override final def foldRight[A, B](fa: Cofree[F, A], z: Eval[B])(f: (A, Eval[B]) => Eval[B]): Eval[B] = + final override def foldRight[A, B](fa: Cofree[F, A], z: Eval[B])(f: (A, Eval[B]) => Eval[B]): Eval[B] = f(fa.head, fa.tail.flatMap(F.foldRight(_, z)(foldRight(_, _)(f)))) - override final def foldLeft[A, B](fa: Cofree[F, A], z: B)(f: (B, A) => B): B = + final override def foldLeft[A, B](fa: Cofree[F, A], z: B)(f: (B, A) => B): B = F.foldLeft(fa.tailForced, f(z, fa.head))((b, cof) => foldLeft(cof, b)(f)) - override final def reduceLeftTo[A, B](fa: Cofree[F, A])(z: A => B)(f: (B, A) => B): B = + final override def reduceLeftTo[A, B](fa: Cofree[F, A])(z: A => B)(f: (B, A) => B): B = F.foldLeft(fa.tailForced, z(fa.head))((b, cof) => foldLeft(cof, b)(f)) - override def reduceRightTo[A, B](fa: Cofree[F, A])(z: A => B)(f: (A, Eval[B]) => Eval[B]): Eval[B] = { + override def reduceRightTo[A, B](fa: Cofree[F, A])(z: A => B)(f: (A, Eval[B]) => Eval[B]): Eval[B] = foldRight(fa, Eval.now((None: Option[B]))) { - case (l, e) => e.flatMap { - case None => Eval.now(Some(z(l))) - case Some(r) => f(l, Eval.now(r)).map(Some(_)) - } + case (l, e) => + e.flatMap { + case None => Eval.now(Some(z(l))) + case Some(r) => f(l, Eval.now(r)).map(Some(_)) + } }.map(_.getOrElse(sys.error("reduceRightTo"))) - } } private trait CofreeTraverse[F[_]] extends Traverse[Cofree[F, ?]] with CofreeReducible[F] with CofreeComonad[F] { implicit def F: Traverse[F] - override final def traverse[G[_], A, B](fa: Cofree[F, A])(f: A => G[B])(implicit G: Applicative[G]): G[Cofree[F, B]] = + final override def traverse[G[_], A, B](fa: Cofree[F, A])(f: A => G[B])(implicit G: Applicative[G]): G[Cofree[F, B]] = G.map2(f(fa.head), F.traverse(fa.tailForced)(traverse(_)(f)))((h, t) => Cofree[F, B](h, Eval.now(t))) } diff --git a/free/src/main/scala/cats/free/ContravariantCoyoneda.scala b/free/src/main/scala/cats/free/ContravariantCoyoneda.scala index d8e8b74133f..61804ecec33 100644 --- a/free/src/main/scala/cats/free/ContravariantCoyoneda.scala +++ b/free/src/main/scala/cats/free/ContravariantCoyoneda.scala @@ -2,12 +2,12 @@ package cats package free /** - * The free contravariant functor on `F`. This is isomorphic to `F` as long as `F` itself is a - * contravariant functor. The function from `F[A]` to `ContravariantCoyoneda[F,A]` exists even when - * `F` is not a contravariant functor. Implemented using a List of functions for stack-safety. - */ + * The free contravariant functor on `F`. This is isomorphic to `F` as long as `F` itself is a + * contravariant functor. The function from `F[A]` to `ContravariantCoyoneda[F,A]` exists even when + * `F` is not a contravariant functor. Implemented using a List of functions for stack-safety. + */ sealed abstract class ContravariantCoyoneda[F[_], A] extends Serializable { self => - import ContravariantCoyoneda.{Aux, unsafeApply} + import ContravariantCoyoneda.{unsafeApply, Aux} /** The pivot between `fi` and `k`, usually existential. */ type Pivot @@ -41,9 +41,9 @@ sealed abstract class ContravariantCoyoneda[F[_], A] extends Serializable { self object ContravariantCoyoneda { /** - * Lift the `Pivot` type member to a parameter. It is usually more convenient to use `Aux` than - * a refinment type. - */ + * Lift the `Pivot` type member to a parameter. It is usually more convenient to use `Aux` than + * a refinment type. + */ type Aux[F[_], A, B] = ContravariantCoyoneda[F, A] { type Pivot = B } /** `F[A]` converts to `ContravariantCoyoneda[F,A]` for any `F` */ @@ -55,9 +55,9 @@ object ContravariantCoyoneda { unsafeApply(fa)(k0.asInstanceOf[Any => Any] :: Nil) /** - * Creates a `ContravariantCoyoneda[F, A]` for any `F`, taking an `F[A]` and a list of - * [[Contravariant.contramap]]ped functions to apply later - */ + * Creates a `ContravariantCoyoneda[F, A]` for any `F`, taking an `F[A]` and a list of + * [[Contravariant.contramap]]ped functions to apply later + */ private[cats] def unsafeApply[F[_], A, B](fa: F[A])(ks0: List[Any => Any]): Aux[F, B, A] = new ContravariantCoyoneda[F, B] { type Pivot = A diff --git a/free/src/main/scala/cats/free/Coyoneda.scala b/free/src/main/scala/cats/free/Coyoneda.scala index 1b0a3c96432..578bccac0b2 100644 --- a/free/src/main/scala/cats/free/Coyoneda.scala +++ b/free/src/main/scala/cats/free/Coyoneda.scala @@ -4,12 +4,12 @@ package free import cats.arrow.FunctionK /** - * The dual view of the Yoneda lemma. The free functor on `F`. - * This is isomorphic to `F` as long as `F` itself is a functor. - * The function from `F[A]` to `Coyoneda[F,A]` exists even when - * `F` is not a functor. - * Implemented using a List of functions for stack-safety. - */ + * The dual view of the Yoneda lemma. The free functor on `F`. + * This is isomorphic to `F` as long as `F` itself is a functor. + * The function from `F[A]` to `Coyoneda[F,A]` exists even when + * `F` is not a functor. + * Implemented using a List of functions for stack-safety. + */ sealed abstract class Coyoneda[F[_], A] extends Serializable { self => /** The pivot between `fi` and `k`, usually existential. */ @@ -24,7 +24,7 @@ sealed abstract class Coyoneda[F[_], A] extends Serializable { self => /** The list of transformer functions composed into a single function, to be lifted into `F` by `run`. */ final def k: Pivot => A = Function.chain(ks.reverse)(_).asInstanceOf[A] - import Coyoneda.{Aux, unsafeApply} + import Coyoneda.{unsafeApply, Aux} /** Converts to `F[A]` given that `F` is a functor */ final def run(implicit F: Functor[F]): F[A] = F.map(fi)(k) @@ -36,13 +36,13 @@ sealed abstract class Coyoneda[F[_], A] extends Serializable { self => /** Converts to `Yoneda[F,A]` given that `F` is a functor */ final def toYoneda(implicit F: Functor[F]): Yoneda[F, A] = new Yoneda[F, A] { - def apply[B](f: A => B): F[B] = F.map(fi)(k andThen f) + def apply[B](f: A => B): F[B] = F.map(fi)(k.andThen(f)) } /** - * Simple function composition. Allows map fusion without touching - * the underlying `F`. - */ + * Simple function composition. Allows map fusion without touching + * the underlying `F`. + */ final def map[B](f: A => B): Aux[F, B, Pivot] = unsafeApply(fi)(f.asInstanceOf[Any => Any] :: ks) @@ -61,8 +61,8 @@ sealed abstract class Coyoneda[F[_], A] extends Serializable { self => object Coyoneda { /** Lift the `Pivot` type member to a parameter. It is usually more - * convenient to use `Aux` than a structural type. - */ + * convenient to use `Aux` than a structural type. + */ type Aux[F[_], A, B] = Coyoneda[F, A] { type Pivot = B } /** `F[A]` converts to `Coyoneda[F,A]` for any `F` */ @@ -73,8 +73,8 @@ object Coyoneda { unsafeApply(fa)(k0.asInstanceOf[Any => Any] :: Nil) /** Creates a `Coyoneda[F, A]` for any `F`, taking an `F[A]` - * and a list of [[Functor.map]]ped functions to apply later - */ + * and a list of [[Functor.map]]ped functions to apply later + */ private[cats] def unsafeApply[F[_], A, B](fa: F[A])(ks0: List[Any => Any]): Aux[F, B, A] = new Coyoneda[F, B] { type Pivot = A @@ -83,11 +83,11 @@ object Coyoneda { } /** - * As the free functor, `Coyoneda[F, ?]` provides a functor for any `F`. - */ + * As the free functor, `Coyoneda[F, ?]` provides a functor for any `F`. + */ implicit def catsFreeFunctorForCoyoneda[F[_]]: Functor[Coyoneda[F, ?]] = new Functor[Coyoneda[F, ?]] { - def map[A, B](cfa: Coyoneda[F, A])(f: A => B): Coyoneda[F, B] = cfa map f + def map[A, B](cfa: Coyoneda[F, A])(f: A => B): Coyoneda[F, B] = cfa.map(f) } } diff --git a/free/src/main/scala/cats/free/Free.scala b/free/src/main/scala/cats/free/Free.scala index 7951e8c7188..5a343d7f01b 100644 --- a/free/src/main/scala/cats/free/Free.scala +++ b/free/src/main/scala/cats/free/Free.scala @@ -6,43 +6,43 @@ import scala.annotation.tailrec import cats.arrow.FunctionK /** - * A free operational monad for some functor `S`. Binding is done - * using the heap instead of the stack, allowing tail-call - * elimination. - */ + * A free operational monad for some functor `S`. Binding is done + * using the heap instead of the stack, allowing tail-call + * elimination. + */ sealed abstract class Free[S[_], A] extends Product with Serializable { - import Free.{ Pure, Suspend, FlatMapped } + import Free.{FlatMapped, Pure, Suspend} final def map[B](f: A => B): Free[S, B] = flatMap(a => Pure(f(a))) /** - * Modify the functor context `S` using transformation `f`. - * - * This is effectively compiling your free monad into another - * language by changing the suspension functor using the given - * natural transformation `f`. - * - * If your natural transformation is effectful, be careful. These - * effects will be applied by `mapK`. - */ + * Modify the functor context `S` using transformation `f`. + * + * This is effectively compiling your free monad into another + * language by changing the suspension functor using the given + * natural transformation `f`. + * + * If your natural transformation is effectful, be careful. These + * effects will be applied by `mapK`. + */ final def mapK[T[_]](f: S ~> T): Free[T, A] = foldMap[Free[T, ?]] { // this is safe because Free is stack safe λ[FunctionK[S, Free[T, ?]]](fa => Suspend(f(fa))) }(Free.catsFreeMonadForFree) /** - * Bind the given continuation to the result of this computation. - * All left-associated binds are reassociated to the right. - */ + * Bind the given continuation to the result of this computation. + * All left-associated binds are reassociated to the right. + */ final def flatMap[B](f: A => Free[S, B]): Free[S, B] = FlatMapped(this, f) /** - * Catamorphism. Run the first given function if Pure, otherwise, - * the second given function. - */ + * Catamorphism. Run the first given function if Pure, otherwise, + * the second given function. + */ final def fold[B](r: A => B, s: S[Free[S, A]] => B)(implicit S: Functor[S]): B = resume.fold(s, r) @@ -50,63 +50,63 @@ sealed abstract class Free[S[_], A] extends Product with Serializable { @tailrec final def step: Free[S, A] = this match { case FlatMapped(FlatMapped(c, f), g) => c.flatMap(cc => f(cc).flatMap(g)).step - case FlatMapped(Pure(a), f) => f(a).step - case x => x + case FlatMapped(Pure(a), f) => f(a).step + case x => x } /** - * Evaluate a single layer of the free monad. - */ + * Evaluate a single layer of the free monad. + */ @tailrec final def resume(implicit S: Functor[S]): Either[S[Free[S, A]], A] = this match { - case Pure(a) => Right(a) + case Pure(a) => Right(a) case Suspend(t) => Left(S.map(t)(Pure(_))) case FlatMapped(c, f) => c match { - case Pure(a) => f(a).resume - case Suspend(t) => Left(S.map(t)(f)) + case Pure(a) => f(a).resume + case Suspend(t) => Left(S.map(t)(f)) case FlatMapped(d, g) => d.flatMap(dd => g(dd).flatMap(f)).resume } } /** - * A combination of step and fold. - */ - private[free] final def foldStep[B]( + * A combination of step and fold. + */ + final private[free] def foldStep[B]( onPure: A => B, onSuspend: S[A] => B, onFlatMapped: ((S[X], X => Free[S, A]) forSome { type X }) => B ): B = this.step match { - case Pure(a) => onPure(a) - case Suspend(a) => onSuspend(a) + case Pure(a) => onPure(a) + case Suspend(a) => onSuspend(a) case FlatMapped(Suspend(fa), f) => onFlatMapped((fa, f)) - case _ => sys.error("FlatMapped should be right associative after step") + case _ => sys.error("FlatMapped should be right associative after step") } /** - * Run to completion, using a function that extracts the resumption - * from its suspension functor. - */ + * Run to completion, using a function that extracts the resumption + * from its suspension functor. + */ final def go(f: S[Free[S, A]] => Free[S, A])(implicit S: Functor[S]): A = { @tailrec def loop(t: Free[S, A]): A = t.resume match { - case Left(s) => loop(f(s)) + case Left(s) => loop(f(s)) case Right(r) => r } loop(this) } /** - * Run to completion, using the given comonad to extract the - * resumption. - */ + * Run to completion, using the given comonad to extract the + * resumption. + */ final def run(implicit S: Comonad[S]): A = go(S.extract) /** - * Run to completion, using a function that maps the resumption - * from `S` to a monad `M`. - */ + * Run to completion, using a function that maps the resumption + * from `S` to a monad `M`. + */ final def runM[M[_]](f: S[Free[S, A]] => M[Free[S, A]])(implicit S: Functor[S], M: Monad[M]): M[A] = { def step(t: S[Free[S, A]]): M[Either[S[Free[S, A]], A]] = M.map(f(t))(_.resume) @@ -118,9 +118,9 @@ sealed abstract class Free[S[_], A] extends Product with Serializable { } /** - * Run to completion, using monadic recursion to evaluate the - * resumption in the context of `S`. - */ + * Run to completion, using monadic recursion to evaluate the + * resumption in the context of `S`. + */ final def runTailRec(implicit S: Monad[S]): S[A] = { def step(rma: Free[S, A]): S[Either[Free[S, A], A]] = rma match { @@ -142,44 +142,44 @@ sealed abstract class Free[S[_], A] extends Product with Serializable { } /** - * Catamorphism for `Free`. - * - * Run to completion, mapping the suspension with the given - * transformation at each step and accumulating into the monad `M`. - * - * This method uses `tailRecM` to provide stack-safety. - */ + * Catamorphism for `Free`. + * + * Run to completion, mapping the suspension with the given + * transformation at each step and accumulating into the monad `M`. + * + * This method uses `tailRecM` to provide stack-safety. + */ final def foldMap[M[_]](f: FunctionK[S, M])(implicit M: Monad[M]): M[A] = M.tailRecM(this)(_.step match { - case Pure(a) => M.pure(Right(a)) - case Suspend(sa) => M.map(f(sa))(Right(_)) + case Pure(a) => M.pure(Right(a)) + case Suspend(sa) => M.map(f(sa))(Right(_)) case FlatMapped(c, g) => M.map(c.foldMap(f))(cc => Left(g(cc))) }) /** - * Compile your free monad into another language by changing the - * suspension functor using the given natural transformation `f`. - * - * If your natural transformation is effectful, be careful. These - * effects will be applied by `compile`. + * Compile your free monad into another language by changing the + * suspension functor using the given natural transformation `f`. + * + * If your natural transformation is effectful, be careful. These + * effects will be applied by `compile`. */ final def compile[T[_]](f: FunctionK[S, T]): Free[T, A] = mapK(f) /** - * Lift into `G` (typically a `EitherK`) given `InjectK`. Analogous - * to `Free.inject` but lifts programs rather than constructors. - * - *{{{ - *scala> type Lo[A] = cats.data.EitherK[List, Option, A] - *defined type alias Lo - * - *scala> val fo = Free.liftF(Option("foo")) - *fo: cats.free.Free[Option,String] = Free(...) - * - *scala> fo.inject[Lo] - *res4: cats.free.Free[Lo,String] = Free(...) - *}}} - */ + * Lift into `G` (typically a `EitherK`) given `InjectK`. Analogous + * to `Free.inject` but lifts programs rather than constructors. + * + *{{{ + *scala> type Lo[A] = cats.data.EitherK[List, Option, A] + *defined type alias Lo + * + *scala> val fo = Free.liftF(Option("foo")) + *fo: cats.free.Free[Option,String] = Free(...) + * + *scala> fo.inject[Lo] + *res4: cats.free.Free[Lo,String] = Free(...) + *}}} + */ final def inject[G[_]](implicit ev: InjectK[S, G]): Free[G, A] = mapK(λ[S ~> G](ev.inj(_))) @@ -190,79 +190,79 @@ sealed abstract class Free[S[_], A] extends Product with Serializable { object Free extends FreeInstances { /** - * Return from the computation with the given value. - */ - private[free] final case class Pure[S[_], A](a: A) extends Free[S, A] + * Return from the computation with the given value. + */ + final private[free] case class Pure[S[_], A](a: A) extends Free[S, A] /** Suspend the computation with the given suspension. */ - private[free] final case class Suspend[S[_], A](a: S[A]) extends Free[S, A] + final private[free] case class Suspend[S[_], A](a: S[A]) extends Free[S, A] /** Call a subroutine and continue with the given function. */ - private[free] final case class FlatMapped[S[_], B, C](c: Free[S, C], f: C => Free[S, B]) extends Free[S, B] + final private[free] case class FlatMapped[S[_], B, C](c: Free[S, C], f: C => Free[S, B]) extends Free[S, B] /** - * Lift a pure `A` value into the free monad. - */ + * Lift a pure `A` value into the free monad. + */ def pure[S[_], A](a: A): Free[S, A] = Pure(a) /** - * Lift an `F[A]` value into the free monad. - */ + * Lift an `F[A]` value into the free monad. + */ def liftF[F[_], A](value: F[A]): Free[F, A] = Suspend(value) /** - * Absorb a step into the free monad. - */ + * Absorb a step into the free monad. + */ def roll[F[_], A](value: F[Free[F, A]]): Free[F, A] = liftF(value).flatMap(identity) /** - * Suspend the creation of a `Free[F, A]` value. - */ + * Suspend the creation of a `Free[F, A]` value. + */ @deprecated("Use Free.defer.", "1.0.0-MF") def suspend[F[_], A](value: => Free[F, A]): Free[F, A] = defer(value) /** - * Defer the creation of a `Free[F, A]` value. - */ + * Defer the creation of a `Free[F, A]` value. + */ def defer[F[_], A](value: => Free[F, A]): Free[F, A] = pure(()).flatMap(_ => value) /** - * a FunctionK, suitable for composition, which calls mapK - */ + * a FunctionK, suitable for composition, which calls mapK + */ def mapK[F[_], G[_]](fk: FunctionK[F, G]): FunctionK[Free[F, ?], Free[G, ?]] = λ[FunctionK[Free[F, ?], Free[G, ?]]](f => f.mapK(fk)) /** - * a FunctionK, suitable for composition, which calls compile - */ + * a FunctionK, suitable for composition, which calls compile + */ def compile[F[_], G[_]](fk: FunctionK[F, G]): FunctionK[Free[F, ?], Free[G, ?]] = mapK(fk) /** - * a FunctionK, suitable for composition, which calls foldMap - */ + * a FunctionK, suitable for composition, which calls foldMap + */ def foldMap[F[_], M[_]: Monad](fk: FunctionK[F, M]): FunctionK[Free[F, ?], M] = λ[FunctionK[Free[F, ?], M]](f => f.foldMap(fk)) /** - * This method is used to defer the application of an InjectK[F, G] - * instance. The actual work happens in - * `FreeInjectKPartiallyApplied#apply`. - * - * This method exists to allow the `F` and `G` parameters to be - * bound independently of the `A` parameter below. - */ + * This method is used to defer the application of an InjectK[F, G] + * instance. The actual work happens in + * `FreeInjectKPartiallyApplied#apply`. + * + * This method exists to allow the `F` and `G` parameters to be + * bound independently of the `A` parameter below. + */ // TODO to be deprecated / removed in cats 2.0 def inject[F[_], G[_]]: FreeInjectKPartiallyApplied[F, G] = new FreeInjectKPartiallyApplied /** - * Uses the [[http://typelevel.org/cats/guidelines.html#partially-applied-type-params Partially Applied Type Params technique]] for ergonomics. - */ - private[free] final class FreeInjectKPartiallyApplied[F[_], G[_]](val dummy: Boolean = true ) extends AnyVal { + * Uses the [[http://typelevel.org/cats/guidelines.html#partially-applied-type-params Partially Applied Type Params technique]] for ergonomics. + */ + final private[free] class FreeInjectKPartiallyApplied[F[_], G[_]](val dummy: Boolean = true) extends AnyVal { def apply[A](fa: F[A])(implicit I: InjectK[F, G]): Free[G, A] = Free.liftF(I.inj(fa)) } @@ -281,7 +281,7 @@ object Free extends FreeInstances { /** * Uses the [[http://typelevel.org/cats/guidelines.html#partially-applied-type-params Partially Applied Type Params technique]] for ergonomics. */ - private[free] final class FreeLiftInjectKPartiallyApplied[G[_]](val dummy: Boolean = true ) extends AnyVal { + final private[free] class FreeLiftInjectKPartiallyApplied[G[_]](val dummy: Boolean = true) extends AnyVal { def apply[F[_], A](fa: F[A])(implicit I: InjectK[F, G]): Free[G, A] = Free.liftF(I.inj(fa)) } @@ -301,18 +301,18 @@ private trait FreeFoldable[F[_]] extends Foldable[Free[F, ?]] { implicit def F: Foldable[F] - override final def foldLeft[A, B](fa: Free[F, A], b: B)(f: (B, A) => B): B = + final override def foldLeft[A, B](fa: Free[F, A], b: B)(f: (B, A) => B): B = fa.foldStep( a => f(b, a), fa => F.foldLeft(fa, b)(f), { case (fx, g) => F.foldLeft(fx, b)((bb, x) => foldLeft(g(x), bb)(f)) } ) - override final def foldRight[A, B](fa: Free[F, A], lb: Eval[B])(f: (A, Eval[B]) => Eval[B]): Eval[B] = + final override def foldRight[A, B](fa: Free[F, A], lb: Eval[B])(f: (A, Eval[B]) => Eval[B]): Eval[B] = fa.foldStep( a => f(a, lb), fa => F.foldRight(fa, lb)(f), - { case (fx, g) => F.foldRight(fx, lb)( (a, lbb) => foldRight(g(a), lbb)(f)) } + { case (fx, g) => F.foldRight(fx, lb)((a, lbb) => foldRight(g(a), lbb)(f)) } ) } @@ -321,21 +321,21 @@ private trait FreeTraverse[F[_]] extends Traverse[Free[F, ?]] with FreeFoldable[ def F: Foldable[F] = TraversableF - override final def traverse[G[_], A, B](fa: Free[F, A])(f: A => G[B])(implicit G: Applicative[G]): G[Free[F, B]] = + final override def traverse[G[_], A, B](fa: Free[F, A])(f: A => G[B])(implicit G: Applicative[G]): G[Free[F, B]] = fa.resume match { - case Right(a) => G.map(f(a))(Free.pure(_)) + case Right(a) => G.map(f(a))(Free.pure(_)) case Left(ffreeA) => G.map(TraversableF.traverse(ffreeA)(traverse(_)(f)))(Free.roll(_)) } // Override Traverse's map to use Free's map for better performance - override final def map[A, B](fa: Free[F, A])(f: A => B): Free[F, B] = fa.map(f) + final override def map[A, B](fa: Free[F, A])(f: A => B): Free[F, B] = fa.map(f) } -sealed private[free] abstract class FreeInstances extends FreeInstances1 { +sealed abstract private[free] class FreeInstances extends FreeInstances1 { /** - * `Free[S, ?]` has a monad for any type constructor `S[_]`. - */ + * `Free[S, ?]` has a monad for any type constructor `S[_]`. + */ implicit def catsFreeMonadForFree[S[_]]: Monad[Free[S, ?]] = new Monad[Free[S, ?]] with StackSafeMonad[Free[S, ?]] { def pure[A](a: A): Free[S, A] = Free.pure(a) @@ -350,7 +350,7 @@ sealed private[free] abstract class FreeInstances extends FreeInstances1 { } } -sealed private[free] abstract class FreeInstances1 { +sealed abstract private[free] class FreeInstances1 { implicit def catsFreeFoldableForFree[F[_]]( implicit diff --git a/free/src/main/scala/cats/free/FreeApplicative.scala b/free/src/main/scala/cats/free/FreeApplicative.scala index 6b4b2a3012b..4b7e8850e7e 100644 --- a/free/src/main/scala/cats/free/FreeApplicative.scala +++ b/free/src/main/scala/cats/free/FreeApplicative.scala @@ -14,23 +14,21 @@ sealed abstract class FreeApplicative[F[_], A] extends Product with Serializable self => // ap => apply alias needed so we can refer to both // FreeApplicative.ap and FreeApplicative#ap - import FreeApplicative.{FA, Pure, Ap, lift} + import FreeApplicative.{lift, Ap, FA, Pure} - final def ap[B](b: FA[F, A => B]): FA[F, B] = { + final def ap[B](b: FA[F, A => B]): FA[F, B] = b match { case Pure(f) => this.map(f) case _ => Ap(b, this) } - } - final def map[B](f: A => B): FA[F, B] = { + final def map[B](f: A => B): FA[F, B] = this match { case Pure(a) => Pure(f(a)) - case _ => Ap(Pure(f), this) + case _ => Ap(Pure(f), this) } - } final def map2[B, C](fb: FA[F, B])(f: (A, B) => C): FA[F, C] = this match { @@ -38,7 +36,7 @@ sealed abstract class FreeApplicative[F[_], A] extends Product with Serializable case _ => fb match { case Pure(b) => Ap(Pure(f((_: A), b)), this) - case _ => Ap(Ap(Pure((a: A) => (b: B) => f(a, b)), this), fb) + case _ => Ap(Ap(Pure((a: A) => (b: B) => f(a, b)), this), fb) } } @@ -129,7 +127,6 @@ sealed abstract class FreeApplicative[F[_], A] extends Product with Serializable } // scalastyle:on method.length - /** * Interpret/run the operations using the semantics of `Applicative[F]`. * Stack-safe. @@ -146,7 +143,6 @@ sealed abstract class FreeApplicative[F[_], A] extends Product with Serializable λ[FunctionK[F, FA[G, ?]]](fa => lift(f(fa))) } - /** * Interpret this algebra into a FreeApplicative over another algebra. * Stack-safe. @@ -183,16 +179,16 @@ object FreeApplicative { } /** Represents a curried function `F[A => B => C => ...]` - * that has been constructed with chained `ap` calls. - * Fn#argc denotes the amount of curried params remaining. - */ - private final case class Fn[G[_], A, B](gab: G[A => B], argc: Int) + * that has been constructed with chained `ap` calls. + * Fn#argc denotes the amount of curried params remaining. + */ + final private case class Fn[G[_], A, B](gab: G[A => B], argc: Int) - private final case class Pure[F[_], A](a: A) extends FA[F, A] + final private case class Pure[F[_], A](a: A) extends FA[F, A] - private final case class Lift[F[_], A](fa: F[A]) extends FA[F, A] + final private case class Lift[F[_], A](fa: F[A]) extends FA[F, A] - private final case class Ap[F[_], P, A](fn: FA[F, P => A], fp: FA[F, P]) extends FA[F, A] + final private case class Ap[F[_], P, A](fn: FA[F, P => A], fp: FA[F, P]) extends FA[F, A] final def pure[F[_], A](a: A): FA[F, A] = Pure(a) diff --git a/free/src/main/scala/cats/free/FreeInvariantMonoidal.scala b/free/src/main/scala/cats/free/FreeInvariantMonoidal.scala index 7407d7f7504..42c4f86a932 100644 --- a/free/src/main/scala/cats/free/FreeInvariantMonoidal.scala +++ b/free/src/main/scala/cats/free/FreeInvariantMonoidal.scala @@ -5,10 +5,10 @@ import cats.arrow.FunctionK import cats.data.Const /** - * Invariant Monoidal for Free - */ + * Invariant Monoidal for Free + */ sealed abstract class FreeInvariantMonoidal[F[_], A] extends Product with Serializable { self => - import FreeInvariantMonoidal.{FA, Zip, Imap, lift} + import FreeInvariantMonoidal.{lift, FA, Imap, Zip} def imap[B](f: A => B)(g: B => A): FA[F, B] = Imap(this, f, g) @@ -41,22 +41,22 @@ sealed abstract class FreeInvariantMonoidal[F[_], A] extends Product with Serial object FreeInvariantMonoidal { type FA[F[_], A] = FreeInvariantMonoidal[F, A] - private final case class Pure[F[_], A](a: A) extends FA[F, A] { + final private case class Pure[F[_], A](a: A) extends FA[F, A] { def foldMap[G[_]](nt: FunctionK[F, G])(implicit im: InvariantMonoidal[G]): G[A] = im.point(a) } - private final case class Suspend[F[_], A](fa: F[A]) extends FA[F, A] { + final private case class Suspend[F[_], A](fa: F[A]) extends FA[F, A] { def foldMap[G[_]](nt: FunctionK[F, G])(implicit im: InvariantMonoidal[G]): G[A] = nt(fa) } - private final case class Zip[F[_], A, B](fa: FA[F, A], fb: FA[F, B]) extends FA[F, (A, B)] { + final private case class Zip[F[_], A, B](fa: FA[F, A], fb: FA[F, B]) extends FA[F, (A, B)] { def foldMap[G[_]](nt: FunctionK[F, G])(implicit im: InvariantMonoidal[G]): G[(A, B)] = im.product(fa.foldMap(nt), fb.foldMap(nt)) } - private final case class Imap[F[_], A, B](fa: FA[F, A], f: A => B, g: B => A) extends FA[F, B] { + final private case class Imap[F[_], A, B](fa: FA[F, A], f: A => B, g: B => A) extends FA[F, B] { def foldMap[G[_]](nt: FunctionK[F, G])(implicit im: InvariantMonoidal[G]): G[B] = im.imap(fa.foldMap(nt))(f)(g) } diff --git a/free/src/main/scala/cats/free/FreeT.scala b/free/src/main/scala/cats/free/FreeT.scala index 9b2882cfe8e..46b6dec3d8d 100644 --- a/free/src/main/scala/cats/free/FreeT.scala +++ b/free/src/main/scala/cats/free/FreeT.scala @@ -6,15 +6,15 @@ import scala.annotation.tailrec import cats.arrow.FunctionK /** - * FreeT is a monad transformer for Free monads over a Functor S - * - * Stack safety for `Free` and `FreeT` is based on the paper - * [[http://functorial.com/stack-safety-for-free/index.pdf Stack Safety for Free]] by Phil Freeman - * - * This Scala implementation of `FreeT` and its usages are derived from - * [[https://github.com/scalaz/scalaz/blob/series/7.3.x/core/src/main/scala/scalaz/FreeT.scala Scalaz's FreeT]], - * originally written by Brian McKenna. - */ + * FreeT is a monad transformer for Free monads over a Functor S + * + * Stack safety for `Free` and `FreeT` is based on the paper + * [[http://functorial.com/stack-safety-for-free/index.pdf Stack Safety for Free]] by Phil Freeman + * + * This Scala implementation of `FreeT` and its usages are derived from + * [[https://github.com/scalaz/scalaz/blob/series/7.3.x/core/src/main/scala/scalaz/FreeT.scala Scalaz's FreeT]], + * originally written by Brian McKenna. + */ sealed abstract class FreeT[S[_], M[_], A] extends Product with Serializable { import FreeT._ @@ -37,8 +37,8 @@ sealed abstract class FreeT[S[_], M[_], A] extends Product with Serializable { FlatMapped(this, f) /** - * Changes the underlying `Monad` for this `FreeT`, ie. - * turning this `FreeT[S, M, A]` into a `FreeT[S, N, A]`. + * Changes the underlying `Monad` for this `FreeT`, ie. + * turning this `FreeT[S, M, A]` into a `FreeT[S, N, A]`. */ def hoist[N[_]](mn: FunctionK[M, N]): FreeT[S, N, A] = mapK(mn) @@ -56,23 +56,26 @@ sealed abstract class FreeT[S[_], M[_], A] extends Product with Serializable { } /** - * Runs to completion, mapping the suspension with the given transformation - * at each step and accumulating into the monad `M`. - */ + * Runs to completion, mapping the suspension with the given transformation + * at each step and accumulating into the monad `M`. + */ def foldMap(f: FunctionK[S, M])(implicit M: Monad[M]): M[A] = { def go(ft: FreeT[S, M, A]): M[Either[FreeT[S, M, A], A]] = ft match { - case Suspend(ma) => M.flatMap(ma) { - case Right(a) => M.pure(Right(a)) - case Left(sa) => M.map(f(sa))(Right(_)) - } - case g @ FlatMapped(_, _) => g.a match { - case Suspend(mx) => M.flatMap(mx) { - case Right(x) => M.pure(Left(g.f(x))) - case Left(sx) => M.map(f(sx))(x => Left(g.f(x))) + case Suspend(ma) => + M.flatMap(ma) { + case Right(a) => M.pure(Right(a)) + case Left(sa) => M.map(f(sa))(Right(_)) + } + case g @ FlatMapped(_, _) => + g.a match { + case Suspend(mx) => + M.flatMap(mx) { + case Right(x) => M.pure(Left(g.f(x))) + case Left(sx) => M.map(f(sx))(x => Left(g.f(x))) + } + case g0 @ FlatMapped(_, _) => M.pure(Left(g0.a.flatMap(g0.f(_).flatMap(g.f)))) } - case g0 @ FlatMapped(_, _) => M.pure(Left(g0.a.flatMap(g0.f(_).flatMap(g.f)))) - } } M.tailRecM(this)(go) @@ -83,21 +86,23 @@ sealed abstract class FreeT[S[_], M[_], A] extends Product with Serializable { def go(ft: FreeT[S, M, A]): M[Either[FreeT[S, M, A], Either[S[FreeT[S, M, A]], A]]] = ft match { case Suspend(f) => M.map(f)(as => Right(as.left.map(S.map(_)(pure(_))))) - case g1 @ FlatMapped(_, _) => g1.a match { - case Suspend(m1) => M.map(m1) { - case Right(a) => Left(g1.f(a)) - case Left(fc) => Right(Left(S.map(fc)(g1.f(_)))) + case g1 @ FlatMapped(_, _) => + g1.a match { + case Suspend(m1) => + M.map(m1) { + case Right(a) => Left(g1.f(a)) + case Left(fc) => Right(Left(S.map(fc)(g1.f(_)))) + } + case g2 @ FlatMapped(_, _) => M.pure(Left(g2.a.flatMap(g2.f(_).flatMap(g1.f)))) } - case g2 @ FlatMapped(_, _) => M.pure(Left(g2.a.flatMap(g2.f(_).flatMap(g1.f)))) - } } M.tailRecM(this)(go) } /** - * Runs to completion, using a function that maps the resumption from `S` to a monad `M`. - */ + * Runs to completion, using a function that maps the resumption from `S` to a monad `M`. + */ def runM(interp: S[FreeT[S, M, A]] => M[FreeT[S, M, A]])(implicit S: Functor[S], M: Monad[M]): M[A] = { def runM2(ft: FreeT[S, M, A]): M[Either[FreeT[S, M, A], A]] = M.flatMap(ft.resume) { @@ -108,33 +113,37 @@ sealed abstract class FreeT[S[_], M[_], A] extends Product with Serializable { } /** - * Finds the first `M` instance, `m`, and maps it to contain the rest - * of the computation. Since only `map` is used on `m`, its structure - * is preserved. - */ + * Finds the first `M` instance, `m`, and maps it to contain the rest + * of the computation. Since only `map` is used on `m`, its structure + * is preserved. + */ @tailrec - private[cats] final def toM(implicit M: Applicative[M]): M[FreeT[S, M, A]] = + final private[cats] def toM(implicit M: Applicative[M]): M[FreeT[S, M, A]] = this match { - case Suspend(m) => M.map(m) { - case Right(a) => pure(a) - case Left(s) => liftF(s) - } - case g1 @ FlatMapped(_, _) => g1.a match { - case Suspend(m) => M.map(m) { - case Right(a) => g1.f(a) - case Left(s) => liftF[S, M, g1.A](s).flatMap(g1.f) + case Suspend(m) => + M.map(m) { + case Right(a) => pure(a) + case Left(s) => liftF(s) + } + case g1 @ FlatMapped(_, _) => + g1.a match { + case Suspend(m) => + M.map(m) { + case Right(a) => g1.f(a) + case Left(s) => liftF[S, M, g1.A](s).flatMap(g1.f) + } + case g0 @ FlatMapped(_, _) => g0.a.flatMap(g0.f(_).flatMap(g1.f)).toM } - case g0 @ FlatMapped(_, _) => g0.a.flatMap(g0.f(_).flatMap(g1.f)).toM - } } @tailrec private def step: FreeT[S, M, A] = this match { - case g @ FlatMapped(_, _) => g.a match { - case g0 @ FlatMapped(_, _) => g0.a.flatMap(a => g0.f(a).flatMap(g.f)).step - case _ => g - } + case g @ FlatMapped(_, _) => + g.a match { + case g0 @ FlatMapped(_, _) => g0.a.flatMap(a => g0.f(a).flatMap(g.f)).step + case _ => g + } case x => x } @@ -142,11 +151,13 @@ sealed abstract class FreeT[S[_], M[_], A] extends Product with Serializable { } object FreeT extends FreeTInstances { + /** Suspend the computation with the given suspension. */ private[free] case class Suspend[S[_], M[_], A](a: M[Either[S[A], A]]) extends FreeT[S, M, A] /** Call a subroutine and continue with the given function. */ - private[free] case class FlatMapped[S[_], M[_], A0, B](a0: FreeT[S, M, A0], f0: A0 => FreeT[S, M, B]) extends FreeT[S, M, B] { + private[free] case class FlatMapped[S[_], M[_], A0, B](a0: FreeT[S, M, A0], f0: A0 => FreeT[S, M, B]) + extends FreeT[S, M, B] { type A = A0 def a: FreeT[S, M, A] = a0 def f: A => FreeT[S, M, B] = f0 @@ -161,7 +172,7 @@ object FreeT extends FreeTInstances { def defer[S[_], M[_], A](a: M[Either[A, S[FreeT[S, M, A]]]])(implicit M: Applicative[M]): FreeT[S, M, A] = liftT(a).flatMap({ - case Left(a) => pure(a) + case Left(a) => pure(a) case Right(s) => roll(s) }) @@ -201,13 +212,13 @@ object FreeT extends FreeTInstances { /** * Uses the [[http://typelevel.org/cats/guidelines.html#partially-applied-type-params Partially Applied Type Params technique]] for ergonomics. */ - private[free] final class FreeTLiftInjectKPartiallyApplied[M[_], G[_]](val dummy: Boolean = true ) extends AnyVal { + final private[free] class FreeTLiftInjectKPartiallyApplied[M[_], G[_]](val dummy: Boolean = true) extends AnyVal { def apply[F[_], A](fa: F[A])(implicit I: InjectK[F, G], m: Applicative[M]): FreeT[G, M, A] = FreeT.liftF[G, M, A](I.inj(fa)) } } -private[free] sealed abstract class FreeTInstances extends FreeTInstances0 { +sealed abstract private[free] class FreeTInstances extends FreeTInstances0 { implicit def catsFreeMonadErrorForFreeT[S[_], M[_], E](implicit E: MonadError[M, E]): MonadError[FreeT[S, M, ?], E] = new MonadError[FreeT[S, M, ?], E] with FreeTMonad[S, M] { override def M = E @@ -218,21 +229,21 @@ private[free] sealed abstract class FreeTInstances extends FreeTInstances0 { } } -private[free] sealed abstract class FreeTInstances0 extends FreeTInstances1 { +sealed abstract private[free] class FreeTInstances0 extends FreeTInstances1 { implicit def catsFreeMonadForFreeT[S[_], M[_]](implicit M0: Applicative[M]): Monad[FreeT[S, M, ?]] = new FreeTMonad[S, M] { def M = M0 } } -private[free] sealed abstract class FreeTInstances1 extends FreeTInstances2 { +sealed abstract private[free] class FreeTInstances1 extends FreeTInstances2 { implicit def catsFreeFlatMapForFreeT[S[_], M[_]](implicit M0: Applicative[M]): FlatMap[FreeT[S, M, ?]] = new FreeTFlatMap[S, M] { implicit def M: Applicative[M] = M0 } } -private[free] sealed abstract class FreeTInstances2 extends FreeTInstances3 { +sealed abstract private[free] class FreeTInstances2 extends FreeTInstances3 { implicit def catsFreeAlternativeForFreeT[S[_], M[_]: Alternative: Monad]: Alternative[FreeT[S, M, ?]] = new Alternative[FreeT[S, M, ?]] with FreeTMonad[S, M] with FreeTMonoidK[S, M] { override def M = Alternative[M] @@ -240,7 +251,7 @@ private[free] sealed abstract class FreeTInstances2 extends FreeTInstances3 { } } -private[free] sealed abstract class FreeTInstances3 { +sealed abstract private[free] class FreeTInstances3 { implicit def catsFreeSemigroupKForFreeT[S[_], M[_]: Applicative: SemigroupK]: SemigroupK[FreeT[S, M, ?]] = new FreeTSemigroupK[S, M] { override def M = Applicative[M] @@ -248,31 +259,31 @@ private[free] sealed abstract class FreeTInstances3 { } } -private[free] sealed trait FreeTFlatMap[S[_], M[_]] extends FlatMap[FreeT[S, M, ?]] { +sealed private[free] trait FreeTFlatMap[S[_], M[_]] extends FlatMap[FreeT[S, M, ?]] { implicit def M: Applicative[M] - override final def map[A, B](fa: FreeT[S, M, A])(f: A => B): FreeT[S, M, B] = fa.map(f) + final override def map[A, B](fa: FreeT[S, M, A])(f: A => B): FreeT[S, M, B] = fa.map(f) def flatMap[A, B](fa: FreeT[S, M, A])(f: A => FreeT[S, M, B]): FreeT[S, M, B] = fa.flatMap(f) - override final def tailRecM[A, B](a: A)(f: A => FreeT[S, M, Either[A, B]]): FreeT[S, M, B] = + final override def tailRecM[A, B](a: A)(f: A => FreeT[S, M, Either[A, B]]): FreeT[S, M, B] = FreeT.tailRecM(a)(f) } -private[free] sealed trait FreeTMonad[S[_], M[_]] extends Monad[FreeT[S, M, ?]] with FreeTFlatMap[S, M] { +sealed private[free] trait FreeTMonad[S[_], M[_]] extends Monad[FreeT[S, M, ?]] with FreeTFlatMap[S, M] { implicit def M: Applicative[M] - override final def pure[A](a: A): FreeT[S, M, A] = + final override def pure[A](a: A): FreeT[S, M, A] = FreeT.pure[S, M, A](a) } -private[free] sealed trait FreeTMonoidK[S[_], M[_]] extends MonoidK[FreeT[S, M, ?]] with FreeTSemigroupK[S, M] { +sealed private[free] trait FreeTMonoidK[S[_], M[_]] extends MonoidK[FreeT[S, M, ?]] with FreeTSemigroupK[S, M] { implicit def M: Applicative[M] def M1: MonoidK[M] - override final def empty[A]: FreeT[S, M, A] = FreeT.liftT[S, M, A](M1.empty[A])(M) + final override def empty[A]: FreeT[S, M, A] = FreeT.liftT[S, M, A](M1.empty[A])(M) } -private[free] sealed trait FreeTSemigroupK[S[_], M[_]] extends SemigroupK[FreeT[S, M, ?]] { +sealed private[free] trait FreeTSemigroupK[S[_], M[_]] extends SemigroupK[FreeT[S, M, ?]] { implicit def M: Applicative[M] def M1: SemigroupK[M] - override final def combineK[A](a: FreeT[S, M, A], b: FreeT[S, M, A]): FreeT[S, M, A] = + final override def combineK[A](a: FreeT[S, M, A], b: FreeT[S, M, A]): FreeT[S, M, A] = FreeT.liftT(M1.combineK(a.toM, b.toM))(M).flatMap(identity) } diff --git a/free/src/main/scala/cats/free/Trampoline.scala b/free/src/main/scala/cats/free/Trampoline.scala index f7473d193ab..026ffa2e892 100644 --- a/free/src/main/scala/cats/free/Trampoline.scala +++ b/free/src/main/scala/cats/free/Trampoline.scala @@ -3,7 +3,7 @@ package free // To workaround SI-7139 `object Trampoline` needs to be defined inside the package object // together with the type alias. -private[free] abstract class TrampolineFunctions { +abstract private[free] class TrampolineFunctions { def done[A](a: A): Trampoline[A] = Free.pure[Function0, A](a) @@ -17,4 +17,3 @@ private[free] abstract class TrampolineFunctions { def delay[A](a: => A): Trampoline[A] = defer(done(a)) } - diff --git a/free/src/main/scala/cats/free/Yoneda.scala b/free/src/main/scala/cats/free/Yoneda.scala index 841435b7f4f..5869bf16ec0 100644 --- a/free/src/main/scala/cats/free/Yoneda.scala +++ b/free/src/main/scala/cats/free/Yoneda.scala @@ -2,36 +2,36 @@ package cats package free /** - * The cofree functor for `F`. The Yoneda lemma says that - * `Yoneda[F,A]` is isomorphic to `F[A]` for any functor `F`. - * The function from `Yoneda[F, A]` to `F[A]` exists even when - * we have forgotten that `F` is a functor. - * Can be seen as a partially applied `map` for the functor `F`. - */ + * The cofree functor for `F`. The Yoneda lemma says that + * `Yoneda[F,A]` is isomorphic to `F[A]` for any functor `F`. + * The function from `Yoneda[F, A]` to `F[A]` exists even when + * we have forgotten that `F` is a functor. + * Can be seen as a partially applied `map` for the functor `F`. + */ abstract class Yoneda[F[_], A] extends Serializable { self => def apply[B](f: A => B): F[B] /** - * Converts to `F[A]` even without a `Functor` instance for `F`. - */ + * Converts to `F[A]` even without a `Functor` instance for `F`. + */ def run: F[A] = apply(a => a) /** - * Converts to `Coyoneda[F,A]` even without a `Functor` instance for `F`. - */ + * Converts to `Coyoneda[F,A]` even without a `Functor` instance for `F`. + */ def toCoyoneda: Coyoneda.Aux[F, A, A] = Coyoneda(run)(identity[A]) /** - * Simple function composition. Allows map fusion without traversing an `F`. - */ + * Simple function composition. Allows map fusion without traversing an `F`. + */ def map[B](f: A => B): Yoneda[F, B] = new Yoneda[F, B] { - def apply[C](g: B => C): F[C] = self(f andThen g) + def apply[C](g: B => C): F[C] = self(f.andThen(g)) } /** - * Modify the context `F` using transformation `f`. - */ + * Modify the context `F` using transformation `f`. + */ def mapK[G[_]](f: F ~> G): Yoneda[G, A] = new Yoneda[G, A] { def apply[B](g: A => B): G[B] = f(self(g)) @@ -41,16 +41,16 @@ abstract class Yoneda[F[_], A] extends Serializable { self => object Yoneda { /** - * `Yoneda[F, _]` is a functor for any `F`. - */ + * `Yoneda[F, _]` is a functor for any `F`. + */ implicit def catsFreeFunctorForYoneda[F[_]]: Functor[Yoneda[F, ?]] = new Functor[Yoneda[F, ?]] { - def map[A, B](ya: Yoneda[F, A])(f: A => B): Yoneda[F, B] = ya map f + def map[A, B](ya: Yoneda[F, A])(f: A => B): Yoneda[F, B] = ya.map(f) } /** - * `F[A]` converts to `Yoneda[F, A]` for any functor `F`. - */ + * `F[A]` converts to `Yoneda[F, A]` for any functor `F`. + */ def apply[F[_], A](fa: F[A])(implicit F: Functor[F]): Yoneda[F, A] = new Yoneda[F, A] { def apply[B](f: A => B): F[B] = F.map(fa)(f) diff --git a/free/src/main/scala/cats/free/package.scala b/free/src/main/scala/cats/free/package.scala index 2942a76ac42..26d512c0ac3 100644 --- a/free/src/main/scala/cats/free/package.scala +++ b/free/src/main/scala/cats/free/package.scala @@ -1,6 +1,7 @@ package cats package object free { + /** Alias for the free monad over the `Function0` functor. */ type Trampoline[A] = Free[Function0, A] object Trampoline extends TrampolineFunctions diff --git a/free/src/test/scala/cats/free/CofreeSuite.scala b/free/src/test/scala/cats/free/CofreeSuite.scala index fc2f27512b7..6bbf13c6d90 100644 --- a/free/src/test/scala/cats/free/CofreeSuite.scala +++ b/free/src/test/scala/cats/free/CofreeSuite.scala @@ -2,7 +2,7 @@ package cats package free import cats.data.{NonEmptyList, OptionT} -import cats.laws.discipline.{SemigroupalTests, ComonadTests, ReducibleTests, SerializableTests, TraverseTests} +import cats.laws.discipline.{ComonadTests, ReducibleTests, SemigroupalTests, SerializableTests, TraverseTests} import cats.syntax.list._ import cats.tests.{CatsSuite, Spooky} import org.scalacheck.{Arbitrary, Cogen, Gen} @@ -33,7 +33,9 @@ class CofreeSuite extends CatsSuite { } test("Cofree.ana") { - val anaHundred: CofreeNel[Int] = Cofree.ana[Option, List[Int], Int](List.tabulate(101)(identity))(l => if (l.tail.isEmpty) None else Some(l.tail), _.head) + val anaHundred: CofreeNel[Int] = + Cofree.ana[Option, List[Int], Int](List.tabulate(101)(identity))(l => if (l.tail.isEmpty) None else Some(l.tail), + _.head) val nelUnfoldedHundred: NonEmptyList[Int] = NonEmptyList.fromListUnsafe(List.tabulate(101)(identity)) cofNelToNel(anaHundred) should ===(nelUnfoldedHundred) } @@ -41,7 +43,9 @@ class CofreeSuite extends CatsSuite { test("Cofree.tailForced") { val spooky = new Spooky val incrementor = - Cofree.unfold[Id, Int](spooky.counter) { _ => spooky.increment(); spooky.counter } + Cofree.unfold[Id, Int](spooky.counter) { _ => + spooky.increment(); spooky.counter + } spooky.counter should ===(0) incrementor.tailForced spooky.counter should ===(1) @@ -50,7 +54,9 @@ class CofreeSuite extends CatsSuite { test("Cofree.forceTail") { val spooky = new Spooky val incrementor = - Cofree.unfold[Id, Int](spooky.counter) { _ => spooky.increment(); spooky.counter } + Cofree.unfold[Id, Int](spooky.counter) { _ => + spooky.increment(); spooky.counter + } spooky.counter should ===(0) incrementor.forceTail spooky.counter should ===(1) @@ -59,13 +65,15 @@ class CofreeSuite extends CatsSuite { test("Cofree.forceAll") { val spooky = new Spooky val incrementor = - Cofree.unfold[Option, Int](spooky.counter)(i => - if (i == 5) { - None - } else { - spooky.increment() - Some(spooky.counter) - }) + Cofree.unfold[Option, Int](spooky.counter)( + i => + if (i == 5) { + None + } else { + spooky.increment() + Some(spooky.counter) + } + ) spooky.counter should ===(0) incrementor.forceAll spooky.counter should ===(5) @@ -92,9 +100,11 @@ class CofreeSuite extends CatsSuite { test("Cofree.cata") { val cata = - Cofree.cata[Option, Int, NonEmptyList[Int]](unfoldedHundred)( - (i, lb) => Eval.now(NonEmptyList(i, lb.fold[List[Int]](Nil)(_.toList))) - ).value + Cofree + .cata[Option, Int, NonEmptyList[Int]](unfoldedHundred)( + (i, lb) => Eval.now(NonEmptyList(i, lb.fold[List[Int]](Nil)(_.toList))) + ) + .value cata should ===(nelUnfoldedHundred) } @@ -109,9 +119,12 @@ class CofreeSuite extends CatsSuite { val cataHundred = Cofree.cataM[Option, EvalOption, Int, NonEmptyList[Int]](unfoldedHundred)(folder)(inclusion).value.value val cataHundredOne = - Cofree.cataM[Option, EvalOption, Int, NonEmptyList[Int]]( - Cofree[Option, Int](101, Eval.now(Some(unfoldedHundred))) - )(folder)(inclusion).value.value + Cofree + .cataM[Option, EvalOption, Int, NonEmptyList[Int]]( + Cofree[Option, Int](101, Eval.now(Some(unfoldedHundred))) + )(folder)(inclusion) + .value + .value cataHundred should ===(Some(nelUnfoldedHundred)) cataHundredOne should ===(None) } @@ -130,14 +143,13 @@ sealed trait CofreeSuiteInstances { def tr(a: CofreeNel[A], b: CofreeNel[A]): Boolean = (a.tailForced, b.tailForced) match { case (Some(at), Some(bt)) if e.eqv(a.head, b.head) => tr(at, bt) - case (None, None) if e.eqv(a.head, b.head) => true - case _ => false + case (None, None) if e.eqv(a.head, b.head) => true + case _ => false } tr(a, b) } } - implicit def CofreeOptionCogen[A: Cogen]: Cogen[CofreeNel[A]] = implicitly[Cogen[List[A]]].contramap[CofreeNel[A]](cofNelToNel(_).toList) @@ -146,19 +158,21 @@ sealed trait CofreeSuiteInstances { Gen.resize(20, Gen.nonEmptyListOf(implicitly[Arbitrary[A]].arbitrary)) } Arbitrary { - arb.arbitrary.map(l => (l.head, l.tail) match { - case (h, Nil) => nelToCofNel(NonEmptyList(h, Nil)) - case (h, t) => nelToCofNel(NonEmptyList(h, t)) - }) + arb.arbitrary.map( + l => + (l.head, l.tail) match { + case (h, Nil) => nelToCofNel(NonEmptyList(h, Nil)) + case (h, t) => nelToCofNel(NonEmptyList(h, t)) + } + ) } } - val nelToCofNel = λ[NonEmptyList ~> CofreeNel](fa => - Cofree(fa.head, Eval.later(fa.tail.toNel.map(apply)))) + val nelToCofNel = λ[NonEmptyList ~> CofreeNel](fa => Cofree(fa.head, Eval.later(fa.tail.toNel.map(apply)))) - val cofNelToNel = λ[CofreeNel ~> NonEmptyList](fa => - NonEmptyList(fa.head, fa.tailForced.map(apply(_).toList).getOrElse(Nil))) + val cofNelToNel = + λ[CofreeNel ~> NonEmptyList](fa => NonEmptyList(fa.head, fa.tailForced.map(apply(_).toList).getOrElse(Nil))) - val cofRoseTreeToNel = λ[CofreeRoseTree ~> NonEmptyList](fa => - NonEmptyList(fa.head, fa.tailForced.flatMap(apply(_).toList))) + val cofRoseTreeToNel = + λ[CofreeRoseTree ~> NonEmptyList](fa => NonEmptyList(fa.head, fa.tailForced.flatMap(apply(_).toList))) } diff --git a/free/src/test/scala/cats/free/ContravariantCoyonedaSuite.scala b/free/src/test/scala/cats/free/ContravariantCoyonedaSuite.scala index a9c95789cfe..f9284f7e2f2 100644 --- a/free/src/test/scala/cats/free/ContravariantCoyonedaSuite.scala +++ b/free/src/test/scala/cats/free/ContravariantCoyonedaSuite.scala @@ -3,9 +3,9 @@ package free import cats.arrow.FunctionK import cats.tests.CatsSuite -import cats.laws.discipline.{ ContravariantTests, SerializableTests } +import cats.laws.discipline.{ContravariantTests, SerializableTests} -import org.scalacheck.{ Arbitrary } +import org.scalacheck.{Arbitrary} class ContravariantCoyonedaSuite extends CatsSuite { @@ -16,8 +16,7 @@ class ContravariantCoyonedaSuite extends CatsSuite { Arbitrary(F.arbitrary.map(ContravariantCoyoneda.lift[? => T, A](_))) // We can't really test that functions are equal but we can try it with a bunch of test data. - implicit def contravariantCoyonedaEq[A: Arbitrary, T]( - implicit eqft: Eq[T]): Eq[ContravariantCoyoneda[? => T, A]] = + implicit def contravariantCoyonedaEq[A: Arbitrary, T](implicit eqft: Eq[T]): Eq[ContravariantCoyoneda[? => T, A]] = new Eq[ContravariantCoyoneda[? => T, A]] { def eqv(cca: ContravariantCoyoneda[? => T, A], ccb: ContravariantCoyoneda[? => T, A]): Boolean = Arbitrary.arbitrary[List[A]].sample.get.forall { a => @@ -30,8 +29,10 @@ class ContravariantCoyonedaSuite extends CatsSuite { implicit val contravariantContravariantCoyonedaToString: Contravariant[ContravariantCoyoneda[? => String, ?]] = ContravariantCoyoneda.catsFreeContravariantFunctorForContravariantCoyoneda[? => String] - checkAll("ContravariantCoyoneda[? => String, Int]", ContravariantTests[ContravariantCoyoneda[? => String, ?]].contravariant[Int, Int, Int]) - checkAll("Contravariant[ContravariantCoyoneda[Option, ?]]", SerializableTests.serializable(Contravariant[ContravariantCoyoneda[Option, ?]])) + checkAll("ContravariantCoyoneda[? => String, Int]", + ContravariantTests[ContravariantCoyoneda[? => String, ?]].contravariant[Int, Int, Int]) + checkAll("Contravariant[ContravariantCoyoneda[Option, ?]]", + SerializableTests.serializable(Contravariant[ContravariantCoyoneda[Option, ?]])) test("mapK and run is same as applying natural trans") { forAll { (b: Boolean) => @@ -47,7 +48,8 @@ class ContravariantCoyonedaSuite extends CatsSuite { .lift[? => Int, String](_.count(_ == 'x')) .contramap((s: String) => s + "x") .contramap((s: String) => s * 3) - .run.apply("foo") === 3 + .run + .apply("foo") === 3 } test("stack-safe contramapmap") { @@ -58,15 +60,16 @@ class ContravariantCoyonedaSuite extends CatsSuite { } test("run, foldMap consistent") { - forAll { ( - c: ContravariantCoyoneda[? => Int, String], - f: Byte => String, - g: Float => Byte, - s: Float - ) => - val cʹ = c.contramap(f).contramap(g) // just to ensure there's some structure - val h = cʹ.foldMap[? => Int](FunctionK.id[? => Int]) - cʹ.run.apply(s) === h(s) + forAll { + ( + c: ContravariantCoyoneda[? => Int, String], + f: Byte => String, + g: Float => Byte, + s: Float + ) => + val cʹ = c.contramap(f).contramap(g) // just to ensure there's some structure + val h = cʹ.foldMap[? => Int](FunctionK.id[? => Int]) + cʹ.run.apply(s) === h(s) } } diff --git a/free/src/test/scala/cats/free/CoyonedaSuite.scala b/free/src/test/scala/cats/free/CoyonedaSuite.scala index 89dcd9fc6d7..a52c92d33a0 100644 --- a/free/src/test/scala/cats/free/CoyonedaSuite.scala +++ b/free/src/test/scala/cats/free/CoyonedaSuite.scala @@ -8,7 +8,7 @@ import cats.laws.discipline.{FunctorTests, SerializableTests} import org.scalacheck.Arbitrary class CoyonedaSuite extends CatsSuite { - implicit def coyonedaArbitrary[F[_] : Functor, A : Arbitrary](implicit F: Arbitrary[F[A]]): Arbitrary[Coyoneda[F, A]] = + implicit def coyonedaArbitrary[F[_]: Functor, A: Arbitrary](implicit F: Arbitrary[F[A]]): Arbitrary[Coyoneda[F, A]] = Arbitrary(F.arbitrary.map(Coyoneda.lift)) implicit def coyonedaEq[F[_]: Functor, A](implicit FA: Eq[F[A]]): Eq[Coyoneda[F, A]] = @@ -19,17 +19,17 @@ class CoyonedaSuite extends CatsSuite { checkAll("Coyoneda[Option, ?]", FunctorTests[Coyoneda[Option, ?]].functor[Int, Int, Int]) checkAll("Functor[Coyoneda[Option, ?]]", SerializableTests.serializable(Functor[Coyoneda[Option, ?]])) - test("toYoneda and then toCoyoneda is identity"){ - forAll{ (y: Coyoneda[Option, Int]) => - y.toYoneda.toCoyoneda should === (y) + test("toYoneda and then toCoyoneda is identity") { + forAll { (y: Coyoneda[Option, Int]) => + y.toYoneda.toCoyoneda should ===(y) } } test("mapK and run is same as applying natural trans") { - val nt = λ[FunctionK[Option, List]](_.toList) - val o = Option("hello") - val c = Coyoneda.lift(o) - c.mapK(nt).run should === (nt(o)) + val nt = λ[FunctionK[Option, List]](_.toList) + val o = Option("hello") + val c = Coyoneda.lift(o) + c.mapK(nt).run should ===(nt(o)) } test("map order") { diff --git a/free/src/test/scala/cats/free/FreeApplicativeSuite.scala b/free/src/test/scala/cats/free/FreeApplicativeSuite.scala index 2cc74462f8a..11cb79308c3 100644 --- a/free/src/test/scala/cats/free/FreeApplicativeSuite.scala +++ b/free/src/test/scala/cats/free/FreeApplicativeSuite.scala @@ -3,7 +3,7 @@ package free import cats.tests.CatsSuite import cats.arrow.FunctionK -import cats.laws.discipline.{SemigroupalTests, ApplicativeTests, SerializableTests} +import cats.laws.discipline.{ApplicativeTests, SemigroupalTests, SerializableTests} import cats.data.State import org.scalacheck.{Arbitrary, Gen} @@ -14,7 +14,8 @@ class FreeApplicativeSuite extends CatsSuite { implicit val iso = SemigroupalTests.Isomorphisms.invariant[FreeApplicative[Option, ?]] checkAll("FreeApplicative[Option, ?]", ApplicativeTests[FreeApplicative[Option, ?]].applicative[Int, Int, Int]) - checkAll("Applicative[FreeApplicative[Option, ?]]", SerializableTests.serializable(Applicative[FreeApplicative[Option, ?]])) + checkAll("Applicative[FreeApplicative[Option, ?]]", + SerializableTests.serializable(Applicative[FreeApplicative[Option, ?]])) test("toString is stack-safe") { val r = FreeApplicative.pure[List, Int](333) @@ -25,9 +26,9 @@ class FreeApplicativeSuite extends CatsSuite { test("fold/map is stack-safe") { val r = FreeApplicative.lift[List, Int](List(333)) val rr = (1 to 70000).foldLeft(r)((r, _) => r.ap(FreeApplicative.lift[List, Int => Int](List((_: Int) + 1)))) - rr.fold should be (List(333 + 70000)) + rr.fold should be(List(333 + 70000)) val rx = (1 to 70000).foldRight(r)((_, r) => r.ap(FreeApplicative.lift[List, Int => Int](List((_: Int) + 1)))) - rx.fold should be (List(333 + 70000)) + rx.fold should be(List(333 + 70000)) } test("FreeApplicative#fold") { @@ -39,7 +40,7 @@ class FreeApplicativeSuite extends CatsSuite { val y = FreeApplicative.pure[Option, Int](n) val f = x.map(i => (j: Int) => i + j) val r = y.ap(f) - r.fold should === (Apply[Option].map2(o1, o2)(_ + _)) + r.fold should ===(Apply[Option].map2(o1, o2)(_ + _)) } test("FreeApplicative#compile") { @@ -52,20 +53,20 @@ class FreeApplicativeSuite extends CatsSuite { forAll { (x: FreeApplicative[Option, Int]) => val nt = λ[FunctionK[Option, FreeApplicative[Option, ?]]](FreeApplicative.lift(_)) - x.foldMap[FreeApplicative[Option, ?]](nt).fold should === (x.flatCompile[Option](nt).fold) + x.foldMap[FreeApplicative[Option, ?]](nt).fold should ===(x.flatCompile[Option](nt).fold) } } test("FreeApplicative#monad") { forAll { (x: FreeApplicative[List, Int]) => - x.monad.foldMap(FunctionK.id) should === (x.fold) + x.monad.foldMap(FunctionK.id) should ===(x.fold) } } test("FreeApplicative#ap") { val x = FreeApplicative.ap[Id, Int, Int](1)(FreeApplicative.pure((_: Int) + 1)) val y = FreeApplicative.lift[Id, Int](1).ap(FreeApplicative.pure((_: Int) + 1)) - x should === (y) + x should ===(y) } // Ensure that syntax and implicit resolution work as expected. @@ -83,10 +84,10 @@ class FreeApplicativeSuite extends CatsSuite { val countingNT = λ[FunctionK[List, G]](la => List(la.length)) val fli1 = FreeApplicative.lift[List, Int](List(1, 3, 5, 7)) - fli1.analyze[G[Int]](countingNT) should === (List(4)) + fli1.analyze[G[Int]](countingNT) should ===(List(4)) val fli2 = FreeApplicative.lift[List, Int](List.empty) - fli2.analyze[G[Int]](countingNT) should === (List(0)) + fli2.analyze[G[Int]](countingNT) should ===(List(0)) } test("foldMap order of effects - regression check for #799") { @@ -100,7 +101,7 @@ class FreeApplicativeSuite extends CatsSuite { type Tracked[A] = State[String, A] - val f = λ[FunctionK[Foo,Tracked]] { fa => + val f = λ[FunctionK[Foo, Tracked]] { fa => State { s0 => (s0 + fa.toString + ";", fa.getA) } @@ -112,8 +113,8 @@ class FreeApplicativeSuite extends CatsSuite { val z1: Dsl[Long] = Apply[Dsl].map2(x, y)((x, y) => x.toLong + y) val z2: Dsl[Long] = Apply[Dsl].map2(y, x)((y, x) => x.toLong + y) - z1.foldMap(f).run("").value should === (("Bar(3);Baz(5);", 8L)) - z2.foldMap(f).run("").value should === (("Baz(5);Bar(3);", 8L)) + z1.foldMap(f).run("").value should ===(("Bar(3);Baz(5);", 8L)) + z2.foldMap(f).run("").value should ===(("Baz(5);Bar(3);", 8L)) } test("analyze order of effects - regression check for #799") { @@ -125,47 +126,47 @@ class FreeApplicativeSuite extends CatsSuite { val asString = λ[FunctionK[Id, λ[α => String]]](_.toString) - z.analyze(asString) should === ("xy") + z.analyze(asString) should ===("xy") } } object FreeApplicativeSuite { - private def freeGen[F[_], A](maxDepth: Int)(implicit F: Arbitrary[F[A]], FF: Arbitrary[(A, A) => A], A: Arbitrary[A]): Gen[FreeApplicative[F, A]] = { - val noFlatMapped = Gen.oneOf( - A.arbitrary.map(FreeApplicative.pure[F, A]), - F.arbitrary.map(FreeApplicative.lift[F, A])) + private def freeGen[F[_], A]( + maxDepth: Int + )(implicit F: Arbitrary[F[A]], FF: Arbitrary[(A, A) => A], A: Arbitrary[A]): Gen[FreeApplicative[F, A]] = { + val noFlatMapped = + Gen.oneOf(A.arbitrary.map(FreeApplicative.pure[F, A]), F.arbitrary.map(FreeApplicative.lift[F, A])) val nextDepth = Gen.chooseNum(1, math.max(1, maxDepth - 1)) - def withFlatMapped = for { - fDepth <- nextDepth - freeDepth <- nextDepth - ff <- FF.arbitrary - f <- freeGen[F, A](fDepth).map(_.map(l => (u: A) => ff(l, u))) - freeFA <- freeGen[F, A](freeDepth) - } yield freeFA.ap(f) + def withFlatMapped = + for { + fDepth <- nextDepth + freeDepth <- nextDepth + ff <- FF.arbitrary + f <- freeGen[F, A](fDepth).map(_.map(l => (u: A) => ff(l, u))) + freeFA <- freeGen[F, A](freeDepth) + } yield freeFA.ap(f) if (maxDepth <= 1) noFlatMapped else Gen.oneOf(noFlatMapped, withFlatMapped) } - implicit def freeArbitrary[F[_], A](implicit F: Arbitrary[F[A]], FF: Arbitrary[(A, A) => A], A: Arbitrary[A]): Arbitrary[FreeApplicative[F, A]] = + implicit def freeArbitrary[F[_], A](implicit F: Arbitrary[F[A]], + FF: Arbitrary[(A, A) => A], + A: Arbitrary[A]): Arbitrary[FreeApplicative[F, A]] = Arbitrary(freeGen[F, A](4)) 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 = { + def eqv(a: FreeApplicative[S, A], b: FreeApplicative[S, A]): Boolean = SA.eqv(a.fold, b.fold) - } } implicit def catsLawsArbitraryForListNatTrans: Arbitrary[List ~> List] = - Arbitrary(Gen.oneOf( - FunctionK.id[List], - new (List ~> List) { - def apply[A](fa: List[A]): List[A] = { - fa ++ fa - } - })) + Arbitrary(Gen.oneOf(FunctionK.id[List], new (List ~> List) { + def apply[A](fa: List[A]): List[A] = + fa ++ fa + })) } diff --git a/free/src/test/scala/cats/free/FreeInvariantMonoidalSuite.scala b/free/src/test/scala/cats/free/FreeInvariantMonoidalSuite.scala index 23e9dfed9b2..1802b449bdd 100644 --- a/free/src/test/scala/cats/free/FreeInvariantMonoidalSuite.scala +++ b/free/src/test/scala/cats/free/FreeInvariantMonoidalSuite.scala @@ -9,13 +9,15 @@ import org.scalacheck.{Arbitrary, Gen} import cats.tests.CsvCodecInvariantMonoidalSuite._ class FreeInvariantMonoidalSuite extends CatsSuite { - implicit def freeInvariantMonoidalArbitrary[F[_], A](implicit F: Arbitrary[F[A]], A: Arbitrary[A]): Arbitrary[FreeInvariantMonoidal[F, A]] = + implicit def freeInvariantMonoidalArbitrary[F[_], A](implicit F: Arbitrary[F[A]], + A: Arbitrary[A]): Arbitrary[FreeInvariantMonoidal[F, A]] = Arbitrary( - Gen.oneOf( - A.arbitrary.map(FreeInvariantMonoidal.pure[F, A]), - F.arbitrary.map(FreeInvariantMonoidal.lift[F, A]))) + Gen.oneOf(A.arbitrary.map(FreeInvariantMonoidal.pure[F, A]), F.arbitrary.map(FreeInvariantMonoidal.lift[F, A])) + ) - implicit def freeInvariantMonoidalEq[S[_]: InvariantMonoidal, A](implicit SA: Eq[S[A]]): Eq[FreeInvariantMonoidal[S, A]] = + implicit def freeInvariantMonoidalEq[S[_]: InvariantMonoidal, A]( + implicit SA: Eq[S[A]] + ): Eq[FreeInvariantMonoidal[S, A]] = new Eq[FreeInvariantMonoidal[S, A]] { def eqv(a: FreeInvariantMonoidal[S, A], b: FreeInvariantMonoidal[S, A]): Boolean = { val nt = FunctionK.id[S] @@ -25,8 +27,10 @@ class FreeInvariantMonoidalSuite extends CatsSuite { implicit val isoFreeCsvCodec = Isomorphisms.invariant[FreeInvariantMonoidal[CsvCodec, ?]] - checkAll("FreeInvariantMonoidal[CsvCodec, ?]", InvariantMonoidalTests[FreeInvariantMonoidal[CsvCodec, ?]].invariantMonoidal[Int, Int, Int]) - checkAll("InvariantMonoidal[FreeInvariantMonoidal[CsvCodec, ?]]", SerializableTests.serializable(InvariantMonoidal[FreeInvariantMonoidal[CsvCodec, ?]])) + checkAll("FreeInvariantMonoidal[CsvCodec, ?]", + InvariantMonoidalTests[FreeInvariantMonoidal[CsvCodec, ?]].invariantMonoidal[Int, Int, Int]) + checkAll("InvariantMonoidal[FreeInvariantMonoidal[CsvCodec, ?]]", + SerializableTests.serializable(InvariantMonoidal[FreeInvariantMonoidal[CsvCodec, ?]])) test("FreeInvariantMonoidal#fold") { val n = 2 @@ -38,7 +42,7 @@ class FreeInvariantMonoidalSuite extends CatsSuite { val f2 = FreeInvariantMonoidal.pure[CsvCodec, Int](n) val fExpr = f1.product(f2.imap(_ * 2)(_ / 2)) - fExpr.fold should === (iExpr) + fExpr.fold should ===(iExpr) } implicit val idIsInvariantMonoidal: InvariantMonoidal[Id] = new InvariantMonoidal[Id] { @@ -54,7 +58,7 @@ class FreeInvariantMonoidalSuite extends CatsSuite { val nt = FunctionK.id[Id] val r1 = y.product(p) val r2 = r1.compile(nt) - r1.foldMap(nt) should === (r2.foldMap(nt)) + r1.foldMap(nt) should ===(r2.foldMap(nt)) } test("FreeInvariantMonoidal#analyze") { @@ -62,9 +66,9 @@ class FreeInvariantMonoidalSuite extends CatsSuite { val countingNT = λ[FunctionK[List, G]](la => List(la.length)) val fli1 = FreeInvariantMonoidal.lift[List, Int](List(1, 3, 5, 7)) - fli1.analyze[G[Int]](countingNT) should === (List(4)) + fli1.analyze[G[Int]](countingNT) should ===(List(4)) val fli2 = FreeInvariantMonoidal.lift[List, Int](List.empty) - fli2.analyze[G[Int]](countingNT) should === (List(0)) + fli2.analyze[G[Int]](countingNT) should ===(List(0)) } } diff --git a/free/src/test/scala/cats/free/FreeSuite.scala b/free/src/test/scala/cats/free/FreeSuite.scala index bf72fdabc0e..edc42e4b3ca 100644 --- a/free/src/test/scala/cats/free/FreeSuite.scala +++ b/free/src/test/scala/cats/free/FreeSuite.scala @@ -3,11 +3,11 @@ package free import cats.arrow.FunctionK import cats.data.EitherK -import cats.laws.discipline.{SemigroupalTests, DeferTests, FoldableTests, MonadTests, SerializableTests, TraverseTests} +import cats.laws.discipline.{DeferTests, FoldableTests, MonadTests, SemigroupalTests, SerializableTests, TraverseTests} import cats.laws.discipline.arbitrary.catsLawsArbitraryForFn0 import cats.tests.CatsSuite -import org.scalacheck.{Arbitrary, Gen, Cogen} +import org.scalacheck.{Arbitrary, Cogen, Gen} import Arbitrary.arbFunction1 class FreeSuite extends CatsSuite { @@ -29,14 +29,14 @@ class FreeSuite extends CatsSuite { locally { implicit val instance = Free.catsFreeFoldableForFree[Option] - checkAll("Free[Option, ?]", FoldableTests[Free[Option,?]].foldable[Int,Int]) - checkAll("Foldable[Free[Option,?]]", SerializableTests.serializable(Foldable[Free[Option,?]])) + checkAll("Free[Option, ?]", FoldableTests[Free[Option, ?]].foldable[Int, Int]) + checkAll("Foldable[Free[Option,?]]", SerializableTests.serializable(Foldable[Free[Option, ?]])) } locally { implicit val instance = Free.catsFreeTraverseForFree[Option] - checkAll("Free[Option,?]", TraverseTests[Free[Option,?]].traverse[Int, Int, Int, Int, Option, Option]) - checkAll("Traverse[Free[Option,?]]", SerializableTests.serializable(Traverse[Free[Option,?]])) + checkAll("Free[Option,?]", TraverseTests[Free[Option, ?]].traverse[Int, Int, Int, Int, Option, Option]) + checkAll("Traverse[Free[Option,?]]", SerializableTests.serializable(Traverse[Free[Option, ?]])) } test("toString is stack-safe") { @@ -45,42 +45,42 @@ class FreeSuite extends CatsSuite { rr.toString.length should be > 0 } - test("compile id"){ + test("compile id") { forAll { x: Free[List, Int] => - x.compile(FunctionK.id[List]) should === (x) + x.compile(FunctionK.id[List]) should ===(x) val fk = Free.compile(FunctionK.id[List]) fk(x) === x } } - test("defer doesn't change value"){ + test("defer doesn't change value") { forAll { x: Free[List, Int] => - Free.defer(x) should === (x) + Free.defer(x) should ===(x) } } - test("defer is lazy"){ + test("defer is lazy") { def yikes[F[_], A]: Free[F, A] = throw new RuntimeException("blargh") // this shouldn't throw an exception unless we try to run it val _ = Free.defer(yikes[Option, Int]) } - test("compile consistent with foldMap"){ + test("compile consistent with foldMap") { forAll { x: Free[List, Int] => val mapped = x.compile(headOptionU) val folded = mapped.foldMap(FunctionK.id[Option]) - folded should === (x.foldMap(headOptionU)) + folded should ===(x.foldMap(headOptionU)) val fk = Free.foldMap(headOptionU) - folded should === (fk(x)) + folded should ===(fk(x)) } } test("tailRecM is stack safe") { val n = 50000 - val fa = Monad[Free[Option, ?]].tailRecM(0)(i => - Free.pure[Option, Either[Int, Int]](if (i < n) Left(i+1) else Right(i))) - fa should === (Free.pure[Option, Int](n)) + val fa = + Monad[Free[Option, ?]].tailRecM(0)(i => Free.pure[Option, Either[Int, Int]](if (i < n) Left(i + 1) else Right(i))) + fa should ===(Free.pure[Option, Int](n)) } test("foldMap is stack safe") { @@ -91,13 +91,14 @@ class FreeSuite extends CatsSuite { def tb(i: Int): FTest[Int] = Free.liftF(TB(i)) - def a(i: Int): FTest[Int] = for { - j <- tb(i) - z <- if (j<10000) a(j) else Free.pure[FTestApi, Int](j) - } yield z + def a(i: Int): FTest[Int] = + for { + j <- tb(i) + z <- if (j < 10000) a(j) else Free.pure[FTestApi, Int](j) + } yield z - def runner: FunctionK[FTestApi,Id] = λ[FunctionK[FTestApi,Id]] { - case TB(i) => i+1 + def runner: FunctionK[FTestApi, Id] = λ[FunctionK[FTestApi, Id]] { + case TB(i) => i + 1 } assert(10000 == a(0).foldMap(runner)) @@ -121,7 +122,7 @@ class FreeSuite extends CatsSuite { sealed trait Test1Algebra[A] - case class Test1[A](value : Int, f: Int => A) extends Test1Algebra[A] + case class Test1[A](value: Int, f: Int => A) extends Test1Algebra[A] def test1[A](value: Int, f: Int => A): Test1Algebra[A] = Test1(value, f) @@ -133,13 +134,14 @@ class FreeSuite extends CatsSuite { } } - implicit def test1AlgebraArbitrary[A](implicit seqArb: Arbitrary[Int], intAArb : Arbitrary[Int => A]): Arbitrary[Test1Algebra[A]] = - Arbitrary(for {s <- seqArb.arbitrary; f <- intAArb.arbitrary} yield Test1(s, f)) + implicit def test1AlgebraArbitrary[A](implicit seqArb: Arbitrary[Int], + intAArb: Arbitrary[Int => A]): Arbitrary[Test1Algebra[A]] = + Arbitrary(for { s <- seqArb.arbitrary; f <- intAArb.arbitrary } yield Test1(s, f)) } sealed trait Test2Algebra[A] - case class Test2[A](value : Int, f: Int => A) extends Test2Algebra[A] + case class Test2[A](value: Int, f: Int => A) extends Test2Algebra[A] def test2[A](value: Int, f: Int => A): Test2Algebra[A] = Test2(value, f) @@ -151,62 +153,56 @@ class FreeSuite extends CatsSuite { } } - implicit def test2AlgebraArbitrary[A](implicit seqArb: Arbitrary[Int], intAArb : Arbitrary[Int => A]): Arbitrary[Test2Algebra[A]] = - Arbitrary(for {s <- seqArb.arbitrary; f <- intAArb.arbitrary} yield Test2(s, f)) + implicit def test2AlgebraArbitrary[A](implicit seqArb: Arbitrary[Int], + intAArb: Arbitrary[Int => A]): Arbitrary[Test2Algebra[A]] = + Arbitrary(for { s <- seqArb.arbitrary; f <- intAArb.arbitrary } yield Test2(s, f)) } type T[A] = EitherK[Test1Algebra, Test2Algebra, A] - object Test1Interpreter extends FunctionK[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 FunctionK[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 eitherKInterpreter: FunctionK[T,Id] = Test1Interpreter or Test2Interpreter + val eitherKInterpreter: FunctionK[T, Id] = Test1Interpreter.or(Test2Interpreter) test(".inject") { forAll { (x: Int, y: Int) => - def res[F[_]] - (implicit I0: Test1Algebra :<: F, - I1: Test2Algebra :<: F): Free[F, Int] = { - for { - a <- Free.inject[Test1Algebra, F](test1(x, identity)) - b <- Free.inject[Test2Algebra, F](test2(y, identity)) - } yield a + b - } - (res[T] foldMap eitherKInterpreter) == (x + y) should ===(true) + def res[F[_]](implicit I0: Test1Algebra :<: F, I1: Test2Algebra :<: F): Free[F, Int] = + for { + a <- Free.inject[Test1Algebra, F](test1(x, identity)) + b <- Free.inject[Test2Algebra, F](test2(y, identity)) + } yield a + b + (res[T].foldMap(eitherKInterpreter)) == (x + y) should ===(true) } } test(".liftInject") { forAll { (x: Int, y: Int) => - def res[F[_]] - (implicit I0: Test1Algebra :<: F, - I1: Test2Algebra :<: F): Free[F, Int] = { + def res[F[_]](implicit I0: Test1Algebra :<: F, I1: Test2Algebra :<: F): Free[F, Int] = for { a <- Free.liftInject[F](test1(x, identity)) b <- Free.liftInject[F](test2(y, identity)) } yield a + b - } - (res[T] foldMap eitherKInterpreter) == (x + y) should ===(true) + (res[T].foldMap(eitherKInterpreter)) == (x + y) should ===(true) } } val x: Free[T, Int] = Free.inject[Test1Algebra, T](Test1(1, identity)) test(".injectRoll") { - def distr[F[_], A](f: Free[F, A]) - (implicit - F: Functor[F], - I0: Test1Algebra :<: F, - I1: Test2Algebra :<: F): Option[Free[F, A]] = + def distr[F[_], A](f: Free[F, A])(implicit + F: Functor[F], + I0: Test1Algebra :<: F, + I1: Test2Algebra :<: F): Option[Free[F, A]] = for { Test1(x, h) <- Free.match_[F, Test1Algebra, A](f) Test2(y, k) <- Free.match_[F, Test2Algebra, A](h(x)) @@ -216,7 +212,7 @@ class FreeSuite extends CatsSuite { val expr1: Free[T, Int] = Free.injectRoll[T, Test1Algebra, Int](Test1(x, Free.pure)) val expr2: Free[T, Int] = Free.injectRoll[T, Test2Algebra, Int](Test2(y, Free.pure)) val res = distr[T, Int](expr1 *> expr2) - res.map(_.foldMap(eitherKInterpreter)) should === (Some(Free.pure[Id, Int](x + y).foldMap(FunctionK.id))) + res.map(_.foldMap(eitherKInterpreter)) should ===(Some(Free.pure[Id, Int](x + y).foldMap(FunctionK.id))) } } } @@ -224,10 +220,10 @@ class FreeSuite extends CatsSuite { object FreeSuite extends FreeSuiteInstances { import cats.instances.function._ - implicit def trampolineArbitrary[A:Arbitrary]: Arbitrary[Trampoline[A]] = + implicit def trampolineArbitrary[A: Arbitrary]: Arbitrary[Trampoline[A]] = freeArbitrary[Function0, A] - implicit def trampolineEq[A:Eq]: Eq[Trampoline[A]] = + implicit def trampolineEq[A: Eq]: Eq[Trampoline[A]] = freeEq[Function0, A] } @@ -239,21 +235,20 @@ sealed trait FreeSuiteInstances extends FreeSuiteInstances1 { } sealed trait FreeSuiteInstances1 { - val headOptionU = λ[FunctionK[List,Option]](_.headOption) + val headOptionU = λ[FunctionK[List, Option]](_.headOption) private def freeGen[F[_], A](maxDepth: Int)(implicit F: Arbitrary[F[A]], A: Arbitrary[A]): Gen[Free[F, A]] = { - val noFlatMapped = Gen.oneOf( - A.arbitrary.map(Free.pure[F, A]), - F.arbitrary.map(Free.liftF[F, A])) + val noFlatMapped = Gen.oneOf(A.arbitrary.map(Free.pure[F, A]), F.arbitrary.map(Free.liftF[F, A])) val nextDepth = Gen.chooseNum(1, math.max(1, maxDepth - 1)) - def withFlatMapped = for { - fDepth <- nextDepth - freeDepth <- nextDepth - f <- arbFunction1[A, Free[F, A]](Arbitrary(freeGen[F, A](fDepth)), Cogen[Unit].contramap(_ => ())).arbitrary - freeFA <- freeGen[F, A](freeDepth) - } yield freeFA.flatMap(f) + def withFlatMapped = + for { + fDepth <- nextDepth + freeDepth <- nextDepth + f <- arbFunction1[A, Free[F, A]](Arbitrary(freeGen[F, A](fDepth)), Cogen[Unit].contramap(_ => ())).arbitrary + freeFA <- freeGen[F, A](freeDepth) + } yield freeFA.flatMap(f) if (maxDepth <= 1) noFlatMapped else Gen.oneOf(noFlatMapped, withFlatMapped) @@ -265,6 +260,6 @@ sealed trait FreeSuiteInstances1 { implicit def freeEq[S[_]: Monad, A](implicit SA: Eq[S[A]]): Eq[Free[S, A]] = new Eq[Free[S, A]] { def eqv(a: Free[S, A], b: Free[S, A]): Boolean = - SA.eqv(a.runM(identity), b.runM(identity)) + SA.eqv(a.runM(identity), b.runM(identity)) } } diff --git a/free/src/test/scala/cats/free/FreeTSuite.scala b/free/src/test/scala/cats/free/FreeTSuite.scala index efc8d10764c..7224a7a837c 100644 --- a/free/src/test/scala/cats/free/FreeTSuite.scala +++ b/free/src/test/scala/cats/free/FreeTSuite.scala @@ -8,7 +8,7 @@ import cats.laws.discipline._ import cats.laws.discipline.arbitrary._ import cats.tests.CatsSuite import cats.instances.option._ -import org.scalacheck.{Arbitrary, Gen, Cogen} +import org.scalacheck.{Arbitrary, Cogen, Gen} class FreeTSuite extends CatsSuite { @@ -41,17 +41,20 @@ class FreeTSuite extends CatsSuite { { implicit val eqEitherTFA: Eq[EitherT[FreeTOption, Unit, Int]] = EitherT.catsDataEqForEitherT[FreeTOption, Unit, Int] checkAll("FreeT[Option, Option, Int]", MonadErrorTests[FreeTOption, Unit].monadError[Int, Int, Int]) - checkAll("MonadError[FreeT[Option, Option, ?], Unit]", SerializableTests.serializable(MonadError[FreeTOption, Unit])) + checkAll("MonadError[FreeT[Option, Option, ?], Unit]", + SerializableTests.serializable(MonadError[FreeTOption, Unit])) } test("FlatMap stack safety tested with 50k flatMaps") { val expected = Applicative[FreeTOption].pure(()) val result = - Monad[FreeTOption].tailRecM(0)((i: Int) => - if (i < 50000) - Applicative[FreeTOption].pure(Either.left[Int, Unit](i + 1)) - else - Applicative[FreeTOption].pure(Either.right[Int, Unit](()))) + Monad[FreeTOption].tailRecM(0)( + (i: Int) => + if (i < 50000) + Applicative[FreeTOption].pure(Either.left[Int, Unit](i + 1)) + else + Applicative[FreeTOption].pure(Either.right[Int, Unit](())) + ) Eq[FreeTOption[Unit]].eqv(expected, result) should ===(true) } @@ -95,7 +98,7 @@ class FreeTSuite extends CatsSuite { val b = a.compile(FunctionK.id) Eq[FreeTOption[Int]].eqv(a, b) should ===(true) val fk = FreeT.compile[Option, Option, Option](FunctionK.id) - a should === (fk(a)) + a should ===(fk(a)) } } @@ -112,13 +115,13 @@ class FreeTSuite extends CatsSuite { val y = a.foldMap(FunctionK.id) val fk = FreeT.foldMap[Option, Option](FunctionK.id) Eq[Option[Int]].eqv(x, y) should ===(true) - y should === (fk(a)) + y should ===(fk(a)) } } sealed trait Test1Algebra[A] - case class Test1[A](value : Int, f: Int => A) extends Test1Algebra[A] + case class Test1[A](value: Int, f: Int => A) extends Test1Algebra[A] def test1[A](value: Int, f: Int => A): Test1Algebra[A] = Test1(value, f) @@ -130,13 +133,14 @@ class FreeTSuite extends CatsSuite { } } - implicit def test1AlgebraArbitrary[A](implicit seqArb: Arbitrary[Int], intAArb : Arbitrary[Int => A]): Arbitrary[Test1Algebra[A]] = - Arbitrary(for {s <- seqArb.arbitrary; f <- intAArb.arbitrary} yield Test1(s, f)) + implicit def test1AlgebraArbitrary[A](implicit seqArb: Arbitrary[Int], + intAArb: Arbitrary[Int => A]): Arbitrary[Test1Algebra[A]] = + Arbitrary(for { s <- seqArb.arbitrary; f <- intAArb.arbitrary } yield Test1(s, f)) } sealed trait Test2Algebra[A] - case class Test2[A](value : Int, f: Int => A) extends Test2Algebra[A] + case class Test2[A](value: Int, f: Int => A) extends Test2Algebra[A] def test2[A](value: Int, f: Int => A): Test2Algebra[A] = Test2(value, f) @@ -148,37 +152,35 @@ class FreeTSuite extends CatsSuite { } } - implicit def test2AlgebraArbitrary[A](implicit seqArb: Arbitrary[Int], intAArb : Arbitrary[Int => A]): Arbitrary[Test2Algebra[A]] = - Arbitrary(for {s <- seqArb.arbitrary; f <- intAArb.arbitrary} yield Test2(s, f)) + implicit def test2AlgebraArbitrary[A](implicit seqArb: Arbitrary[Int], + intAArb: Arbitrary[Int => A]): Arbitrary[Test2Algebra[A]] = + Arbitrary(for { s <- seqArb.arbitrary; f <- intAArb.arbitrary } yield Test2(s, f)) } type T[A] = EitherK[Test1Algebra, Test2Algebra, A] - object Test1Interpreter extends FunctionK[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 FunctionK[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 eitherKInterpreter: FunctionK[T,Id] = Test1Interpreter or Test2Interpreter + val eitherKInterpreter: FunctionK[T, Id] = Test1Interpreter.or(Test2Interpreter) test(".liftInject") { forAll { (x: Int, y: Int) => - def res[F[_]] - (implicit I0: Test1Algebra :<: F, - I1: Test2Algebra :<: F): FreeT[F, Id, Int] = { + def res[F[_]](implicit I0: Test1Algebra :<: F, I1: Test2Algebra :<: F): FreeT[F, Id, Int] = for { a <- FreeT.liftInject[Id, F](test1(x, identity)) b <- FreeT.liftInject[Id, F](test2(y, identity)) } yield a + b - } - (res[T] foldMap eitherKInterpreter) == (x + y) should ===(true) + (res[T].foldMap(eitherKInterpreter)) == (x + y) should ===(true) } } @@ -197,7 +199,7 @@ class FreeTSuite extends CatsSuite { } private[free] def liftTCompilationTests() = { - val a: Either[String, Int]= Right(42) + val a: Either[String, Int] = Right(42) val b: FreeT[Option, Either[String, ?], Int] = FreeT.liftT(a) } @@ -208,11 +210,14 @@ object FreeTSuite extends FreeTSuiteInstances { import Arbitrary._ import org.scalacheck.Arbitrary - - implicit def freeTArb[F[_], G[_]: Applicative, A](implicit F: Arbitrary[F[A]], G: Arbitrary[G[A]], A: Arbitrary[A]): Arbitrary[FreeT[F, G, A]] = + implicit def freeTArb[F[_], G[_]: Applicative, A](implicit F: Arbitrary[F[A]], + G: Arbitrary[G[A]], + A: Arbitrary[A]): Arbitrary[FreeT[F, G, A]] = Arbitrary(freeTGen[F, G, A](4)) - private def freeTGen[F[_], G[_]: Applicative, A](maxDepth: Int)(implicit F: Arbitrary[F[A]], G: Arbitrary[G[A]], A: Arbitrary[A]): Gen[FreeT[F, G, A]] = { + private def freeTGen[F[_], G[_]: Applicative, A]( + maxDepth: Int + )(implicit F: Arbitrary[F[A]], G: Arbitrary[G[A]], A: Arbitrary[A]): Gen[FreeT[F, G, A]] = { val noFlatMapped = Gen.oneOf( A.arbitrary.map(FreeT.pure[F, G, A]), F.arbitrary.map(FreeT.liftF[F, G, A]) @@ -220,12 +225,13 @@ object FreeTSuite extends FreeTSuiteInstances { val nextDepth = Gen.chooseNum(1, math.max(1, maxDepth - 1)) - def withFlatMapped = for { - fDepth <- nextDepth - freeDepth <- nextDepth - f <- arbFunction1[A, FreeT[F, G, A]](Arbitrary(freeTGen[F, G, A](fDepth)), Cogen[Unit].contramap(_ => ())).arbitrary - freeFGA <- freeTGen[F, G, A](freeDepth) - } yield freeFGA.flatMap(f) + def withFlatMapped = + for { + fDepth <- nextDepth + freeDepth <- nextDepth + f <- arbFunction1[A, FreeT[F, G, A]](Arbitrary(freeTGen[F, G, A](fDepth)), Cogen[Unit].contramap(_ => ())).arbitrary + freeFGA <- freeTGen[F, G, A](freeDepth) + } yield freeFGA.flatMap(f) if (maxDepth <= 1) noFlatMapped else Gen.oneOf(noFlatMapped, withFlatMapped) @@ -270,6 +276,7 @@ trait FreeTSuiteInstances { } implicit def freeTStateEq[A](implicit A: Eq[A], SM: Monad[IntState]): Eq[FreeTState[A]] = new Eq[FreeTState[A]] { - def eqv(a: FreeTState[A], b: FreeTState[A]) = Eq[IntState[A]].eqv(a.runM(identity)(SM, SM), b.runM(identity)(SM, SM)) + def eqv(a: FreeTState[A], b: FreeTState[A]) = + Eq[IntState[A]].eqv(a.runM(identity)(SM, SM), b.runM(identity)(SM, SM)) } } diff --git a/free/src/test/scala/cats/free/YonedaSuite.scala b/free/src/test/scala/cats/free/YonedaSuite.scala index 3a236a449e4..d8962f6bef1 100644 --- a/free/src/test/scala/cats/free/YonedaSuite.scala +++ b/free/src/test/scala/cats/free/YonedaSuite.scala @@ -7,7 +7,7 @@ import cats.laws.discipline.{FunctorTests, SerializableTests} import org.scalacheck.Arbitrary class YonedaSuite extends CatsSuite { - implicit def yonedaArbitrary[F[_] : Functor, A](implicit F: Arbitrary[F[A]]): Arbitrary[Yoneda[F, A]] = + implicit def yonedaArbitrary[F[_]: Functor, A](implicit F: Arbitrary[F[A]]): Arbitrary[Yoneda[F, A]] = Arbitrary(F.arbitrary.map(Yoneda(_))) implicit def yonedaEq[F[_]: Functor, A](implicit FA: Eq[F[A]]): Eq[Yoneda[F, A]] = @@ -18,9 +18,9 @@ class YonedaSuite extends CatsSuite { checkAll("Yoneda[Option, ?]", FunctorTests[Yoneda[Option, ?]].functor[Int, Int, Int]) checkAll("Functor[Yoneda[Option, ?]]", SerializableTests.serializable(Functor[Yoneda[Option, ?]])) - test("toCoyoneda and then toYoneda is identity"){ - forAll{ (y: Yoneda[Option, Int]) => - y.toCoyoneda.toYoneda should === (y) + test("toCoyoneda and then toYoneda is identity") { + forAll { (y: Yoneda[Option, Int]) => + y.toCoyoneda.toYoneda should ===(y) } } } diff --git a/js/src/main/scala/cats/js/instances/future.scala b/js/src/main/scala/cats/js/instances/future.scala index d00daf10fdc..d641b4fdb89 100644 --- a/js/src/main/scala/cats/js/instances/future.scala +++ b/js/src/main/scala/cats/js/instances/future.scala @@ -13,12 +13,12 @@ object future extends FutureInstances0 object Await { def result[A](f: Future[A], atMost: FiniteDuration): A = f.value match { - case Some(v) => v.get - case None => throw new IllegalStateException() - } + case Some(v) => v.get + case None => throw new IllegalStateException() + } } -private[instances] sealed trait FutureInstances0 extends FutureInstances1 { +sealed private[instances] trait FutureInstances0 extends FutureInstances1 { def futureComonad(atMost: FiniteDuration)(implicit ec: E): Comonad[Future] = new FutureCoflatMap with Comonad[Future] { def extract[A](x: Future[A]): A = @@ -28,23 +28,23 @@ private[instances] sealed trait FutureInstances0 extends FutureInstances1 { def futureOrder[A: Order](atMost: FiniteDuration)(implicit ec: E): Order[Future[A]] = new Order[Future[A]] { def compare(x: Future[A], y: Future[A]): Int = - Await.result((x zip y).map { case (x, y) => x compare y }, atMost) + Await.result(x.zip(y).map { case (x, y) => x.compare(y) }, atMost) } } -private[instances] sealed trait FutureInstances1 extends FutureInstances2 { +sealed private[instances] trait FutureInstances1 extends FutureInstances2 { def futurePartialOrder[A: PartialOrder](atMost: FiniteDuration)(implicit ec: E): PartialOrder[Future[A]] = new PartialOrder[Future[A]] { def partialCompare(x: Future[A], y: Future[A]): Double = - Await.result((x zip y).map { case (x, y) => x partialCompare y }, atMost) + Await.result(x.zip(y).map { case (x, y) => x.partialCompare(y) }, atMost) } } -private[instances] sealed trait FutureInstances2 { +sealed private[instances] trait FutureInstances2 { def futureEq[A: Eq](atMost: FiniteDuration)(implicit ec: E): Eq[Future[A]] = new Eq[Future[A]] { def eqv(x: Future[A], y: Future[A]): Boolean = - Await.result((x zip y).map { case (x, y) => x === y }, atMost) + Await.result(x.zip(y).map { case (x, y) => x === y }, atMost) } } diff --git a/js/src/test/scala/cats/tests/FutureTests.scala b/js/src/test/scala/cats/tests/FutureTests.scala index bc712666c14..8976bc383ab 100644 --- a/js/src/test/scala/cats/tests/FutureTests.scala +++ b/js/src/test/scala/cats/tests/FutureTests.scala @@ -32,12 +32,11 @@ class FutureTests extends CatsSuite { implicit def eqfa[A: Eq]: Eq[Future[A]] = new Eq[Future[A]] { def eqv(fx: Future[A], fy: Future[A]): Boolean = { - val fz = futureEither(fx) zip futureEither(fy) + val fz = futureEither(fx).zip(futureEither(fy)) Await.result(fz.map { case (tx, ty) => tx === ty }, timeout) } } - implicit val throwableEq: Eq[Throwable] = Eq.by[Throwable, String](_.toString) diff --git a/jvm/src/test/scala/cats/tests/FutureSuite.scala b/jvm/src/test/scala/cats/tests/FutureSuite.scala index 02d477cc91f..b30aaf7ec9b 100644 --- a/jvm/src/test/scala/cats/tests/FutureSuite.scala +++ b/jvm/src/test/scala/cats/tests/FutureSuite.scala @@ -23,14 +23,15 @@ class FutureSuite extends CatsSuite { implicit def eqfa[A: Eq]: Eq[Future[A]] = new Eq[Future[A]] { def eqv(fx: Future[A], fy: Future[A]): Boolean = { - val fz = futureEither(fx) zip futureEither(fy) + val fz = futureEither(fx).zip(futureEither(fy)) Await.result(fz.map { case (tx, ty) => tx === ty }, timeout) } } implicit def cogen[A: Cogen]: Cogen[Future[A]] = - Cogen[Future[A]] { (seed: Seed, t: Future[A]) => Cogen[A].perturb(seed, Await.result(t, timeout)) } - + Cogen[Future[A]] { (seed: Seed, t: Future[A]) => + Cogen[A].perturb(seed, Await.result(t, timeout)) + } implicit val throwableEq: Eq[Throwable] = Eq.by[Throwable, String](_.toString) diff --git a/kernel-laws/src/main/scala/cats/kernel/laws/BandLaws.scala b/kernel-laws/src/main/scala/cats/kernel/laws/BandLaws.scala index a6e8f03180e..167f2659ce4 100644 --- a/kernel-laws/src/main/scala/cats/kernel/laws/BandLaws.scala +++ b/kernel-laws/src/main/scala/cats/kernel/laws/BandLaws.scala @@ -3,7 +3,7 @@ package cats.kernel.laws import cats.kernel.Band trait BandLaws[A] extends SemigroupLaws[A] { - override implicit def S: Band[A] + implicit override def S: Band[A] def idempotence(x: A): IsEq[A] = S.combine(x, x) <-> x diff --git a/kernel-laws/src/main/scala/cats/kernel/laws/BoundedSemilatticeLaws.scala b/kernel-laws/src/main/scala/cats/kernel/laws/BoundedSemilatticeLaws.scala index d55b64a3800..92963f3c247 100644 --- a/kernel-laws/src/main/scala/cats/kernel/laws/BoundedSemilatticeLaws.scala +++ b/kernel-laws/src/main/scala/cats/kernel/laws/BoundedSemilatticeLaws.scala @@ -3,7 +3,7 @@ package cats.kernel.laws import cats.kernel.BoundedSemilattice trait BoundedSemilatticeLaws[A] extends CommutativeMonoidLaws[A] with SemilatticeLaws[A] { - override implicit def S: BoundedSemilattice[A] + implicit override def S: BoundedSemilattice[A] } diff --git a/kernel-laws/src/main/scala/cats/kernel/laws/CommutativeGroupLaws.scala b/kernel-laws/src/main/scala/cats/kernel/laws/CommutativeGroupLaws.scala index 0a2d6ceee00..1f5735db4aa 100644 --- a/kernel-laws/src/main/scala/cats/kernel/laws/CommutativeGroupLaws.scala +++ b/kernel-laws/src/main/scala/cats/kernel/laws/CommutativeGroupLaws.scala @@ -2,9 +2,8 @@ package cats package kernel package laws - trait CommutativeGroupLaws[A] extends GroupLaws[A] with CommutativeMonoidLaws[A] { - override implicit def S: CommutativeGroup[A] + implicit override def S: CommutativeGroup[A] } object CommutativeGroupLaws { diff --git a/kernel-laws/src/main/scala/cats/kernel/laws/CommutativeMonoidLaws.scala b/kernel-laws/src/main/scala/cats/kernel/laws/CommutativeMonoidLaws.scala index 115962db14f..92e789794c1 100644 --- a/kernel-laws/src/main/scala/cats/kernel/laws/CommutativeMonoidLaws.scala +++ b/kernel-laws/src/main/scala/cats/kernel/laws/CommutativeMonoidLaws.scala @@ -3,7 +3,7 @@ package cats.kernel.laws import cats.kernel.CommutativeMonoid trait CommutativeMonoidLaws[A] extends MonoidLaws[A] with CommutativeSemigroupLaws[A] { - override implicit def S: CommutativeMonoid[A] + implicit override def S: CommutativeMonoid[A] } diff --git a/kernel-laws/src/main/scala/cats/kernel/laws/CommutativeSemigroupLaws.scala b/kernel-laws/src/main/scala/cats/kernel/laws/CommutativeSemigroupLaws.scala index b183816e340..6e405649c17 100644 --- a/kernel-laws/src/main/scala/cats/kernel/laws/CommutativeSemigroupLaws.scala +++ b/kernel-laws/src/main/scala/cats/kernel/laws/CommutativeSemigroupLaws.scala @@ -3,7 +3,7 @@ package cats.kernel.laws import cats.kernel.CommutativeSemigroup trait CommutativeSemigroupLaws[A] extends SemigroupLaws[A] { - override implicit def S: CommutativeSemigroup[A] + implicit override def S: CommutativeSemigroup[A] def commutative(x: A, y: A): IsEq[A] = S.combine(x, y) <-> S.combine(y, x) diff --git a/kernel-laws/src/main/scala/cats/kernel/laws/GroupLaws.scala b/kernel-laws/src/main/scala/cats/kernel/laws/GroupLaws.scala index 340d24e9d70..b4ac324a733 100644 --- a/kernel-laws/src/main/scala/cats/kernel/laws/GroupLaws.scala +++ b/kernel-laws/src/main/scala/cats/kernel/laws/GroupLaws.scala @@ -1,9 +1,8 @@ package cats.kernel package laws - trait GroupLaws[A] extends MonoidLaws[A] { - override implicit def S: Group[A] + implicit override def S: Group[A] def leftInverse(x: A): IsEq[A] = S.empty <-> S.combine(S.inverse(x), x) @@ -19,5 +18,3 @@ object GroupLaws { def apply[A](implicit ev: Group[A]): GroupLaws[A] = new GroupLaws[A] { def S: Group[A] = ev } } - - diff --git a/kernel-laws/src/main/scala/cats/kernel/laws/HashLaws.scala b/kernel-laws/src/main/scala/cats/kernel/laws/HashLaws.scala index a710a90e618..20fb31dd105 100644 --- a/kernel-laws/src/main/scala/cats/kernel/laws/HashLaws.scala +++ b/kernel-laws/src/main/scala/cats/kernel/laws/HashLaws.scala @@ -4,20 +4,18 @@ package laws import scala.util.hashing._ trait HashLaws[A] extends EqLaws[A] { - override implicit def E: Hash[A] + implicit override def E: Hash[A] def hashCompatibility(x: A, y: A): IsEq[Boolean] = (!E.eqv(x, y) || (Hash.hash(x) == Hash.hash(y))) <-> true - - def sameAsUniversalHash (x: A, y: A): IsEq[Boolean] = + def sameAsUniversalHash(x: A, y: A): IsEq[Boolean] = ((E.hash(x) == x.hashCode) && (Hash.fromUniversalHashCode[A].hash(x) == x.hashCode()) && - (E.eqv(x, y) == Hash.fromUniversalHashCode[A].eqv(x, y))) <-> true - + (E.eqv(x, y) == Hash.fromUniversalHashCode[A].eqv(x, y))) <-> true def sameAsScalaHashing(x: A, y: A, scalaHashing: Hashing[A]): IsEq[Boolean] = - ((E.hash(x) == Hash.fromHashing(scalaHashing).hash(x)) && - (E.eqv(x, y) == Hash.fromHashing(scalaHashing).eqv(x, y))) <-> true + ((E.hash(x) == Hash.fromHashing(scalaHashing).hash(x)) && + (E.eqv(x, y) == Hash.fromHashing(scalaHashing).eqv(x, y))) <-> true } diff --git a/kernel-laws/src/main/scala/cats/kernel/laws/MonoidLaws.scala b/kernel-laws/src/main/scala/cats/kernel/laws/MonoidLaws.scala index 979d80ca0a1..8345e76044b 100644 --- a/kernel-laws/src/main/scala/cats/kernel/laws/MonoidLaws.scala +++ b/kernel-laws/src/main/scala/cats/kernel/laws/MonoidLaws.scala @@ -3,7 +3,7 @@ package cats.kernel.laws import cats.kernel.{Eq, Monoid} trait MonoidLaws[A] extends SemigroupLaws[A] { - override implicit def S: Monoid[A] + implicit override def S: Monoid[A] def leftIdentity(x: A): IsEq[A] = S.combine(S.empty, x) <-> x @@ -20,9 +20,8 @@ trait MonoidLaws[A] extends SemigroupLaws[A] { def combineAll(xs: Vector[A]): IsEq[A] = S.combineAll(xs) <-> (S.empty +: xs).reduce(S.combine) - def isId(x: A, eqv: Eq[A]): IsEq[Boolean] = { + def isId(x: A, eqv: Eq[A]): IsEq[Boolean] = eqv.eqv(x, S.empty) <-> S.isEmpty(x)(eqv) - } } diff --git a/kernel-laws/src/main/scala/cats/kernel/laws/OrderLaws.scala b/kernel-laws/src/main/scala/cats/kernel/laws/OrderLaws.scala index dc7aa026c39..1595108ddec 100644 --- a/kernel-laws/src/main/scala/cats/kernel/laws/OrderLaws.scala +++ b/kernel-laws/src/main/scala/cats/kernel/laws/OrderLaws.scala @@ -5,7 +5,7 @@ import cats.kernel.Order trait OrderLaws[A] extends PartialOrderLaws[A] { - override implicit def E: Order[A] + implicit override def E: Order[A] def totality(x: A, y: A): IsEq[Boolean] = (E.lteqv(x, y) || E.lteqv(y, x)) <-> true @@ -37,4 +37,3 @@ object OrderLaws { def apply[A](implicit ev: Order[A]): OrderLaws[A] = new OrderLaws[A] { def E: Order[A] = ev } } - diff --git a/kernel-laws/src/main/scala/cats/kernel/laws/PartialOrderLaws.scala b/kernel-laws/src/main/scala/cats/kernel/laws/PartialOrderLaws.scala index f8887d7c147..a43acebf2a0 100644 --- a/kernel-laws/src/main/scala/cats/kernel/laws/PartialOrderLaws.scala +++ b/kernel-laws/src/main/scala/cats/kernel/laws/PartialOrderLaws.scala @@ -4,7 +4,7 @@ import cats.kernel.{Eq, PartialOrder} import cats.kernel.instances.option._ trait PartialOrderLaws[A] extends EqLaws[A] { - override implicit def E: PartialOrder[A] + implicit override def E: PartialOrder[A] def reflexitivityLt(x: A): IsEq[Boolean] = E.lteqv(x, x) <-> true @@ -50,7 +50,6 @@ trait PartialOrderLaws[A] extends EqLaws[A] { else Eq[Option[A]].eqv(m, None) <-> true } - } object PartialOrderLaws { diff --git a/kernel-laws/src/main/scala/cats/kernel/laws/SerializableLaws.scala b/kernel-laws/src/main/scala/cats/kernel/laws/SerializableLaws.scala index aa567cd7568..9f5633cf623 100644 --- a/kernel-laws/src/main/scala/cats/kernel/laws/SerializableLaws.scala +++ b/kernel-laws/src/main/scala/cats/kernel/laws/SerializableLaws.scala @@ -1,7 +1,7 @@ package cats.kernel.laws import org.scalacheck.Prop -import org.scalacheck.Prop.{ Exception, Proof, Result } +import org.scalacheck.Prop.{Exception, Proof, Result} import catalysts.Platform @@ -29,25 +29,28 @@ object SerializableLaws { // laws project. def serializable[A](a: A): Prop = - if (Platform.isJs) Prop(_ => Result(status = Proof)) else Prop { _ => - import java.io.{ ByteArrayInputStream, ByteArrayOutputStream, ObjectInputStream, ObjectOutputStream } + if (Platform.isJs) Prop(_ => Result(status = Proof)) + else + Prop { _ => + import java.io.{ByteArrayInputStream, ByteArrayOutputStream, ObjectInputStream, ObjectOutputStream} - val baos = new ByteArrayOutputStream() - val oos = new ObjectOutputStream(baos) - var ois: ObjectInputStream = null // scalastyle:ignore null - try { - oos.writeObject(a) - oos.close() - val bais = new ByteArrayInputStream(baos.toByteArray()) - ois = new ObjectInputStream(bais) - val a2 = ois.readObject() - ois.close() - Result(status = Proof) - } catch { case NonFatal(t) => - Result(status = Exception(t)) - } finally { - oos.close() - if (ois != null) ois.close() // scalastyle:ignore null + val baos = new ByteArrayOutputStream() + val oos = new ObjectOutputStream(baos) + var ois: ObjectInputStream = null // scalastyle:ignore null + try { + oos.writeObject(a) + oos.close() + val bais = new ByteArrayInputStream(baos.toByteArray()) + ois = new ObjectInputStream(bais) + val a2 = ois.readObject() + ois.close() + Result(status = Proof) + } catch { + case NonFatal(t) => + Result(status = Exception(t)) + } finally { + oos.close() + if (ois != null) ois.close() // scalastyle:ignore null + } } - } } diff --git a/kernel-laws/src/main/scala/cats/kernel/laws/discipline/BandTests.scala b/kernel-laws/src/main/scala/cats/kernel/laws/discipline/BandTests.scala index 87a9941f66d..fd707966b1d 100644 --- a/kernel-laws/src/main/scala/cats/kernel/laws/discipline/BandTests.scala +++ b/kernel-laws/src/main/scala/cats/kernel/laws/discipline/BandTests.scala @@ -11,10 +11,7 @@ trait BandTests[A] extends SemigroupTests[A] { def laws: BandLaws[A] def band(implicit arbA: Arbitrary[A], eqA: Eq[A]): RuleSet = - new DefaultRuleSet( - "band", - Some(semigroup), - "idempotency" -> forAll(laws.idempotence _)) + new DefaultRuleSet("band", Some(semigroup), "idempotency" -> forAll(laws.idempotence _)) } diff --git a/kernel-laws/src/main/scala/cats/kernel/laws/discipline/CommutativeSemigroupTests.scala b/kernel-laws/src/main/scala/cats/kernel/laws/discipline/CommutativeSemigroupTests.scala index 2a0f97accf3..c5430d1ea08 100644 --- a/kernel-laws/src/main/scala/cats/kernel/laws/discipline/CommutativeSemigroupTests.scala +++ b/kernel-laws/src/main/scala/cats/kernel/laws/discipline/CommutativeSemigroupTests.scala @@ -11,10 +11,7 @@ trait CommutativeSemigroupTests[A] extends SemigroupTests[A] { def laws: CommutativeSemigroupLaws[A] def commutativeSemigroup(implicit arbA: Arbitrary[A], eqA: Eq[A]): RuleSet = - new DefaultRuleSet( - "commutativeSemigroup", - Some(semigroup), - "commutative" -> forAll(laws.commutative _)) + new DefaultRuleSet("commutativeSemigroup", Some(semigroup), "commutative" -> forAll(laws.commutative _)) } diff --git a/kernel-laws/src/main/scala/cats/kernel/laws/discipline/EqTests.scala b/kernel-laws/src/main/scala/cats/kernel/laws/discipline/EqTests.scala index 585687ed3ba..e93e6f185a1 100644 --- a/kernel-laws/src/main/scala/cats/kernel/laws/discipline/EqTests.scala +++ b/kernel-laws/src/main/scala/cats/kernel/laws/discipline/EqTests.scala @@ -20,7 +20,8 @@ trait EqTests[A] extends Laws { "reflexitivity" -> forAll(laws.reflexitivityEq _), "symmetry" -> forAll(laws.symmetryEq _), "antisymmetry" -> forAll(laws.antiSymmetryEq _), - "transitivity" -> forAll(laws.transitivityEq _)) + "transitivity" -> forAll(laws.transitivityEq _) + ) } } @@ -28,4 +29,3 @@ object EqTests { def apply[A: Eq]: EqTests[A] = new EqTests[A] { def laws: EqLaws[A] = EqLaws[A] } } - diff --git a/kernel-laws/src/main/scala/cats/kernel/laws/discipline/GroupTests.scala b/kernel-laws/src/main/scala/cats/kernel/laws/discipline/GroupTests.scala index 506f860c794..2e7d9e1e38c 100644 --- a/kernel-laws/src/main/scala/cats/kernel/laws/discipline/GroupTests.scala +++ b/kernel-laws/src/main/scala/cats/kernel/laws/discipline/GroupTests.scala @@ -16,7 +16,8 @@ trait GroupTests[A] extends MonoidTests[A] { Some(monoid), "left inverse" -> forAll(laws.leftInverse _), "right inverse" -> forAll(laws.rightInverse _), - "consistent inverse" -> forAll(laws.consistentInverse _)) + "consistent inverse" -> forAll(laws.consistentInverse _) + ) } diff --git a/kernel-laws/src/main/scala/cats/kernel/laws/discipline/MonoidTests.scala b/kernel-laws/src/main/scala/cats/kernel/laws/discipline/MonoidTests.scala index f058cf8780c..1436fee98f1 100644 --- a/kernel-laws/src/main/scala/cats/kernel/laws/discipline/MonoidTests.scala +++ b/kernel-laws/src/main/scala/cats/kernel/laws/discipline/MonoidTests.scala @@ -20,7 +20,8 @@ trait MonoidTests[A] extends SemigroupTests[A] { "combine all" -> forAll(laws.combineAll _), "collect0" -> forAll(laws.collect0 _), "is id" -> forAll((a: A) => laws.isId(a, eqA)), - "repeat0" -> forAll(laws.repeat0 _)) + "repeat0" -> forAll(laws.repeat0 _) + ) } diff --git a/kernel-laws/src/main/scala/cats/kernel/laws/discipline/SemigroupTests.scala b/kernel-laws/src/main/scala/cats/kernel/laws/discipline/SemigroupTests.scala index 8badff4e6d7..213b2287d3a 100644 --- a/kernel-laws/src/main/scala/cats/kernel/laws/discipline/SemigroupTests.scala +++ b/kernel-laws/src/main/scala/cats/kernel/laws/discipline/SemigroupTests.scala @@ -18,7 +18,8 @@ trait SemigroupTests[A] extends Laws { "associative" -> forAll(laws.semigroupAssociative _), "repeat1" -> forAll(laws.repeat1 _), "repeat2" -> forAll(laws.repeat2 _), - "combineAllOption" -> forAll(laws.combineAllOption _)) + "combineAllOption" -> forAll(laws.combineAllOption _) + ) } object SemigroupTests { diff --git a/kernel-laws/src/main/scala/cats/kernel/laws/discipline/SemilatticeTests.scala b/kernel-laws/src/main/scala/cats/kernel/laws/discipline/SemilatticeTests.scala index d4a697a52bd..89c3f4e9184 100644 --- a/kernel-laws/src/main/scala/cats/kernel/laws/discipline/SemilatticeTests.scala +++ b/kernel-laws/src/main/scala/cats/kernel/laws/discipline/SemilatticeTests.scala @@ -23,5 +23,3 @@ object SemilatticeTests { def apply[A: Semilattice]: SemilatticeTests[A] = new SemilatticeTests[A] { def laws: SemilatticeLaws[A] = SemilatticeLaws[A] } } - - diff --git a/kernel-laws/src/main/scala/cats/kernel/laws/discipline/SerializableTests.scala b/kernel-laws/src/main/scala/cats/kernel/laws/discipline/SerializableTests.scala index a19d46c498b..4be5b8a16ef 100644 --- a/kernel-laws/src/main/scala/cats/kernel/laws/discipline/SerializableTests.scala +++ b/kernel-laws/src/main/scala/cats/kernel/laws/discipline/SerializableTests.scala @@ -5,8 +5,7 @@ import org.typelevel.discipline.Laws object SerializableTests extends Laws { def serializable[A](a: A): RuleSet = - new DefaultRuleSet( - name = "serializable", - parent = None, - "can serialize and deserialize" -> SerializableLaws.serializable(a)) + new DefaultRuleSet(name = "serializable", + parent = None, + "can serialize and deserialize" -> SerializableLaws.serializable(a)) } diff --git a/kernel-laws/src/main/scala/cats/kernel/laws/discipline/package.scala b/kernel-laws/src/main/scala/cats/kernel/laws/discipline/package.scala index cd7ce970b01..99fb11e50dc 100644 --- a/kernel-laws/src/main/scala/cats/kernel/laws/discipline/package.scala +++ b/kernel-laws/src/main/scala/cats/kernel/laws/discipline/package.scala @@ -6,11 +6,14 @@ import org.scalacheck.util.Pretty package object discipline { implicit def catsLawsIsEqToProp[A](isEq: IsEq[A])(implicit ev: Eq[A], pp: A => Pretty): Prop = - isEq match { case IsEq(x, y) => - if (ev.eqv(x, y)) Prop.proved else Prop.falsified :| { - val exp = Pretty.pretty[A](y, Pretty.Params(0)) - val act = Pretty.pretty[A](x, Pretty.Params(0)) - s"Expected: $exp\n" + s"Received: $act" - } + isEq match { + case IsEq(x, y) => + if (ev.eqv(x, y)) Prop.proved + else + Prop.falsified :| { + val exp = Pretty.pretty[A](y, Pretty.Params(0)) + val act = Pretty.pretty[A](x, Pretty.Params(0)) + s"Expected: $exp\n" + s"Received: $act" + } } } diff --git a/kernel-laws/src/test/scala/cats/kernel/laws/LawTests.scala b/kernel-laws/src/test/scala/cats/kernel/laws/LawTests.scala index 44779c592cf..e9b61469f26 100644 --- a/kernel-laws/src/test/scala/cats/kernel/laws/LawTests.scala +++ b/kernel-laws/src/test/scala/cats/kernel/laws/LawTests.scala @@ -6,24 +6,22 @@ import catalysts.macros.TypeTagM import cats.kernel.instances.all._ import cats.kernel.laws.discipline._ - import org.typelevel.discipline.Laws import org.typelevel.discipline.scalatest.Discipline -import org.scalacheck.{ Arbitrary, Cogen, Gen } +import org.scalacheck.{Arbitrary, Cogen, Gen} import Arbitrary.arbitrary -import org.scalactic.anyvals.{ PosInt, PosZInt } +import org.scalactic.anyvals.{PosInt, PosZInt} import org.scalatest.FunSuite -import scala.concurrent.duration.{ Duration, FiniteDuration } +import scala.concurrent.duration.{Duration, FiniteDuration} import scala.collection.immutable.{BitSet, Queue} import scala.util.Random import java.util.UUID -import java.util.concurrent.TimeUnit.{DAYS, HOURS, MINUTES, SECONDS, MILLISECONDS, MICROSECONDS, NANOSECONDS} +import java.util.concurrent.TimeUnit.{DAYS, HOURS, MICROSECONDS, MILLISECONDS, MINUTES, NANOSECONDS, SECONDS} object KernelCheck { - implicit val arbitraryBitSet: Arbitrary[BitSet] = Arbitrary(arbitrary[List[Short]].map(ns => BitSet(ns.map(_ & 0xffff): _*))) @@ -37,28 +35,34 @@ object KernelCheck { // max range is +/- 292 years, but we give ourselves some extra headroom // to ensure that we can add these things up. they crash on overflow. val n = (292L * 365) / 50 - Arbitrary(Gen.oneOf( - Gen.choose(-n, n).map(Duration(_, DAYS)), - Gen.choose(-n * 24L, n * 24L).map(Duration(_, HOURS)), - Gen.choose(-n * 1440L, n * 1440L).map(Duration(_, MINUTES)), - Gen.choose(-n * 86400L, n * 86400L).map(Duration(_, SECONDS)), - Gen.choose(-n * 86400000L, n * 86400000L).map(Duration(_, MILLISECONDS)), - Gen.choose(-n * 86400000000L, n * 86400000000L).map(Duration(_, MICROSECONDS)), - Gen.choose(-n * 86400000000000L, n * 86400000000000L).map(Duration(_, NANOSECONDS)))) + Arbitrary( + Gen.oneOf( + Gen.choose(-n, n).map(Duration(_, DAYS)), + Gen.choose(-n * 24L, n * 24L).map(Duration(_, HOURS)), + Gen.choose(-n * 1440L, n * 1440L).map(Duration(_, MINUTES)), + Gen.choose(-n * 86400L, n * 86400L).map(Duration(_, SECONDS)), + Gen.choose(-n * 86400000L, n * 86400000L).map(Duration(_, MILLISECONDS)), + Gen.choose(-n * 86400000000L, n * 86400000000L).map(Duration(_, MICROSECONDS)), + Gen.choose(-n * 86400000000000L, n * 86400000000000L).map(Duration(_, NANOSECONDS)) + ) + ) } implicit val arbitraryFiniteDuration: Arbitrary[FiniteDuration] = { // max range is +/- 292 years, but we give ourselves some extra headroom // to ensure that we can add these things up. they crash on overflow. val n = (292L * 365) / 50 - Arbitrary(Gen.oneOf( - Gen.choose(-n, n).map(FiniteDuration(_, DAYS)), - Gen.choose(-n * 24L, n * 24L).map(FiniteDuration(_, HOURS)), - Gen.choose(-n * 1440L, n * 1440L).map(FiniteDuration(_, MINUTES)), - Gen.choose(-n * 86400L, n * 86400L).map(FiniteDuration(_, SECONDS)), - Gen.choose(-n * 86400000L, n * 86400000L).map(FiniteDuration(_, MILLISECONDS)), - Gen.choose(-n * 86400000000L, n * 86400000000L).map(FiniteDuration(_, MICROSECONDS)), - Gen.choose(-n * 86400000000000L, n * 86400000000000L).map(FiniteDuration(_, NANOSECONDS)))) + Arbitrary( + Gen.oneOf( + Gen.choose(-n, n).map(FiniteDuration(_, DAYS)), + Gen.choose(-n * 24L, n * 24L).map(FiniteDuration(_, HOURS)), + Gen.choose(-n * 1440L, n * 1440L).map(FiniteDuration(_, MINUTES)), + Gen.choose(-n * 86400L, n * 86400L).map(FiniteDuration(_, SECONDS)), + Gen.choose(-n * 86400000L, n * 86400000L).map(FiniteDuration(_, MILLISECONDS)), + Gen.choose(-n * 86400000000L, n * 86400000000L).map(FiniteDuration(_, MICROSECONDS)), + Gen.choose(-n * 86400000000000L, n * 86400000000000L).map(FiniteDuration(_, NANOSECONDS)) + ) + ) } // this instance is not available in scalacheck 1.13.2. @@ -82,27 +86,28 @@ object KernelCheck { if (d == Duration.Inf) 3896691548866406746L else if (d == Duration.MinusInf) 1844151880988859955L else if (d == Duration.Undefined) -7917359255778781894L - else d.length * (d.unit match { - case DAYS => -6307593037248227856L - case HOURS => -3527447467459552709L - case MINUTES => 5955657079535371609L - case SECONDS => 5314272869665647192L - case MILLISECONDS => -2025740217814855607L - case MICROSECONDS => -2965853209268633779L - case NANOSECONDS => 6128745701389500153L - }) + else + d.length * (d.unit match { + case DAYS => -6307593037248227856L + case HOURS => -3527447467459552709L + case MINUTES => 5955657079535371609L + case SECONDS => 5314272869665647192L + case MILLISECONDS => -2025740217814855607L + case MICROSECONDS => -2965853209268633779L + case NANOSECONDS => 6128745701389500153L + }) } implicit val cogenFiniteDuration: Cogen[FiniteDuration] = Cogen[Long].contramap { d => d.length * (d.unit match { - case DAYS => -6307593037248227856L - case HOURS => -3527447467459552709L - case MINUTES => 5955657079535371609L - case SECONDS => 5314272869665647192L + case DAYS => -6307593037248227856L + case HOURS => -3527447467459552709L + case MINUTES => 5955657079535371609L + case SECONDS => 5314272869665647192L case MILLISECONDS => -2025740217814855607L case MICROSECONDS => -2965853209268633779L - case NANOSECONDS => 6128745701389500153L + case NANOSECONDS => 6128745701389500153L }) } } @@ -117,11 +122,7 @@ class Tests extends FunSuite with Discipline { final val PropWorkers: PosInt = if (Platform.isJvm) PosInt(2) else PosInt(1) implicit override val generatorDrivenConfig: PropertyCheckConfiguration = - PropertyCheckConfiguration( - minSuccessful = PropMinSuccessful, - sizeRange = PropMaxSize, - workers = PropWorkers) - + PropertyCheckConfiguration(minSuccessful = PropMinSuccessful, sizeRange = PropMaxSize, workers = PropWorkers) { // needed for Cogen[Map[...]] @@ -129,7 +130,6 @@ class Tests extends FunSuite with Discipline { checkAll("Eq[Map[String, HasEq[Int]]]", EqTests[Map[String, HasEq[Int]]].eqv) } - checkAll("Eq[List[HasEq[Int]]]", EqTests[List[HasEq[Int]]].eqv) checkAll("Eq[Option[HasEq[Int]]]", EqTests[Option[HasEq[Int]]].eqv) checkAll("Eq[Vector[HasEq[Int]]]", EqTests[Vector[HasEq[Int]]].eqv) @@ -137,15 +137,21 @@ class Tests extends FunSuite with Discipline { checkAll("Eq[Queue[HasEq[Int]]]", EqTests[Queue[HasEq[Int]]].eqv) checkAll("PartialOrder[Set[Int]]", PartialOrderTests[Set[Int]].partialOrder) - checkAll("PartialOrder.reverse(PartialOrder[Set[Int]])", PartialOrderTests(PartialOrder.reverse(PartialOrder[Set[Int]])).partialOrder) - checkAll("PartialOrder.reverse(PartialOrder.reverse(PartialOrder[Set[Int]]))", PartialOrderTests(PartialOrder.reverse(PartialOrder.reverse(PartialOrder[Set[Int]]))).partialOrder) + checkAll("PartialOrder.reverse(PartialOrder[Set[Int]])", + PartialOrderTests(PartialOrder.reverse(PartialOrder[Set[Int]])).partialOrder) + checkAll( + "PartialOrder.reverse(PartialOrder.reverse(PartialOrder[Set[Int]]))", + PartialOrderTests(PartialOrder.reverse(PartialOrder.reverse(PartialOrder[Set[Int]]))).partialOrder + ) checkAll("PartialOrder[Option[HasPartialOrder[Int]]]", PartialOrderTests[Option[HasPartialOrder[Int]]].partialOrder) checkAll("PartialOrder[List[HasPartialOrder[Int]]]", PartialOrderTests[List[HasPartialOrder[Int]]].partialOrder) checkAll("PartialOrder[Vector[HasPartialOrder[Int]]]", PartialOrderTests[Vector[HasPartialOrder[Int]]].partialOrder) checkAll("PartialOrder[Stream[HasPartialOrder[Int]]]", PartialOrderTests[Stream[HasPartialOrder[Int]]].partialOrder) checkAll("PartialOrder[Queue[HasPartialOrder[Int]]]", PartialOrderTests[Queue[HasPartialOrder[Int]]].partialOrder) - checkAll("Semilattice.asMeetPartialOrder[Set[Int]]", PartialOrderTests(Semilattice.asMeetPartialOrder[Set[Int]]).partialOrder) - checkAll("Semilattice.asJoinPartialOrder[Set[Int]]", PartialOrderTests(Semilattice.asJoinPartialOrder[Set[Int]]).partialOrder) + checkAll("Semilattice.asMeetPartialOrder[Set[Int]]", + PartialOrderTests(Semilattice.asMeetPartialOrder[Set[Int]]).partialOrder) + checkAll("Semilattice.asJoinPartialOrder[Set[Int]]", + PartialOrderTests(Semilattice.asJoinPartialOrder[Set[Int]]).partialOrder) checkAll("Order[Unit]", OrderTests[Unit].order) checkAll("Order[Boolean]", OrderTests[Boolean].order) @@ -161,7 +167,7 @@ class Tests extends FunSuite with Discipline { checkAll("Order[Duration]", OrderTests[Duration].order) checkAll("Order[FiniteDuration]", OrderTests[FiniteDuration].order) checkAll("Order[UUID]", OrderTests[UUID].order) - checkAll("Order[List[Int]]", OrderTests[List[Int]] .order) + checkAll("Order[List[Int]]", OrderTests[List[Int]].order) checkAll("Order[Option[String]]", OrderTests[Option[String]].order) checkAll("Order[List[String]", OrderTests[List[String]].order) checkAll("Order[Vector[Int]]", OrderTests[Vector[Int]].order) @@ -218,15 +224,14 @@ class Tests extends FunSuite with Discipline { checkAll("CommutativeGroup[FiniteDuration]", CommutativeGroupTests[FiniteDuration].commutativeGroup) checkAll("CommutativeGroup[FiniteDuration]", SerializableTests.serializable(CommutativeGroup[FiniteDuration])) - - checkAll("Hash[Unit]" , HashTests[Unit].hash) - checkAll("Hash[Boolean]" , HashTests[Boolean].hash) - checkAll("Hash[String]" , HashTests[String].hash) - checkAll("Hash[Symbol]" , HashTests[Symbol].hash) - checkAll("Hash[Byte]" , HashTests[Byte].hash) - checkAll("Hash[Short]" , HashTests[Short].hash) - checkAll("Hash[Char]" , HashTests[Char].hash) - checkAll("Hash[Int]" , HashTests[Int].hash) + checkAll("Hash[Unit]", HashTests[Unit].hash) + checkAll("Hash[Boolean]", HashTests[Boolean].hash) + checkAll("Hash[String]", HashTests[String].hash) + checkAll("Hash[Symbol]", HashTests[Symbol].hash) + checkAll("Hash[Byte]", HashTests[Byte].hash) + checkAll("Hash[Short]", HashTests[Short].hash) + checkAll("Hash[Char]", HashTests[Char].hash) + checkAll("Hash[Int]", HashTests[Int].hash) checkAll("Hash[Duration]", HashTests[Duration].hash) checkAll("Hash[FiniteDuration]", HashTests[FiniteDuration].hash) @@ -234,23 +239,21 @@ class Tests extends FunSuite with Discipline { // `##` is different from `hashCode`. See [[scala.runtime.Statics.anyHash]]. // checkAll("Hash[Float]" , HashTests[Float].hash) // checkAll("Hash[Double]" , HashTests[Double].hash) - checkAll("Hash[BitSet]" , HashTests[BitSet].hash) - checkAll("Hash[BigDecimal]" , HashTests[BigDecimal].hash) - checkAll("Hash[BigInt]" , HashTests[BigInt].hash) - checkAll("Hash[UUID]" , HashTests[UUID].hash) - checkAll("Hash[List[Int]]" , HashTests[List[Int]].hash) - checkAll("Hash[Option[String]]" , HashTests[Option[String]].hash) - checkAll("Hash[List[String]]" , HashTests[List[String]].hash) - checkAll("Hash[Vector[Int]]" , HashTests[Vector[Int]].hash) - checkAll("Hash[Stream[Int]]" , HashTests[Stream[Int]].hash) - checkAll("Hash[Set[Int]]" , HashTests[Set[Int]].hash) - checkAll("Hash[(Int, String)]" , HashTests[(Int, String)].hash) - checkAll("Hash[Either[Int, String]]" , HashTests[Either[Int, String]].hash) - checkAll("Hash[Map[Int, String]]" , HashTests[Map[Int, String]].hash) + checkAll("Hash[BitSet]", HashTests[BitSet].hash) + checkAll("Hash[BigDecimal]", HashTests[BigDecimal].hash) + checkAll("Hash[BigInt]", HashTests[BigInt].hash) + checkAll("Hash[UUID]", HashTests[UUID].hash) + checkAll("Hash[List[Int]]", HashTests[List[Int]].hash) + checkAll("Hash[Option[String]]", HashTests[Option[String]].hash) + checkAll("Hash[List[String]]", HashTests[List[String]].hash) + checkAll("Hash[Vector[Int]]", HashTests[Vector[Int]].hash) + checkAll("Hash[Stream[Int]]", HashTests[Stream[Int]].hash) + checkAll("Hash[Set[Int]]", HashTests[Set[Int]].hash) + checkAll("Hash[(Int, String)]", HashTests[(Int, String)].hash) + checkAll("Hash[Either[Int, String]]", HashTests[Either[Int, String]].hash) + checkAll("Hash[Map[Int, String]]", HashTests[Map[Int, String]].hash) checkAll("Hash[Queue[Int]", HashTests[Queue[Int]].hash) - - { // default Arbitrary[BigDecimal] is a bit too intense :/ implicit val arbBigDecimal: Arbitrary[BigDecimal] = @@ -272,8 +275,8 @@ class Tests extends FunSuite with Discipline { def subsetPartialOrder[A]: PartialOrder[Set[A]] = new PartialOrder[Set[A]] { def partialCompare(x: Set[A], y: Set[A]): Double = if (x == y) 0.0 - else if (x subsetOf y) -1.0 - else if (y subsetOf x) 1.0 + else if (x.subsetOf(y)) -1.0 + else if (y.subsetOf(x)) 1.0 else Double.NaN } @@ -282,14 +285,13 @@ class Tests extends FunSuite with Discipline { { implicit def subsetPartialOrdering[A]: PartialOrdering[Set[A]] = new PartialOrdering[Set[A]] { - override def tryCompare(x: Set[A], y: Set[A]): Option[Int] = { + override def tryCompare(x: Set[A], y: Set[A]): Option[Int] = if (x == y) Some(0) - else if (x subsetOf y) Some(-1) - else if (y subsetOf x) Some(1) + else if (x.subsetOf(y)) Some(-1) + else if (y.subsetOf(x)) Some(1) else None - } - override def lteq(x: Set[A], y: Set[A]): Boolean = (x subsetOf y) || (x == y) + override def lteq(x: Set[A], y: Set[A]): Boolean = (x.subsetOf(y)) || (x == y) } checkAll("fromPartialOrdering[Int]", PartialOrderTests(PartialOrder.fromPartialOrdering[Set[Int]]).partialOrder) } @@ -305,17 +307,17 @@ class Tests extends FunSuite with Discipline { test("comparison") { val order = Order[Int] val eqv = Eq[Comparison] - eqv.eqv(order.comparison(1, 0), Comparison.GreaterThan) && - eqv.eqv(order.comparison(0, 0), Comparison.EqualTo) && + eqv.eqv(order.comparison(1, 0), Comparison.GreaterThan) && + eqv.eqv(order.comparison(0, 0), Comparison.EqualTo) && eqv.eqv(order.comparison(-1, 0), Comparison.LessThan) } test("partialComparison") { val po = subsetPartialOrder[Int] val eqv = Eq[Option[Comparison]] - eqv.eqv(po.partialComparison(Set(1), Set()), Some(Comparison.GreaterThan)) && - eqv.eqv(po.partialComparison(Set(), Set()), Some(Comparison.EqualTo)) && - eqv.eqv(po.partialComparison(Set(), Set(1)), Some(Comparison.LessThan)) && + eqv.eqv(po.partialComparison(Set(1), Set()), Some(Comparison.GreaterThan)) && + eqv.eqv(po.partialComparison(Set(), Set()), Some(Comparison.EqualTo)) && + eqv.eqv(po.partialComparison(Set(), Set(1)), Some(Comparison.LessThan)) && eqv.eqv(po.partialComparison(Set(1, 2), Set(2, 3)), None) } @@ -352,7 +354,9 @@ class Tests extends FunSuite with Discipline { // integers. implicit val arbNOrder: Arbitrary[Order[N]] = Arbitrary(arbitrary[Int].map { seed => val order = new Random(seed).shuffle(Vector.range(0, nMax)) - Order.by { (n: N) => order(n.n) } + Order.by { (n: N) => + order(n.n) + } }) implicit val cogNOrder: Cogen[Order[N]] = Cogen[Unit].contramap(_ => ()) @@ -360,7 +364,9 @@ class Tests extends FunSuite with Discipline { // integers. implicit val arbNEq: Arbitrary[Eq[N]] = Arbitrary(arbitrary[Int].map { seed => val mapping = new Random(seed).shuffle(Vector.range(0, nMax)) - Eq.by { (n: N) => mapping(n.n) } + Eq.by { (n: N) => + mapping(n.n) + } }) implicit val cogNEq: Cogen[Eq[N]] = Cogen[Unit].contramap(_ => ()) @@ -374,8 +380,11 @@ class Tests extends FunSuite with Discipline { } implicit val NEqEq: Eq[Eq[N]] = new Eq[Eq[N]] { def eqv(a: Eq[N], b: Eq[N]) = - Iterator.tabulate(nMax)(N) - .flatMap { x => Iterator.tabulate(nMax)(N).map((x, _)) } + Iterator + .tabulate(nMax)(N) + .flatMap { x => + Iterator.tabulate(nMax)(N).map((x, _)) + } .forall { case (x, y) => a.eqv(x, y) == b.eqv(x, y) } } @@ -434,5 +443,5 @@ class Tests extends FunSuite with Discipline { laws[L, A]("") private[laws] def laws[L[_] <: Laws, A](extraTag: String)(implicit laws: L[A], tag: TypeTagM[A]): LawChecker[L[A]] = - LawChecker("[" + tag.name.toString + (if(extraTag != "") "@@" + extraTag else "") + "]", laws) + LawChecker("[" + tag.name.toString + (if (extraTag != "") "@@" + extraTag else "") + "]", laws) } diff --git a/kernel/src/main/scala-2.12-/cats/kernel/compat/TraversableOnce.scala b/kernel/src/main/scala-2.12-/cats/kernel/compat/TraversableOnce.scala index 4685fd53e57..0106979caf6 100644 --- a/kernel/src/main/scala-2.12-/cats/kernel/compat/TraversableOnce.scala +++ b/kernel/src/main/scala-2.12-/cats/kernel/compat/TraversableOnce.scala @@ -1,8 +1,7 @@ package cats.kernel package compat - -private[kernel] object TraversableOnce { +private[kernel] object TraversableOnce { def reduceOption[A, A1 >: A](as: TraversableOnce[A], op: (A1, A1) => A1): Option[A1] = as.reduceOption(op) } diff --git a/kernel/src/main/scala-2.12-/cats/kernel/compat/WrappedMutableMapBase.scala b/kernel/src/main/scala-2.12-/cats/kernel/compat/WrappedMutableMapBase.scala index 80d570fe4ab..216a84bd0b6 100644 --- a/kernel/src/main/scala-2.12-/cats/kernel/compat/WrappedMutableMapBase.scala +++ b/kernel/src/main/scala-2.12-/cats/kernel/compat/WrappedMutableMapBase.scala @@ -3,8 +3,7 @@ package compat import scala.collection.mutable - -private[kernel] abstract class WrappedMutableMapBase[K, V](m: mutable.Map[K, V]) extends Map[K, V] { +abstract private[kernel] class WrappedMutableMapBase[K, V](m: mutable.Map[K, V]) extends Map[K, V] { def +[V2 >: V](kv: (K, V2)): Map[K, V2] = m.toMap + kv def -(key: K): Map[K, V] = m.toMap - key } diff --git a/kernel/src/main/scala/cats/kernel/Band.scala b/kernel/src/main/scala/cats/kernel/Band.scala index e2d6c6ab053..3a50a28ec96 100644 --- a/kernel/src/main/scala/cats/kernel/Band.scala +++ b/kernel/src/main/scala/cats/kernel/Band.scala @@ -2,17 +2,16 @@ package cats.kernel import scala.{specialized => sp} - /** - * Bands are semigroups whose operation - * (i.e. combine) is also idempotent. - */ + * Bands are semigroups whose operation + * (i.e. combine) is also idempotent. + */ trait Band[@sp(Int, Long, Float, Double) A] extends Any with Semigroup[A] object Band extends SemigroupFunctions[Band] { /** - * Access an implicit `Band[A]`. - */ + * Access an implicit `Band[A]`. + */ @inline final def apply[@sp(Int, Long, Float, Double) A](implicit ev: Band[A]): Band[A] = ev } diff --git a/kernel/src/main/scala/cats/kernel/BoundedSemilattice.scala b/kernel/src/main/scala/cats/kernel/BoundedSemilattice.scala index 9838164ea74..dc79b1490b3 100644 --- a/kernel/src/main/scala/cats/kernel/BoundedSemilattice.scala +++ b/kernel/src/main/scala/cats/kernel/BoundedSemilattice.scala @@ -7,7 +7,8 @@ trait BoundedSemilattice[@sp(Int, Long, Float, Double) A] extends Any with Semil object BoundedSemilattice extends SemilatticeFunctions[BoundedSemilattice] { /** - * Access an implicit `BoundedSemilattice[A]`. - */ - @inline final def apply[@sp(Int, Long, Float, Double) A](implicit ev: BoundedSemilattice[A]): BoundedSemilattice[A] = ev + * Access an implicit `BoundedSemilattice[A]`. + */ + @inline final def apply[@sp(Int, Long, Float, Double) A](implicit ev: BoundedSemilattice[A]): BoundedSemilattice[A] = + ev } diff --git a/kernel/src/main/scala/cats/kernel/CommutativeGroup.scala b/kernel/src/main/scala/cats/kernel/CommutativeGroup.scala index 80a5c6fa8c8..0bc6332446c 100644 --- a/kernel/src/main/scala/cats/kernel/CommutativeGroup.scala +++ b/kernel/src/main/scala/cats/kernel/CommutativeGroup.scala @@ -1,17 +1,17 @@ package cats.kernel -import scala.{ specialized => sp } +import scala.{specialized => sp} /** - * An commutative group (also known as an abelian group) is a group - * whose combine operation is commutative. - */ + * An commutative group (also known as an abelian group) is a group + * whose combine operation is commutative. + */ trait CommutativeGroup[@sp(Int, Long, Float, Double) A] extends Any with Group[A] with CommutativeMonoid[A] object CommutativeGroup extends GroupFunctions[CommutativeGroup] { /** - * Access an implicit `CommutativeGroup[A]`. - */ + * Access an implicit `CommutativeGroup[A]`. + */ @inline final def apply[A](implicit ev: CommutativeGroup[A]): CommutativeGroup[A] = ev } diff --git a/kernel/src/main/scala/cats/kernel/CommutativeMonoid.scala b/kernel/src/main/scala/cats/kernel/CommutativeMonoid.scala index c8bb7a36577..a5021a4fbf8 100644 --- a/kernel/src/main/scala/cats/kernel/CommutativeMonoid.scala +++ b/kernel/src/main/scala/cats/kernel/CommutativeMonoid.scala @@ -1,17 +1,18 @@ package cats.kernel -import scala.{ specialized => sp } +import scala.{specialized => sp} /** - * CommutativeMonoid represents a commutative monoid. - * - * A monoid is commutative if for all x and y, x |+| y === y |+| x. - */ + * CommutativeMonoid represents a commutative monoid. + * + * A monoid is commutative if for all x and y, x |+| y === y |+| x. + */ trait CommutativeMonoid[@sp(Int, Long, Float, Double) A] extends Any with Monoid[A] with CommutativeSemigroup[A] object CommutativeMonoid extends MonoidFunctions[CommutativeMonoid] { + /** - * Access an implicit `CommutativeMonoid[A]`. - */ + * Access an implicit `CommutativeMonoid[A]`. + */ @inline final def apply[A](implicit ev: CommutativeMonoid[A]): CommutativeMonoid[A] = ev } diff --git a/kernel/src/main/scala/cats/kernel/CommutativeSemigroup.scala b/kernel/src/main/scala/cats/kernel/CommutativeSemigroup.scala index 2874a6b5d86..d1406a6890d 100644 --- a/kernel/src/main/scala/cats/kernel/CommutativeSemigroup.scala +++ b/kernel/src/main/scala/cats/kernel/CommutativeSemigroup.scala @@ -1,18 +1,18 @@ package cats.kernel -import scala.{ specialized => sp } +import scala.{specialized => sp} /** - * CommutativeSemigroup represents a commutative semigroup. - * - * A semigroup is commutative if for all x and y, x |+| y === y |+| x. - */ + * CommutativeSemigroup represents a commutative semigroup. + * + * A semigroup is commutative if for all x and y, x |+| y === y |+| x. + */ trait CommutativeSemigroup[@sp(Int, Long, Float, Double) A] extends Any with Semigroup[A] object CommutativeSemigroup extends SemigroupFunctions[CommutativeSemigroup] { /** - * Access an implicit `CommutativeSemigroup[A]`. - */ + * Access an implicit `CommutativeSemigroup[A]`. + */ @inline final def apply[A](implicit ev: CommutativeSemigroup[A]): CommutativeSemigroup[A] = ev } diff --git a/kernel/src/main/scala/cats/kernel/Comparison.scala b/kernel/src/main/scala/cats/kernel/Comparison.scala index 78a24987791..6d3a25faa37 100644 --- a/kernel/src/main/scala/cats/kernel/Comparison.scala +++ b/kernel/src/main/scala/cats/kernel/Comparison.scala @@ -5,26 +5,24 @@ sealed abstract class Comparison(val toInt: Int, val toDouble: Double) extends P object Comparison { final case object GreaterThan extends Comparison(1, 1.0) - final case object EqualTo extends Comparison(0, 0.0) - final case object LessThan extends Comparison(-1, -1.0) + final case object EqualTo extends Comparison(0, 0.0) + final case object LessThan extends Comparison(-1, -1.0) // Used for fromDouble private val SomeGt = Some(Comparison.GreaterThan) private val SomeEq = Some(Comparison.EqualTo) private val SomeLt = Some(Comparison.LessThan) - def fromInt(int: Int): Comparison = { - if (int > 0) Comparison.GreaterThan + def fromInt(int: Int): Comparison = + if (int > 0) Comparison.GreaterThan else if (int == 0) Comparison.EqualTo - else Comparison.LessThan // scalastyle:ignore ensure.single.space.after.token - } + else Comparison.LessThan // scalastyle:ignore ensure.single.space.after.token - def fromDouble(double: Double): Option[Comparison] = { + def fromDouble(double: Double): Option[Comparison] = if (double.isNaN) None else if (double > 0.0) SomeGt else if (double == 0.0) SomeEq else SomeLt - } implicit val catsKernelEqForComparison: Eq[Comparison] = Eq.fromUniversalEquals } diff --git a/kernel/src/main/scala/cats/kernel/Eq.scala b/kernel/src/main/scala/cats/kernel/Eq.scala index 9caf1c0700b..1885e013329 100644 --- a/kernel/src/main/scala/cats/kernel/Eq.scala +++ b/kernel/src/main/scala/cats/kernel/Eq.scala @@ -5,20 +5,20 @@ import scala.{specialized => sp} import scala.math.Equiv /** - * A type class used to determine equality between 2 instances of the same - * type. Any 2 instances `x` and `y` are equal if `eqv(x, y)` is `true`. - * Moreover, `eqv` should form an equivalence relation. - */ + * A type class used to determine equality between 2 instances of the same + * type. Any 2 instances `x` and `y` are equal if `eqv(x, y)` is `true`. + * Moreover, `eqv` should form an equivalence relation. + */ trait Eq[@sp A] extends Any with Serializable { self => /** - * Returns `true` if `x` and `y` are equivalent, `false` otherwise. - */ + * Returns `true` if `x` and `y` are equivalent, `false` otherwise. + */ def eqv(x: A, y: A): Boolean /** - * Returns `false` if `x` and `y` are equivalent, `true` otherwise. - */ + * Returns `false` if `x` and `y` are equivalent, `true` otherwise. + */ def neqv(x: A, y: A): Boolean = !eqv(x, y) } @@ -33,10 +33,11 @@ abstract class EqFunctions[E[T] <: Eq[T]] { } trait EqToEquivConversion { + /** - * Implicitly derive a `scala.math.Equiv[A]` from a `Eq[A]` - * instance. - */ + * Implicitly derive a `scala.math.Equiv[A]` from a `Eq[A]` + * instance. + */ implicit def catsKernelEquivForEq[A](implicit ev: Eq[A]): Equiv[A] = new Equiv[A] { def equiv(a: A, b: A) = ev.eqv(a, b) } @@ -45,14 +46,14 @@ trait EqToEquivConversion { object Eq extends EqFunctions[Eq] with EqToEquivConversion { /** - * Access an implicit `Eq[A]`. - */ + * Access an implicit `Eq[A]`. + */ @inline final def apply[A](implicit ev: Eq[A]): Eq[A] = ev /** - * Convert an implicit `Eq[B]` to an `Eq[A]` using the given - * function `f`. - */ + * Convert an implicit `Eq[B]` to an `Eq[A]` using the given + * function `f`. + */ def by[@sp A, @sp B](f: A => B)(implicit ev: Eq[B]): Eq[A] = new Eq[A] { def eqv(x: A, y: A) = ev.eqv(f(x), f(y)) @@ -76,37 +77,36 @@ object Eq extends EqFunctions[Eq] with EqToEquivConversion { def eqv(x: A, y: A) = eq1.eqv(x, y) || eq2.eqv(x, y) } - /** - * Create an `Eq` instance from an `eqv` implementation. - */ + * Create an `Eq` instance from an `eqv` implementation. + */ def instance[A](f: (A, A) => Boolean): Eq[A] = new Eq[A] { def eqv(x: A, y: A) = f(x, y) } /** - * An `Eq[A]` that delegates to universal equality (`==`). - * - * This can be useful for case classes, which have reasonable `equals` - * implementations - */ + * An `Eq[A]` that delegates to universal equality (`==`). + * + * This can be useful for case classes, which have reasonable `equals` + * implementations + */ def fromUniversalEquals[A]: Eq[A] = new Eq[A] { def eqv(x: A, y: A) = x == y } /** - * Everything is the same - */ + * Everything is the same + */ def allEqual[A]: Eq[A] = new Eq[A] { def eqv(x: A, y: A) = true } /** - * This is a monoid that creates an Eq that - * checks that all equality checks pass - */ + * This is a monoid that creates an Eq that + * checks that all equality checks pass + */ def allEqualBoundedSemilattice[A]: BoundedSemilattice[Eq[A]] = new BoundedSemilattice[Eq[A]] { def empty = allEqual[A] def combine(e1: Eq[A], e2: Eq[A]): Eq[A] = Eq.and(e1, e2) @@ -121,9 +121,9 @@ object Eq extends EqFunctions[Eq] with EqToEquivConversion { } /** - * This is a monoid that creates an Eq that - * checks that at least one equality check passes - */ + * This is a monoid that creates an Eq that + * checks that at least one equality check passes + */ def anyEqualSemilattice[A]: Semilattice[Eq[A]] = new Semilattice[Eq[A]] { def combine(e1: Eq[A], e2: Eq[A]): Eq[A] = Eq.or(e1, e2) override def combineAllOption(es: TraversableOnce[Eq[A]]): Option[Eq[A]] = diff --git a/kernel/src/main/scala/cats/kernel/Group.scala b/kernel/src/main/scala/cats/kernel/Group.scala index 31d019146f3..6889df23364 100644 --- a/kernel/src/main/scala/cats/kernel/Group.scala +++ b/kernel/src/main/scala/cats/kernel/Group.scala @@ -1,47 +1,47 @@ package cats.kernel -import scala.{ specialized => sp } +import scala.{specialized => sp} /** - * A group is a monoid where each element has an inverse. - */ + * A group is a monoid where each element has an inverse. + */ trait Group[@sp(Int, Long, Float, Double) A] extends Any with Monoid[A] { /** - * Find the inverse of `a`. - * - * `combine(a, inverse(a))` = `combine(inverse(a), a)` = `empty`. - * - * Example: - * {{{ - * scala> import cats.kernel.instances.int._ - * - * scala> Group[Int].inverse(5) - * res0: Int = -5 - * }}} - */ + * Find the inverse of `a`. + * + * `combine(a, inverse(a))` = `combine(inverse(a), a)` = `empty`. + * + * Example: + * {{{ + * scala> import cats.kernel.instances.int._ + * + * scala> Group[Int].inverse(5) + * res0: Int = -5 + * }}} + */ def inverse(a: A): A /** - * Remove the element `b` from `a`. - * - * Equivalent to `combine(a, inverse(b))` - * - * Example: - * {{{ - * scala> import cats.kernel.instances.int._ - * - * scala> Group[Int].remove(5, 2) - * res0: Int = 3 - * }}} - */ + * Remove the element `b` from `a`. + * + * Equivalent to `combine(a, inverse(b))` + * + * Example: + * {{{ + * scala> import cats.kernel.instances.int._ + * + * scala> Group[Int].remove(5, 2) + * res0: Int = 3 + * }}} + */ def remove(a: A, b: A): A = combine(a, inverse(b)) /** - * Return `a` appended to itself `n` times. If `n` is negative, then - * this returns `inverse(a)` appended to itself `n` times. - */ - override def combineN(a: A, n: Int): A = { + * Return `a` appended to itself `n` times. If `n` is negative, then + * this returns `inverse(a)` appended to itself `n` times. + */ + override def combineN(a: A, n: Int): A = // This method is a bit tricky. Normally, to sum x a negative // number of times (n), we can sum (-x) a positive number of times // (-n). The issue here is that Int.MinValue cannot be negated; in @@ -58,7 +58,6 @@ trait Group[@sp(Int, Long, Float, Double) A] extends Any with Monoid[A] { else if (n == 0) empty else if (n == Int.MinValue) combineN(inverse(combine(a, a)), 1073741824) else repeatedCombineN(inverse(a), -n) - } } abstract class GroupFunctions[G[T] <: Group[T]] extends MonoidFunctions[Group] { @@ -72,7 +71,7 @@ abstract class GroupFunctions[G[T] <: Group[T]] extends MonoidFunctions[Group] { object Group extends GroupFunctions[Group] { /** - * Access an implicit `Group[A]`. - */ + * Access an implicit `Group[A]`. + */ @inline final def apply[A](implicit ev: Group[A]): Group[A] = ev } diff --git a/kernel/src/main/scala/cats/kernel/Hash.scala b/kernel/src/main/scala/cats/kernel/Hash.scala index 4579f121848..866e4e0cc09 100644 --- a/kernel/src/main/scala/cats/kernel/Hash.scala +++ b/kernel/src/main/scala/cats/kernel/Hash.scala @@ -4,16 +4,16 @@ import scala.{specialized => sp} import scala.util.hashing.Hashing /** - * A type class used to represent a hashing scheme for objects of a given type. - * For any two instances `x` and `y` that are considered equivalent under the - * equivalence relation defined by this object, `hash(x)` should equal `hash(y)`. - * @author Tongfei Chen - */ + * A type class used to represent a hashing scheme for objects of a given type. + * For any two instances `x` and `y` that are considered equivalent under the + * equivalence relation defined by this object, `hash(x)` should equal `hash(y)`. + * @author Tongfei Chen + */ trait Hash[@sp A] extends Any with Eq[A] with Serializable { self => /** - * Returns the hash code of the given object under this hashing scheme. - */ + * Returns the hash code of the given object under this hashing scheme. + */ def hash(x: A): Int // `Hash#toHashing` deliberately not implemented since `scala.util.hashing.Hashing` is only @@ -26,7 +26,6 @@ abstract class HashFunctions[H[T] <: Hash[T]] extends EqFunctions[H] { } - object Hash extends HashFunctions[Hash] { /** Fetch a `Hash` instance given the specific type. */ @@ -45,8 +44,8 @@ object Hash extends HashFunctions[Hash] { } /** - * Constructs a `Hash` instance by using the universal `hashCode` function and the universal equality relation. - */ + * Constructs a `Hash` instance by using the universal `hashCode` function and the universal equality relation. + */ def fromUniversalHashCode[A]: Hash[A] = new Hash[A] { def hash(x: A) = x.hashCode() diff --git a/kernel/src/main/scala/cats/kernel/Monoid.scala b/kernel/src/main/scala/cats/kernel/Monoid.scala index 3dab5678afb..9817dc304ca 100644 --- a/kernel/src/main/scala/cats/kernel/Monoid.scala +++ b/kernel/src/main/scala/cats/kernel/Monoid.scala @@ -1,82 +1,82 @@ package cats.kernel -import scala.{ specialized => sp } +import scala.{specialized => sp} /** - * A monoid is a semigroup with an identity. A monoid is a specialization of a - * semigroup, so its operation must be associative. Additionally, - * `combine(x, empty) == combine(empty, x) == x`. For example, if we have `Monoid[String]`, - * with `combine` as string concatenation, then `empty = ""`. - */ + * A monoid is a semigroup with an identity. A monoid is a specialization of a + * semigroup, so its operation must be associative. Additionally, + * `combine(x, empty) == combine(empty, x) == x`. For example, if we have `Monoid[String]`, + * with `combine` as string concatenation, then `empty = ""`. + */ trait Monoid[@sp(Int, Long, Float, Double) A] extends Any with Semigroup[A] { /** - * Return the identity element for this monoid. - * - * Example: - * {{{ - * scala> import cats.kernel.instances.int._ - * scala> import cats.kernel.instances.string._ - * - * scala> Monoid[String].empty - * res0: String = "" - * - * scala> Monoid[Int].empty - * res1: Int = 0 - * }}} - */ + * Return the identity element for this monoid. + * + * Example: + * {{{ + * scala> import cats.kernel.instances.int._ + * scala> import cats.kernel.instances.string._ + * + * scala> Monoid[String].empty + * res0: String = "" + * + * scala> Monoid[Int].empty + * res1: Int = 0 + * }}} + */ def empty: A /** - * Tests if `a` is the identity. - * - * Example: - * {{{ - * scala> import cats.kernel.instances.string._ - * - * scala> Monoid[String].isEmpty("") - * res0: Boolean = true - * - * scala> Monoid[String].isEmpty("something") - * res1: Boolean = false - * }}} - */ + * Tests if `a` is the identity. + * + * Example: + * {{{ + * scala> import cats.kernel.instances.string._ + * + * scala> Monoid[String].isEmpty("") + * res0: Boolean = true + * + * scala> Monoid[String].isEmpty("something") + * res1: Boolean = false + * }}} + */ def isEmpty(a: A)(implicit ev: Eq[A]): Boolean = ev.eqv(a, empty) /** - * Return `a` appended to itself `n` times. - * - * Example: - * {{{ - * scala> import cats.kernel.instances.string._ - * - * scala> Monoid[String].combineN("ha", 3) - * res0: String = hahaha - * - * scala> Monoid[String].combineN("ha", 0) - * res1: String = "" - * }}} - */ + * Return `a` appended to itself `n` times. + * + * Example: + * {{{ + * scala> import cats.kernel.instances.string._ + * + * scala> Monoid[String].combineN("ha", 3) + * res0: String = hahaha + * + * scala> Monoid[String].combineN("ha", 0) + * res1: String = "" + * }}} + */ override def combineN(a: A, n: Int): A = if (n < 0) throw new IllegalArgumentException("Repeated combining for monoids must have n >= 0") else if (n == 0) empty else repeatedCombineN(a, n) /** - * Given a sequence of `as`, sum them using the monoid and return the total. - * - * Example: - * {{{ - * scala> import cats.kernel.instances.string._ - * - * scala> Monoid[String].combineAll(List("One ", "Two ", "Three")) - * res0: String = One Two Three - * - * scala> Monoid[String].combineAll(List.empty) - * res1: String = "" - * }}} - */ + * Given a sequence of `as`, sum them using the monoid and return the total. + * + * Example: + * {{{ + * scala> import cats.kernel.instances.string._ + * + * scala> Monoid[String].combineAll(List("One ", "Two ", "Three")) + * res0: String = One Two Three + * + * scala> Monoid[String].combineAll(List.empty) + * res1: String = "" + * }}} + */ def combineAll(as: TraversableOnce[A]): A = as.foldLeft(empty)(combine) @@ -98,7 +98,7 @@ abstract class MonoidFunctions[M[T] <: Monoid[T]] extends SemigroupFunctions[M] object Monoid extends MonoidFunctions[Monoid] { /** - * Access an implicit `Monoid[A]`. - */ + * Access an implicit `Monoid[A]`. + */ @inline final def apply[A](implicit ev: Monoid[A]): Monoid[A] = ev } diff --git a/kernel/src/main/scala/cats/kernel/Order.scala b/kernel/src/main/scala/cats/kernel/Order.scala index 4b67ad8645f..7b6ded0e1f8 100644 --- a/kernel/src/main/scala/cats/kernel/Order.scala +++ b/kernel/src/main/scala/cats/kernel/Order.scala @@ -3,95 +3,96 @@ package cats.kernel import scala.{specialized => sp} /** - * The `Order` type class is used to define a total ordering on some type `A`. - * An order is defined by a relation <=, which obeys the following laws: - * - * - either x <= y or y <= x (totality) - * - if x <= y and y <= x, then x == y (antisymmetry) - * - if x <= y and y <= z, then x <= z (transitivity) - * - * The truth table for compare is defined as follows: - * - * x <= y x >= y Int - * true true = 0 (corresponds to x == y) - * true false < 0 (corresponds to x < y) - * false true > 0 (corresponds to x > y) - * - * By the totality law, x <= y and y <= x cannot be both false. - */ + * The `Order` type class is used to define a total ordering on some type `A`. + * An order is defined by a relation <=, which obeys the following laws: + * + * - either x <= y or y <= x (totality) + * - if x <= y and y <= x, then x == y (antisymmetry) + * - if x <= y and y <= z, then x <= z (transitivity) + * + * The truth table for compare is defined as follows: + * + * x <= y x >= y Int + * true true = 0 (corresponds to x == y) + * true false < 0 (corresponds to x < y) + * false true > 0 (corresponds to x > y) + * + * By the totality law, x <= y and y <= x cannot be both false. + */ trait Order[@sp A] extends Any with PartialOrder[A] { self => + /** - * Result of comparing `x` with `y`. Returns an Int whose sign is: - * - negative iff `x < y` - * - zero iff `x = y` - * - positive iff `x > y` - */ + * Result of comparing `x` with `y`. Returns an Int whose sign is: + * - negative iff `x < y` + * - zero iff `x = y` + * - positive iff `x > y` + */ def compare(x: A, y: A): Int /** - * Like `compare`, but returns a [[cats.kernel.Comparison]] instead of an Int. - * Has the benefit of being able to pattern match on, but not as performant. - */ + * Like `compare`, but returns a [[cats.kernel.Comparison]] instead of an Int. + * Has the benefit of being able to pattern match on, but not as performant. + */ def comparison(x: A, y: A): Comparison = Comparison.fromInt(compare(x, y)) def partialCompare(x: A, y: A): Double = compare(x, y).toDouble /** - * If x <= y, return x, else return y. - */ + * If x <= y, return x, else return y. + */ def min(x: A, y: A): A = if (lt(x, y)) x else y /** - * If x >= y, return x, else return y. - */ + * If x >= y, return x, else return y. + */ def max(x: A, y: A): A = if (gt(x, y)) x else y // The following may be overridden for performance: /** - * Returns true if `x` = `y`, false otherwise. - */ + * Returns true if `x` = `y`, false otherwise. + */ override def eqv(x: A, y: A): Boolean = compare(x, y) == 0 /** - * Returns true if `x` != `y`, false otherwise. - * - * Note: this default implementation provided by [[Order]] is the same as the - * one defined in [[Eq]], but for purposes of binary compatibility, the - * override in [[Order]] has not yet been removed. - * See [[https://github.com/typelevel/cats/pull/2230#issuecomment-381818633 this discussion]]. - */ + * Returns true if `x` != `y`, false otherwise. + * + * Note: this default implementation provided by [[Order]] is the same as the + * one defined in [[Eq]], but for purposes of binary compatibility, the + * override in [[Order]] has not yet been removed. + * See [[https://github.com/typelevel/cats/pull/2230#issuecomment-381818633 this discussion]]. + */ override def neqv(x: A, y: A): Boolean = !eqv(x, y) /** - * Returns true if `x` <= `y`, false otherwise. - */ + * Returns true if `x` <= `y`, false otherwise. + */ override def lteqv(x: A, y: A): Boolean = compare(x, y) <= 0 /** - * Returns true if `x` < `y`, false otherwise. - */ + * Returns true if `x` < `y`, false otherwise. + */ override def lt(x: A, y: A): Boolean = compare(x, y) < 0 /** - * Returns true if `x` >= `y`, false otherwise. - */ + * Returns true if `x` >= `y`, false otherwise. + */ override def gteqv(x: A, y: A): Boolean = compare(x, y) >= 0 /** - * Returns true if `x` > `y`, false otherwise. - */ + * Returns true if `x` > `y`, false otherwise. + */ override def gt(x: A, y: A): Boolean = compare(x, y) > 0 /** - * Convert a `Order[A]` to a `scala.math.Ordering[A]` - * instance. - */ + * Convert a `Order[A]` to a `scala.math.Ordering[A]` + * instance. + */ def toOrdering: Ordering[A] = new Ordering[A] { def compare(x: A, y: A): Int = self.compare(x, y) } @@ -113,25 +114,27 @@ abstract class OrderFunctions[O[T] <: Order[T]] extends PartialOrderFunctions[O] } trait OrderToOrderingConversion { + /** - * Implicitly derive a `scala.math.Ordering[A]` from a `Order[A]` - * instance. - */ + * Implicitly derive a `scala.math.Ordering[A]` from a `Order[A]` + * instance. + */ implicit def catsKernelOrderingForOrder[A](implicit ev: Order[A]): Ordering[A] = ev.toOrdering } object Order extends OrderFunctions[Order] with OrderToOrderingConversion { + /** - * Access an implicit `Order[A]`. - */ + * Access an implicit `Order[A]`. + */ @inline final def apply[A](implicit ev: Order[A]): Order[A] = ev /** - * Convert an implicit `Order[B]` to an `Order[A]` using the given - * function `f`. - */ + * Convert an implicit `Order[B]` to an `Order[A]` using the given + * function `f`. + */ def by[@sp A, @sp B](f: A => B)(implicit ev: Order[B]): Order[A] = new Order[A] { def compare(x: A, y: A): Int = ev.compare(f(x), f(y)) @@ -162,16 +165,16 @@ object Order extends OrderFunctions[Order] with OrderToOrderingConversion { } /** - * Define an `Order[A]` using the given function `f`. - */ + * Define an `Order[A]` using the given function `f`. + */ def from[@sp A](f: (A, A) => Int): Order[A] = new Order[A] { def compare(x: A, y: A) = f(x, y) } /** - * Define an `Order[A]` using the given 'less than' function `f`. - */ + * Define an `Order[A]` using the given 'less than' function `f`. + */ def fromLessThan[@sp A](f: (A, A) => Boolean): Order[A] = new Order[A] { override def compare(x: A, y: A): Int = @@ -187,28 +190,28 @@ object Order extends OrderFunctions[Order] with OrderToOrderingConversion { } /** - * An `Order` instance that considers all `A` instances to be equal. - */ + * An `Order` instance that considers all `A` instances to be equal. + */ def allEqual[A]: Order[A] = new Order[A] { def compare(x: A, y: A): Int = 0 } /** - * A `Monoid[Order[A]]` can be generated for all `A` with the following - * properties: - * - * `empty` returns a trivial `Order[A]` which considers all `A` instances to - * be equal. - * - * `combine(x: Order[A], y: Order[A])` creates an `Order[A]` that first - * orders by `x` and then (if two elements are equal) falls back to `y`. - * - * This monoid is also a `Band[Order[A]]` since its combine - * operations is idempotent. - * - * @see [[Order.whenEqual]] - */ + * A `Monoid[Order[A]]` can be generated for all `A` with the following + * properties: + * + * `empty` returns a trivial `Order[A]` which considers all `A` instances to + * be equal. + * + * `combine(x: Order[A], y: Order[A])` creates an `Order[A]` that first + * orders by `x` and then (if two elements are equal) falls back to `y`. + * + * This monoid is also a `Band[Order[A]]` since its combine + * operations is idempotent. + * + * @see [[Order.whenEqual]] + */ def whenEqualMonoid[A]: Monoid[Order[A]] with Band[Order[A]] = new Monoid[Order[A]] with Band[Order[A]] { val empty: Order[A] = allEqual[A] @@ -222,10 +225,9 @@ object Order extends OrderFunctions[Order] with OrderToOrderingConversion { override def toOrdering: Ordering[A] = ev } - def fromComparable[A <: Comparable[A]]: Order[A] = { + def fromComparable[A <: Comparable[A]]: Order[A] = new Order[A] { override def compare(x: A, y: A): Int = - x compareTo y + x.compareTo(y) } - } } diff --git a/kernel/src/main/scala/cats/kernel/PartialOrder.scala b/kernel/src/main/scala/cats/kernel/PartialOrder.scala index caa3baf535f..84ca580fe74 100644 --- a/kernel/src/main/scala/cats/kernel/PartialOrder.scala +++ b/kernel/src/main/scala/cats/kernel/PartialOrder.scala @@ -4,58 +4,59 @@ import java.lang.Double.isNaN import scala.{specialized => sp} /** - * The `PartialOrder` type class is used to define a partial ordering on some type `A`. - * - * A partial order is defined by a relation <=, which obeys the following laws: - * - * - x <= x (reflexivity) - * - if x <= y and y <= x, then x = y (anti-symmetry) - * - if x <= y and y <= z, then x <= z (transitivity) - * - * To compute both <= and >= at the same time, we use a Double number - * to encode the result of the comparisons x <= y and x >= y. - * The truth table is defined as follows: - * - * x <= y x >= y Double - * true true = 0.0 (corresponds to x = y) - * false false = NaN (x and y cannot be compared) - * true false = -1.0 (corresponds to x < y) - * false true = 1.0 (corresponds to x > y) - */ + * The `PartialOrder` type class is used to define a partial ordering on some type `A`. + * + * A partial order is defined by a relation <=, which obeys the following laws: + * + * - x <= x (reflexivity) + * - if x <= y and y <= x, then x = y (anti-symmetry) + * - if x <= y and y <= z, then x <= z (transitivity) + * + * To compute both <= and >= at the same time, we use a Double number + * to encode the result of the comparisons x <= y and x >= y. + * The truth table is defined as follows: + * + * x <= y x >= y Double + * true true = 0.0 (corresponds to x = y) + * false false = NaN (x and y cannot be compared) + * true false = -1.0 (corresponds to x < y) + * false true = 1.0 (corresponds to x > y) + */ trait PartialOrder[@sp A] extends Any with Eq[A] { self => + /** - * Result of comparing `x` with `y`. Returns NaN if operands are not - * comparable. If operands are comparable, returns a Double whose - * sign is: - * - negative iff `x < y` - * - zero iff `x = y` - * - positive iff `x > y` - */ + * Result of comparing `x` with `y`. Returns NaN if operands are not + * comparable. If operands are comparable, returns a Double whose + * sign is: + * - negative iff `x < y` + * - zero iff `x = y` + * - positive iff `x > y` + */ def partialCompare(x: A, y: A): Double /** - * Like `partialCompare`, but returns a [[cats.kernel.Comparison]] instead of an Double. - * Has the benefit of being able to pattern match on, but not as performant. - */ + * Like `partialCompare`, but returns a [[cats.kernel.Comparison]] instead of an Double. + * Has the benefit of being able to pattern match on, but not as performant. + */ def partialComparison(x: A, y: A): Option[Comparison] = Comparison.fromDouble(partialCompare(x, y)) /** - * Result of comparing `x` with `y`. Returns None if operands are - * not comparable. If operands are comparable, returns Some[Int] - * where the Int sign is: - * - negative iff `x < y` - * - zero iff `x = y` - * - positive iff `x > y` - */ + * Result of comparing `x` with `y`. Returns None if operands are + * not comparable. If operands are comparable, returns Some[Int] + * where the Int sign is: + * - negative iff `x < y` + * - zero iff `x = y` + * - positive iff `x > y` + */ def tryCompare(x: A, y: A): Option[Int] = { val c = partialCompare(x, y) if (isNaN(c)) None else Some(c.signum) } /** - * Returns Some(x) if x <= y, Some(y) if x > y, otherwise None. - */ + * Returns Some(x) if x <= y, Some(y) if x > y, otherwise None. + */ def pmin(x: A, y: A): Option[A] = { val c = partialCompare(x, y) if (c <= 0) Some(x) @@ -64,11 +65,11 @@ trait PartialOrder[@sp A] extends Any with Eq[A] { self => } /** - * Returns Some(x) if x >= y, Some(y) if x < y, otherwise None. - */ + * Returns Some(x) if x >= y, Some(y) if x < y, otherwise None. + */ def pmax(x: A, y: A): Option[A] = { val c = partialCompare(x, y) - if (c >= 0) Some(x) + if (c >= 0) Some(x) else if (c < 0) Some(y) else None } @@ -76,28 +77,28 @@ trait PartialOrder[@sp A] extends Any with Eq[A] { self => // The following may be overridden for performance: /** - * Returns true if `x` = `y`, false otherwise. - */ + * Returns true if `x` = `y`, false otherwise. + */ def eqv(x: A, y: A): Boolean = partialCompare(x, y) == 0 /** - * Returns true if `x` <= `y`, false otherwise. - */ + * Returns true if `x` <= `y`, false otherwise. + */ def lteqv(x: A, y: A): Boolean = partialCompare(x, y) <= 0 /** - * Returns true if `x` < `y`, false otherwise. - */ + * Returns true if `x` < `y`, false otherwise. + */ def lt(x: A, y: A): Boolean = partialCompare(x, y) < 0 /** - * Returns true if `x` >= `y`, false otherwise. - */ + * Returns true if `x` >= `y`, false otherwise. + */ def gteqv(x: A, y: A): Boolean = partialCompare(x, y) >= 0 /** - * Returns true if `x` > `y`, false otherwise. - */ + * Returns true if `x` > `y`, false otherwise. + */ def gt(x: A, y: A): Boolean = partialCompare(x, y) > 0 } @@ -124,15 +125,16 @@ abstract class PartialOrderFunctions[P[T] <: PartialOrder[T]] extends EqFunction } object PartialOrder extends PartialOrderFunctions[PartialOrder] with PartialOrderToPartialOrderingConversion { + /** - * Access an implicit `PartialOrder[A]`. - */ + * Access an implicit `PartialOrder[A]`. + */ @inline final def apply[A](implicit ev: PartialOrder[A]): PartialOrder[A] = ev /** - * Convert an implicit `PartialOrder[B]` to an `PartialOrder[A]` using the given - * function `f`. - */ + * Convert an implicit `PartialOrder[B]` to an `PartialOrder[A]` using the given + * function `f`. + */ def by[@sp A, @sp B](f: A => B)(implicit ev: PartialOrder[B]): PartialOrder[A] = new PartialOrder[A] { def partialCompare(x: A, y: A): Double = ev.partialCompare(f(x), f(y)) @@ -147,8 +149,8 @@ object PartialOrder extends PartialOrderFunctions[PartialOrder] with PartialOrde } /** - * Define a `PartialOrder[A]` using the given function `f`. - */ + * Define a `PartialOrder[A]` using the given function `f`. + */ def from[@sp A](f: (A, A) => Double): PartialOrder[A] = new PartialOrder[A] { def partialCompare(x: A, y: A) = f(x, y) @@ -160,7 +162,6 @@ object PartialOrder extends PartialOrderFunctions[PartialOrder] with PartialOrde } } - trait PartialOrderToPartialOrderingConversion { implicit def catsKernelPartialOrderingForPartialOrder[A](implicit ev: PartialOrder[A]): PartialOrdering[A] = new PartialOrdering[A] { diff --git a/kernel/src/main/scala/cats/kernel/Semigroup.scala b/kernel/src/main/scala/cats/kernel/Semigroup.scala index 5665324abcf..66a3c485044 100644 --- a/kernel/src/main/scala/cats/kernel/Semigroup.scala +++ b/kernel/src/main/scala/cats/kernel/Semigroup.scala @@ -2,54 +2,56 @@ package cats.kernel import scala.{specialized => sp} import scala.annotation.tailrec + /** - * A semigroup is any set `A` with an associative operation (`combine`). - */ + * A semigroup is any set `A` with an associative operation (`combine`). + */ trait Semigroup[@sp(Int, Long, Float, Double) A] extends Any with Serializable { /** - * Associative operation which combines two values. - * - * Example: - * {{{ - * scala> import cats.kernel.instances.string._ - * scala> import cats.kernel.instances.int._ - * scala> import cats.kernel.instances.option._ - * - * scala> Semigroup[String].combine("Hello ", "World!") - * res0: String = Hello World! - * - * scala> Semigroup[Option[Int]].combine(None, Some(1)) - * res1: Option[Int] = Some(1) - * }}} - */ + * Associative operation which combines two values. + * + * Example: + * {{{ + * scala> import cats.kernel.instances.string._ + * scala> import cats.kernel.instances.int._ + * scala> import cats.kernel.instances.option._ + * + * scala> Semigroup[String].combine("Hello ", "World!") + * res0: String = Hello World! + * + * scala> Semigroup[Option[Int]].combine(None, Some(1)) + * res1: Option[Int] = Some(1) + * }}} + */ def combine(x: A, y: A): A /** - * Return `a` combined with itself `n` times. - * - * Example: - * {{{ - * scala> import cats.kernel.instances.int._ - * scala> import cats.kernel.instances.string._ - * - * scala> Semigroup[Int].combineN(1, 10) - * res0: Int = 10 - * - * scala> Semigroup[String].combineN("ha", 3) - * res1: String = hahaha - * }}} - */ + * Return `a` combined with itself `n` times. + * + * Example: + * {{{ + * scala> import cats.kernel.instances.int._ + * scala> import cats.kernel.instances.string._ + * + * scala> Semigroup[Int].combineN(1, 10) + * res0: Int = 10 + * + * scala> Semigroup[String].combineN("ha", 3) + * res1: String = hahaha + * }}} + */ def combineN(a: A, n: Int): A = if (n <= 0) throw new IllegalArgumentException("Repeated combining for semigroups must have n > 0") else repeatedCombineN(a, n) /** - * Return `a` combined with itself more than once. - */ + * Return `a` combined with itself more than once. + */ protected[this] def repeatedCombineN(a: A, n: Int): A = { @tailrec def loop(b: A, k: Int, extra: A): A = - if (k == 1) combine(b, extra) else { + if (k == 1) combine(b, extra) + else { val x = if ((k & 1) == 1) combine(b, extra) else extra loop(combine(b, b), k >>> 1, x) } @@ -57,21 +59,21 @@ trait Semigroup[@sp(Int, Long, Float, Double) A] extends Any with Serializable { } /** - * Given a sequence of `as`, combine them and return the total. - * - * If the sequence is empty, returns None. Otherwise, returns Some(total). - * - * Example: - * {{{ - * scala> import cats.kernel.instances.string._ - * - * scala> Semigroup[String].combineAllOption(List("One ", "Two ", "Three")) - * res0: Option[String] = Some(One Two Three) - * - * scala> Semigroup[String].combineAllOption(List.empty) - * res1: Option[String] = None - * }}} - */ + * Given a sequence of `as`, combine them and return the total. + * + * If the sequence is empty, returns None. Otherwise, returns Some(total). + * + * Example: + * {{{ + * scala> import cats.kernel.instances.string._ + * + * scala> Semigroup[String].combineAllOption(List("One ", "Two ", "Three")) + * res0: Option[String] = Some(One Two Three) + * + * scala> Semigroup[String].combineAllOption(List.empty) + * res1: Option[String] = None + * }}} + */ def combineAllOption(as: TraversableOnce[A]): Option[A] = cats.kernel.compat.TraversableOnce.reduceOption(as, combine) } @@ -83,13 +85,13 @@ abstract class SemigroupFunctions[S[T] <: Semigroup[T]] { def maybeCombine[@sp(Int, Long, Float, Double) A](ox: Option[A], y: A)(implicit ev: S[A]): A = ox match { case Some(x) => ev.combine(x, y) - case None => y + case None => y } def maybeCombine[@sp(Int, Long, Float, Double) A](x: A, oy: Option[A])(implicit ev: S[A]): A = oy match { case Some(y) => ev.combine(x, y) - case None => x + case None => x } def isCommutative[A](implicit ev: S[A]): Boolean = @@ -108,13 +110,13 @@ abstract class SemigroupFunctions[S[T] <: Semigroup[T]] { object Semigroup extends SemigroupFunctions[Semigroup] { /** - * Access an implicit `Semigroup[A]`. - */ + * Access an implicit `Semigroup[A]`. + */ @inline final def apply[A](implicit ev: Semigroup[A]): Semigroup[A] = ev /** - * Create a `Semigroup` instance from the given function. - */ + * Create a `Semigroup` instance from the given function. + */ @inline def instance[A](cmb: (A, A) => A): Semigroup[A] = new Semigroup[A] { override def combine(x: A, y: A): A = cmb(x, y) } diff --git a/kernel/src/main/scala/cats/kernel/Semilattice.scala b/kernel/src/main/scala/cats/kernel/Semilattice.scala index 77a69ff2d5c..4371dfe8b5c 100644 --- a/kernel/src/main/scala/cats/kernel/Semilattice.scala +++ b/kernel/src/main/scala/cats/kernel/Semilattice.scala @@ -3,50 +3,50 @@ package cats.kernel import scala.{specialized => sp} /** - * Semilattices are commutative semigroups whose operation - * (i.e. combine) is also idempotent. - */ -trait Semilattice[@sp(Int, Long, Float, Double) A] extends Any - with Band[A] - with CommutativeSemigroup[A] { self => + * Semilattices are commutative semigroups whose operation + * (i.e. combine) is also idempotent. + */ +trait Semilattice[@sp(Int, Long, Float, Double) A] extends Any with Band[A] with CommutativeSemigroup[A] { self => /** - * Given Eq[A], return a PartialOrder[A] using the `combine` - * operator to determine the partial ordering. This method assumes - * `combine` functions as `meet` (that is, as a lower bound). - * - * This method returns: - * - * 0.0 if x = y - * -1.0 if x = combine(x, y) - * 1.0 if y = combine(x, y) - * NaN otherwise - */ + * Given Eq[A], return a PartialOrder[A] using the `combine` + * operator to determine the partial ordering. This method assumes + * `combine` functions as `meet` (that is, as a lower bound). + * + * This method returns: + * + * 0.0 if x = y + * -1.0 if x = combine(x, y) + * 1.0 if y = combine(x, y) + * NaN otherwise + */ def asMeetPartialOrder(implicit ev: Eq[A]): PartialOrder[A] = new PartialOrder[A] { def partialCompare(x: A, y: A): Double = - if (ev.eqv(x, y)) 0.0 else { + if (ev.eqv(x, y)) 0.0 + else { val z = self.combine(x, y) if (ev.eqv(x, z)) -1.0 else if (ev.eqv(y, z)) 1.0 else Double.NaN } } /** - * Given Eq[A], return a PartialOrder[A] using the `combine` - * operator to determine the partial ordering. This method assumes - * `combine` functions as `join` (that is, as an upper bound). - * - * This method returns: - * - * 0.0 if x = y - * -1.0 if y = combine(x, y) - * 1.0 if x = combine(x, y) - * NaN otherwise - */ + * Given Eq[A], return a PartialOrder[A] using the `combine` + * operator to determine the partial ordering. This method assumes + * `combine` functions as `join` (that is, as an upper bound). + * + * This method returns: + * + * 0.0 if x = y + * -1.0 if y = combine(x, y) + * 1.0 if x = combine(x, y) + * NaN otherwise + */ def asJoinPartialOrder(implicit ev: Eq[A]): PartialOrder[A] = new PartialOrder[A] { def partialCompare(x: A, y: A): Double = - if (ev.eqv(x, y)) 0.0 else { + if (ev.eqv(x, y)) 0.0 + else { val z = self.combine(x, y) if (ev.eqv(y, z)) -1.0 else if (ev.eqv(x, z)) 1.0 else Double.NaN } @@ -63,7 +63,7 @@ abstract class SemilatticeFunctions[S[T] <: Semilattice[T]] extends SemigroupFun object Semilattice extends SemilatticeFunctions[Semilattice] { /** - * Access an implicit `Semilattice[A]`. - */ + * Access an implicit `Semilattice[A]`. + */ @inline final def apply[@sp(Int, Long, Float, Double) A](implicit ev: Semilattice[A]): Semilattice[A] = ev } diff --git a/kernel/src/main/scala/cats/kernel/instances/StaticMethods.scala b/kernel/src/main/scala/cats/kernel/instances/StaticMethods.scala index 47df763c2e8..8e136a15203 100644 --- a/kernel/src/main/scala/cats/kernel/instances/StaticMethods.scala +++ b/kernel/src/main/scala/cats/kernel/instances/StaticMethods.scala @@ -10,10 +10,10 @@ object StaticMethods { new WrappedMutableMap(m) private[kernel] class WrappedMutableMap[K, V](m: mutable.Map[K, V]) - extends kernel.compat.WrappedMutableMapBase[K, V](m) { - override def size: Int = m.size - def get(k: K): Option[V] = m.get(k) - def iterator: Iterator[(K, V)] = m.iterator + extends kernel.compat.WrappedMutableMapBase[K, V](m) { + override def size: Int = m.size + def get(k: K): Option[V] = m.get(k) + def iterator: Iterator[(K, V)] = m.iterator } // scalastyle:off return @@ -119,7 +119,7 @@ object StaticMethods { import scala.util.hashing.MurmurHash3._ var n = 0 var h = seqSeed - xs foreach { x => + xs.foreach { x => h = mix(h, A.hash(x)) n += 1 } diff --git a/kernel/src/main/scala/cats/kernel/instances/all.scala b/kernel/src/main/scala/cats/kernel/instances/all.scala index 75d15035457..bc8f0e6ecc9 100644 --- a/kernel/src/main/scala/cats/kernel/instances/all.scala +++ b/kernel/src/main/scala/cats/kernel/instances/all.scala @@ -35,5 +35,4 @@ trait AllInstances with UUIDInstances with VectorInstances - trait AllInstancesBinCompat0 extends FiniteDurationInstances diff --git a/kernel/src/main/scala/cats/kernel/instances/bigDecimal.scala b/kernel/src/main/scala/cats/kernel/instances/bigDecimal.scala index 910eb8e147a..126617bd685 100644 --- a/kernel/src/main/scala/cats/kernel/instances/bigDecimal.scala +++ b/kernel/src/main/scala/cats/kernel/instances/bigDecimal.scala @@ -21,7 +21,7 @@ class BigDecimalOrder extends Order[BigDecimal] with Hash[BigDecimal] { def hash(x: BigDecimal): Int = x.hashCode() - def compare(x: BigDecimal, y: BigDecimal): Int = x compare y + def compare(x: BigDecimal, y: BigDecimal): Int = x.compare(y) override def eqv(x: BigDecimal, y: BigDecimal): Boolean = x == y override def neqv(x: BigDecimal, y: BigDecimal): Boolean = x != y @@ -30,6 +30,6 @@ class BigDecimalOrder extends Order[BigDecimal] with Hash[BigDecimal] { override def lt(x: BigDecimal, y: BigDecimal): Boolean = x < y override def lteqv(x: BigDecimal, y: BigDecimal): Boolean = x <= y - override def min(x: BigDecimal, y: BigDecimal): BigDecimal = x min y - override def max(x: BigDecimal, y: BigDecimal): BigDecimal = x max y + override def min(x: BigDecimal, y: BigDecimal): BigDecimal = x.min(y) + override def max(x: BigDecimal, y: BigDecimal): BigDecimal = x.max(y) } diff --git a/kernel/src/main/scala/cats/kernel/instances/bigInt.scala b/kernel/src/main/scala/cats/kernel/instances/bigInt.scala index 46a5a26af8f..e52dbac3fa2 100644 --- a/kernel/src/main/scala/cats/kernel/instances/bigInt.scala +++ b/kernel/src/main/scala/cats/kernel/instances/bigInt.scala @@ -20,7 +20,7 @@ class BigIntGroup extends CommutativeGroup[BigInt] { class BigIntOrder extends Order[BigInt] with Hash[BigInt] { def hash(x: BigInt): Int = x.hashCode() - def compare(x: BigInt, y: BigInt): Int = x compare y + def compare(x: BigInt, y: BigInt): Int = x.compare(y) override def eqv(x: BigInt, y: BigInt): Boolean = x == y override def neqv(x: BigInt, y: BigInt): Boolean = x != y @@ -29,6 +29,6 @@ class BigIntOrder extends Order[BigInt] with Hash[BigInt] { override def lt(x: BigInt, y: BigInt): Boolean = x < y override def lteqv(x: BigInt, y: BigInt): Boolean = x <= y - override def min(x: BigInt, y: BigInt): BigInt = x min y - override def max(x: BigInt, y: BigInt): BigInt = x max y + override def min(x: BigInt, y: BigInt): BigInt = x.min(y) + override def max(x: BigInt, y: BigInt): BigInt = x.max(y) } diff --git a/kernel/src/main/scala/cats/kernel/instances/boolean.scala b/kernel/src/main/scala/cats/kernel/instances/boolean.scala index 8b005587966..e217a776183 100644 --- a/kernel/src/main/scala/cats/kernel/instances/boolean.scala +++ b/kernel/src/main/scala/cats/kernel/instances/boolean.scala @@ -14,8 +14,8 @@ class BooleanOrder extends Order[Boolean] with Hash[Boolean] { def compare(x: Boolean, y: Boolean): Int = if (x == y) 0 else if (x) 1 else -1 - override def eqv(x:Boolean, y:Boolean): Boolean = x == y - override def neqv(x:Boolean, y:Boolean): Boolean = x != y + override def eqv(x: Boolean, y: Boolean): Boolean = x == y + override def neqv(x: Boolean, y: Boolean): Boolean = x != y override def gt(x: Boolean, y: Boolean): Boolean = x && !y override def lt(x: Boolean, y: Boolean): Boolean = !x && y override def gteqv(x: Boolean, y: Boolean): Boolean = x == y || x diff --git a/kernel/src/main/scala/cats/kernel/instances/char.scala b/kernel/src/main/scala/cats/kernel/instances/char.scala index be0a77949c6..5756535c129 100644 --- a/kernel/src/main/scala/cats/kernel/instances/char.scala +++ b/kernel/src/main/scala/cats/kernel/instances/char.scala @@ -11,8 +11,8 @@ class CharOrder extends Order[Char] with Hash[Char] { def hash(x: Char): Int = x.hashCode() def compare(x: Char, y: Char): Int = if (x < y) -1 else if (x > y) 1 else 0 - override def eqv(x:Char, y:Char): Boolean = x == y - override def neqv(x:Char, y:Char): Boolean = x != y + override def eqv(x: Char, y: Char): Boolean = x == y + override def neqv(x: Char, y: Char): Boolean = x != y override def gt(x: Char, y: Char): Boolean = x > y override def gteqv(x: Char, y: Char): Boolean = x >= y override def lt(x: Char, y: Char): Boolean = x < y diff --git a/kernel/src/main/scala/cats/kernel/instances/double.scala b/kernel/src/main/scala/cats/kernel/instances/double.scala index e9f8c203ec5..3c77440be20 100644 --- a/kernel/src/main/scala/cats/kernel/instances/double.scala +++ b/kernel/src/main/scala/cats/kernel/instances/double.scala @@ -21,8 +21,8 @@ class DoubleOrder extends Order[Double] with Hash[Double] { def compare(x: Double, y: Double): Int = java.lang.Double.compare(x, y) - override def eqv(x:Double, y:Double): Boolean = x == y - override def neqv(x:Double, y:Double): Boolean = x != y + override def eqv(x: Double, y: Double): Boolean = x == y + override def neqv(x: Double, y: Double): Boolean = x != y override def gt(x: Double, y: Double): Boolean = x > y override def gteqv(x: Double, y: Double): Boolean = x >= y override def lt(x: Double, y: Double): Boolean = x < y diff --git a/kernel/src/main/scala/cats/kernel/instances/duration.scala b/kernel/src/main/scala/cats/kernel/instances/duration.scala index 406ed025e77..2a784474e3a 100644 --- a/kernel/src/main/scala/cats/kernel/instances/duration.scala +++ b/kernel/src/main/scala/cats/kernel/instances/duration.scala @@ -13,15 +13,15 @@ trait DurationInstances { // Duration.Undefined, Duration.Inf, Duration.MinusInf /** - * This ordering is valid for all defined durations. - * - * The value Duration.Undefined breaks our laws, because undefined - * values are not equal to themselves. - */ + * This ordering is valid for all defined durations. + * + * The value Duration.Undefined breaks our laws, because undefined + * values are not equal to themselves. + */ class DurationOrder extends Order[Duration] with Hash[Duration] { def hash(x: Duration): Int = x.hashCode() - def compare(x: Duration, y: Duration): Int = x compare y + def compare(x: Duration, y: Duration): Int = x.compare(y) override def eqv(x: Duration, y: Duration): Boolean = x == y override def neqv(x: Duration, y: Duration): Boolean = x != y @@ -30,17 +30,17 @@ class DurationOrder extends Order[Duration] with Hash[Duration] { override def lt(x: Duration, y: Duration): Boolean = x < y override def lteqv(x: Duration, y: Duration): Boolean = x <= y - override def min(x: Duration, y: Duration): Duration = x min y - override def max(x: Duration, y: Duration): Duration = x max y + override def min(x: Duration, y: Duration): Duration = x.min(y) + override def max(x: Duration, y: Duration): Duration = x.max(y) } /** - * This group models addition, but has a few problematic edge cases. - * - * 1. finite values can overflow, throwing an exception - * 2. inf + (-inf) = undefined, not zero - * 3. undefined + zero = undefined - */ + * This group models addition, but has a few problematic edge cases. + * + * 1. finite values can overflow, throwing an exception + * 2. inf + (-inf) = undefined, not zero + * 3. undefined + zero = undefined + */ class DurationGroup extends CommutativeGroup[Duration] { def empty: Duration = Duration.Zero def inverse(x: Duration): Duration = -x diff --git a/kernel/src/main/scala/cats/kernel/instances/either.scala b/kernel/src/main/scala/cats/kernel/instances/either.scala index bf71f233894..d063ad60474 100644 --- a/kernel/src/main/scala/cats/kernel/instances/either.scala +++ b/kernel/src/main/scala/cats/kernel/instances/either.scala @@ -9,14 +9,16 @@ trait EitherInstances extends EitherInstances0 { new Order[Either[A, B]] { def compare(x: Either[A, B], y: Either[A, B]): Int = x match { - case Left(xx) => y match { - case Left(yy) => A.compare(xx, yy) - case Right(_) => -1 - } - case Right(xx) => y match { - case Left(_) => 1 - case Right(yy) => B.compare(xx, yy) - } + case Left(xx) => + y match { + case Left(yy) => A.compare(xx, yy) + case Right(_) => -1 + } + case Right(xx) => + y match { + case Left(_) => 1 + case Right(yy) => B.compare(xx, yy) + } } } @@ -27,10 +29,11 @@ trait EitherInstances extends EitherInstances0 { def combine(x: Either[A, B], y: Either[A, B]): Either[A, B] = x match { case left @ Left(_) => left - case Right(xx) => y match { - case left @ Left(_) => left - case Right(yy) => Right(B.combine(xx, yy)) - } + case Right(xx) => + y match { + case left @ Left(_) => left + case Right(yy) => Right(B.combine(xx, yy)) + } } } } @@ -42,25 +45,29 @@ trait EitherInstances0 extends EitherInstances1 { def combine(x: Either[A, B], y: Either[A, B]): Either[A, B] = x match { case left @ Left(_) => left - case Right(xx) => y match { - case left @ Left(_) => left - case Right(yy) => Right(B.combine(xx, yy)) - } + case Right(xx) => + y match { + case left @ Left(_) => left + case Right(yy) => Right(B.combine(xx, yy)) + } } } - implicit def catsStdPartialOrderForEither[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 match { - case Left(xx) => y match { - case Left(yy) => A.partialCompare(xx, yy) - case Right(_) => -1.0 - } - case Right(xx) => y match { - case Left(_) => 1.0 - case Right(yy) => B.partialCompare(xx, yy) - } + case Left(xx) => + y match { + case Left(yy) => A.partialCompare(xx, yy) + case Right(_) => -1.0 + } + case Right(xx) => + y match { + case Left(_) => 1.0 + case Right(yy) => B.partialCompare(xx, yy) + } } } @@ -73,27 +80,27 @@ trait EitherInstances1 { } - // isolated class for inheritance class EitherEq[A, B](implicit A: Eq[A], B: Eq[B]) extends Eq[Either[A, B]] { def eqv(x: Either[A, B], y: Either[A, B]): Boolean = x match { - case Left(xx) => y match { - case Left(yy) => A.eqv(xx, yy) - case Right(_) => false - } - case Right(xx) => y match { - case Left(_) => false - case Right(yy) => B.eqv(xx, yy) - } + case Left(xx) => + y match { + case Left(yy) => A.eqv(xx, yy) + case Right(_) => false + } + case Right(xx) => + y match { + case Left(_) => false + case Right(yy) => B.eqv(xx, yy) + } } } class EitherHash[A, B](implicit A: Hash[A], B: Hash[B]) extends EitherEq[A, B] with Hash[Either[A, B]] { - def hash(x: Either[A, B]): Int = { + def hash(x: Either[A, B]): Int = x match { - case Left(xx) => StaticMethods.product1Hash(A.hash(xx)) + case Left(xx) => StaticMethods.product1Hash(A.hash(xx)) case Right(xx) => StaticMethods.product1Hash(B.hash(xx)) } - } } diff --git a/kernel/src/main/scala/cats/kernel/instances/finiteDuration.scala b/kernel/src/main/scala/cats/kernel/instances/finiteDuration.scala index 3efa92d2835..c4a7e0682f7 100644 --- a/kernel/src/main/scala/cats/kernel/instances/finiteDuration.scala +++ b/kernel/src/main/scala/cats/kernel/instances/finiteDuration.scala @@ -1,17 +1,17 @@ package cats.kernel package instances -import scala.concurrent.duration.{ Duration, FiniteDuration } - +import scala.concurrent.duration.{Duration, FiniteDuration} trait FiniteDurationInstances { - implicit val catsKernelStdOrderForFiniteDuration: Order[FiniteDuration] with Hash[FiniteDuration] = new FiniteDurationOrder + implicit val catsKernelStdOrderForFiniteDuration: Order[FiniteDuration] with Hash[FiniteDuration] = + new FiniteDurationOrder implicit val catsKernelStdGroupForFiniteDuration: CommutativeGroup[FiniteDuration] = new FiniteDurationGroup } class FiniteDurationOrder extends Order[FiniteDuration] with Hash[FiniteDuration] { def hash(x: FiniteDuration): Int = x.hashCode() - def compare(x: FiniteDuration, y: FiniteDuration): Int = x compare y + def compare(x: FiniteDuration, y: FiniteDuration): Int = x.compare(y) override def eqv(x: FiniteDuration, y: FiniteDuration): Boolean = x == y override def neqv(x: FiniteDuration, y: FiniteDuration): Boolean = x != y @@ -20,8 +20,8 @@ class FiniteDurationOrder extends Order[FiniteDuration] with Hash[FiniteDuration override def lt(x: FiniteDuration, y: FiniteDuration): Boolean = x < y override def lteqv(x: FiniteDuration, y: FiniteDuration): Boolean = x <= y - override def min(x: FiniteDuration, y: FiniteDuration): FiniteDuration = x min y - override def max(x: FiniteDuration, y: FiniteDuration): FiniteDuration = x max y + override def min(x: FiniteDuration, y: FiniteDuration): FiniteDuration = x.min(y) + override def max(x: FiniteDuration, y: FiniteDuration): FiniteDuration = x.max(y) } class FiniteDurationGroup extends CommutativeGroup[FiniteDuration] { diff --git a/kernel/src/main/scala/cats/kernel/instances/float.scala b/kernel/src/main/scala/cats/kernel/instances/float.scala index d6b9a07e398..f2486de87de 100644 --- a/kernel/src/main/scala/cats/kernel/instances/float.scala +++ b/kernel/src/main/scala/cats/kernel/instances/float.scala @@ -9,8 +9,8 @@ trait FloatInstances { } /** - * This is only approximately associative. - */ + * This is only approximately associative. + */ class FloatGroup extends CommutativeGroup[Float] { def combine(x: Float, y: Float): Float = x + y def empty: Float = 0F @@ -19,13 +19,13 @@ class FloatGroup extends CommutativeGroup[Float] { } /** - * Due to the way floating-point equality works, this instance is not - * lawful under equality, but is correct when taken as an - * approximation of an exact value. - * - * If you would prefer an absolutely lawful fractional value, you'll - * need to investigate rational numbers or more exotic types. - */ + * Due to the way floating-point equality works, this instance is not + * lawful under equality, but is correct when taken as an + * approximation of an exact value. + * + * If you would prefer an absolutely lawful fractional value, you'll + * need to investigate rational numbers or more exotic types. + */ class FloatOrder extends Order[Float] with Hash[Float] { def hash(x: Float): Int = x.hashCode() @@ -33,8 +33,8 @@ class FloatOrder extends Order[Float] with Hash[Float] { def compare(x: Float, y: Float): Int = java.lang.Float.compare(x, y) - override def eqv(x:Float, y:Float): Boolean = x == y - override def neqv(x:Float, y:Float): Boolean = x != y + override def eqv(x: Float, y: Float): Boolean = x == y + override def neqv(x: Float, y: Float): Boolean = x != y override def gt(x: Float, y: Float): Boolean = x > y override def gteqv(x: Float, y: Float): Boolean = x >= y override def lt(x: Float, y: Float): Boolean = x < y diff --git a/kernel/src/main/scala/cats/kernel/instances/function.scala b/kernel/src/main/scala/cats/kernel/instances/function.scala index 4ff4f1476e2..a0846825f85 100644 --- a/kernel/src/main/scala/cats/kernel/instances/function.scala +++ b/kernel/src/main/scala/cats/kernel/instances/function.scala @@ -36,10 +36,14 @@ trait FunctionInstances0 extends FunctionInstances1 { implicit def catsKernelGroupForFunction1[A, B](implicit G: Group[B]): Group[A => B] = new Function1Group[A, B] { def B: Group[B] = G } - implicit def catsKernelBoundedSemilatticeForFunction0[A](implicit G: BoundedSemilattice[A]): BoundedSemilattice[() => A] = + implicit def catsKernelBoundedSemilatticeForFunction0[A]( + implicit G: BoundedSemilattice[A] + ): BoundedSemilattice[() => A] = new Function0Monoid[A] with BoundedSemilattice[() => A] { def A: Monoid[A] = G } - implicit def catsKernelBoundedSemilatticeForFunction1[A, B](implicit G: BoundedSemilattice[B]): BoundedSemilattice[A => B] = + implicit def catsKernelBoundedSemilatticeForFunction1[A, B]( + implicit G: BoundedSemilattice[B] + ): BoundedSemilattice[A => B] = new Function1Monoid[A, B] with BoundedSemilattice[A => B] { def B: Monoid[B] = G } } @@ -50,10 +54,14 @@ trait FunctionInstances1 extends FunctionInstances2 { def eqv(x: () => A, y: () => A): Boolean = ev.eqv(x(), y()) } - implicit def catsKernelCommutativeMonoidForFunction0[A](implicit M: CommutativeMonoid[A]): CommutativeMonoid[() => A] = + implicit def catsKernelCommutativeMonoidForFunction0[A]( + implicit M: CommutativeMonoid[A] + ): CommutativeMonoid[() => A] = new Function0Monoid[A] with CommutativeMonoid[() => A] { def A: Monoid[A] = M } - implicit def catsKernelCommutativeMonoidForFunction1[A, B](implicit M: CommutativeMonoid[B]): CommutativeMonoid[A => B] = + implicit def catsKernelCommutativeMonoidForFunction1[A, B]( + implicit M: CommutativeMonoid[B] + ): CommutativeMonoid[A => B] = new Function1Monoid[A, B] with CommutativeMonoid[A => B] { def B: Monoid[B] = M } implicit def catsKernelSemilatticeForFunction0[A](implicit M: Semilattice[A]): Semilattice[() => A] = @@ -80,10 +88,14 @@ trait FunctionInstances2 extends FunctionInstances3 { trait FunctionInstances3 extends FunctionInstances4 { - implicit def catsKernelCommutativeSemigroupForFunction0[A](implicit S: CommutativeSemigroup[A]): CommutativeSemigroup[() => A] = + implicit def catsKernelCommutativeSemigroupForFunction0[A]( + implicit S: CommutativeSemigroup[A] + ): CommutativeSemigroup[() => A] = new Function0Semigroup[A] with CommutativeSemigroup[() => A] { def A: Semigroup[A] = S } - implicit def catsKernelCommutativeSemigroupForFunction1[A, B](implicit S: CommutativeSemigroup[B]): CommutativeSemigroup[A => B] = + implicit def catsKernelCommutativeSemigroupForFunction1[A, B]( + implicit S: CommutativeSemigroup[B] + ): CommutativeSemigroup[A => B] = new Function1Semigroup[A, B] with CommutativeSemigroup[A => B] { def B: Semigroup[B] = S } } diff --git a/kernel/src/main/scala/cats/kernel/instances/map.scala b/kernel/src/main/scala/cats/kernel/instances/map.scala index 1831ffb9913..ef50b20145d 100644 --- a/kernel/src/main/scala/cats/kernel/instances/map.scala +++ b/kernel/src/main/scala/cats/kernel/instances/map.scala @@ -27,13 +27,14 @@ class MapHash[K, V](implicit V: Hash[V]) extends MapEq[K, V]()(V) with Hash[Map[ def hash(x: Map[K, V]): Int = { var a, b, n = 0 var c = 1 - x foreach { case (k, v) => - // use the default hash on keys because that's what Scala's Map does - val h = StaticMethods.product2Hash(k.hashCode(), V.hash(v)) - a += h - b ^= h - if (h != 0) c *= h - n += 1 + x.foreach { + case (k, v) => + // use the default hash on keys because that's what Scala's Map does + val h = StaticMethods.product2Hash(k.hashCode(), V.hash(v)) + a += h + b ^= h + if (h != 0) c *= h + n += 1 } var h = mapSeed h = mix(h, a) @@ -46,26 +47,30 @@ class MapHash[K, V](implicit V: Hash[V]) extends MapEq[K, V]()(V) with Hash[Map[ class MapEq[K, V](implicit V: Eq[V]) extends Eq[Map[K, V]] { def eqv(x: Map[K, V], y: Map[K, V]): Boolean = if (x eq y) true - else x.size == y.size && x.forall { case (k, v1) => - y.get(k) match { - case Some(v2) => V.eqv(v1, v2) - case None => false + else + x.size == y.size && x.forall { + case (k, v1) => + y.get(k) match { + case Some(v2) => V.eqv(v1, v2) + case None => false + } } - } } -class MapMonoid[K, V](implicit V: Semigroup[V]) extends Monoid[Map[K, V]] { +class MapMonoid[K, V](implicit V: Semigroup[V]) extends Monoid[Map[K, V]] { def empty: Map[K, V] = Map.empty def combine(xs: Map[K, V], ys: Map[K, V]): Map[K, V] = if (xs.size <= ys.size) { - xs.foldLeft(ys) { case (my, (k, x)) => - my.updated(k, Semigroup.maybeCombine(x, my.get(k))) + xs.foldLeft(ys) { + case (my, (k, x)) => + my.updated(k, Semigroup.maybeCombine(x, my.get(k))) } } else { - ys.foldLeft(xs) { case (mx, (k, y)) => - mx.updated(k, Semigroup.maybeCombine(mx.get(k), y)) + ys.foldLeft(xs) { + case (mx, (k, y)) => + mx.updated(k, Semigroup.maybeCombine(mx.get(k), y)) } } diff --git a/kernel/src/main/scala/cats/kernel/instances/option.scala b/kernel/src/main/scala/cats/kernel/instances/option.scala index ab324dabd8d..1d5f0519269 100644 --- a/kernel/src/main/scala/cats/kernel/instances/option.scala +++ b/kernel/src/main/scala/cats/kernel/instances/option.scala @@ -32,7 +32,7 @@ class OptionOrder[A](implicit A: Order[A]) extends Order[Option[A]] { if (y.isEmpty) 0 else -1 case Some(a) => y match { - case None => 1 + case None => 1 case Some(b) => A.compare(a, b) } } @@ -45,7 +45,7 @@ class OptionPartialOrder[A](implicit A: PartialOrder[A]) extends PartialOrder[Op if (y.isEmpty) 0.0 else -1.0 case Some(a) => y match { - case None => 1.0 + case None => 1.0 case Some(b) => A.partialCompare(a, b) } } @@ -53,7 +53,7 @@ class OptionPartialOrder[A](implicit A: PartialOrder[A]) extends PartialOrder[Op class OptionHash[A](implicit A: Hash[A]) extends OptionEq[A]()(A) with Hash[Option[A]] { def hash(x: Option[A]): Int = x match { - case None => None.hashCode() + case None => None.hashCode() case Some(xx) => StaticMethods.product1Hash(A.hash(xx)) } } @@ -64,7 +64,7 @@ class OptionEq[A](implicit A: Eq[A]) extends Eq[Option[A]] { case None => y.isEmpty case Some(a) => y match { - case None => false + case None => false case Some(b) => A.eqv(a, b) } } @@ -77,7 +77,7 @@ class OptionMonoid[A](implicit A: Semigroup[A]) extends Monoid[Option[A]] { case None => y case Some(a) => y match { - case None => x + case None => x case Some(b) => Some(A.combine(a, b)) } } diff --git a/kernel/src/main/scala/cats/kernel/instances/string.scala b/kernel/src/main/scala/cats/kernel/instances/string.scala index 14faf231e86..1e24ed3bc3d 100644 --- a/kernel/src/main/scala/cats/kernel/instances/string.scala +++ b/kernel/src/main/scala/cats/kernel/instances/string.scala @@ -15,7 +15,7 @@ class StringOrder extends Order[String] with Hash[String] { override def eqv(x: String, y: String): Boolean = x == y def compare(x: String, y: String): Int = - if (x eq y) 0 else x compareTo y + if (x eq y) 0 else x.compareTo(y) } class StringMonoid extends Monoid[String] { diff --git a/kernel/src/main/scala/cats/kernel/instances/symbol.scala b/kernel/src/main/scala/cats/kernel/instances/symbol.scala index 0b89e4fff25..fef07e9f6d0 100644 --- a/kernel/src/main/scala/cats/kernel/instances/symbol.scala +++ b/kernel/src/main/scala/cats/kernel/instances/symbol.scala @@ -11,11 +11,10 @@ class SymbolOrder extends Order[Symbol] with Hash[Symbol] { def hash(x: Symbol): Int = x.hashCode() - override def eqv(x: Symbol, y: Symbol): Boolean = { + override def eqv(x: Symbol, y: Symbol): Boolean = // Symbols are interned x eq y - } def compare(x: Symbol, y: Symbol): Int = - if (x eq y) 0 else x.name compareTo y.name + if (x eq y) 0 else x.name.compareTo(y.name) } diff --git a/kernel/src/main/scala/cats/kernel/instances/uuid.scala b/kernel/src/main/scala/cats/kernel/instances/uuid.scala index 1ef98c68372..95da72ea425 100644 --- a/kernel/src/main/scala/cats/kernel/instances/uuid.scala +++ b/kernel/src/main/scala/cats/kernel/instances/uuid.scala @@ -7,7 +7,7 @@ package object uuid extends UUIDInstances trait UUIDInstances { implicit val catsKernelStdOrderForUUID: Order[UUID] with Hash[UUID] = new Order[UUID] with Hash[UUID] { - def compare(x: UUID, y: UUID): Int = x compareTo y + def compare(x: UUID, y: UUID): Int = x.compareTo(y) def hash(x: UUID): Int = x.hashCode() } } diff --git a/laws/src/main/scala/cats/laws/AlternativeLaws.scala b/laws/src/main/scala/cats/laws/AlternativeLaws.scala index e8bb2f83b30..bb75483bcd7 100644 --- a/laws/src/main/scala/cats/laws/AlternativeLaws.scala +++ b/laws/src/main/scala/cats/laws/AlternativeLaws.scala @@ -8,13 +8,13 @@ trait AlternativeLaws[F[_]] extends ApplicativeLaws[F] with MonoidKLaws[F] { implicit def algebra[A]: Monoid[F[A]] = F.algebra[A] def alternativeRightAbsorption[A, B](ff: F[A => B]): IsEq[F[B]] = - (ff ap F.empty[A]) <-> F.empty[B] + (ff.ap(F.empty[A])) <-> F.empty[B] def alternativeLeftDistributivity[A, B](fa: F[A], fa2: F[A], f: A => B): IsEq[F[B]] = - ((fa |+| fa2) map f) <-> ((fa map f) |+| (fa2 map f)) + ((fa |+| fa2).map(f)) <-> ((fa.map(f)) |+| (fa2.map(f))) def alternativeRightDistributivity[A, B](fa: F[A], ff: F[A => B], fg: F[A => B]): IsEq[F[B]] = - ((ff |+| fg) ap fa) <-> ((ff ap fa) |+| (fg ap fa)) + ((ff |+| fg).ap(fa)) <-> ((ff.ap(fa)) |+| (fg.ap(fa))) } diff --git a/laws/src/main/scala/cats/laws/ApplicativeErrorLaws.scala b/laws/src/main/scala/cats/laws/ApplicativeErrorLaws.scala index 44b7afc7203..ddc66a6d27a 100644 --- a/laws/src/main/scala/cats/laws/ApplicativeErrorLaws.scala +++ b/laws/src/main/scala/cats/laws/ApplicativeErrorLaws.scala @@ -32,7 +32,7 @@ trait ApplicativeErrorLaws[F[_], E] extends ApplicativeLaws[F] { F.handleError(fa)(f) <-> F.recover(fa) { case x => f(x) } def recoverConsistentWithRecoverWith[A](fa: F[A], pf: PartialFunction[E, A]): IsEq[F[A]] = - F.recover(fa)(pf) <-> F.recoverWith(fa)(pf andThen F.pure) + F.recover(fa)(pf) <-> F.recoverWith(fa)(pf.andThen(F.pure)) def attemptConsistentWithAttemptT[A](fa: F[A]): IsEq[EitherT[F, E, A]] = EitherT(F.attempt(fa)) <-> F.attemptT(fa) @@ -44,7 +44,7 @@ trait ApplicativeErrorLaws[F[_], E] extends ApplicativeLaws[F] { F.onError(F.pure(a)) { case x => f(x) } <-> F.pure(a) def onErrorRaise[A](fa: F[A], e: E, fb: F[Unit]): IsEq[F[A]] = - F.onError(F.raiseError[A](e)){case err => fb} <-> F.map2(fb, F.raiseError[A](e))((_, b) => b) + F.onError(F.raiseError[A](e)) { case err => fb } <-> F.map2(fb, F.raiseError[A](e))((_, b) => b) } object ApplicativeErrorLaws { diff --git a/laws/src/main/scala/cats/laws/ApplicativeLaws.scala b/laws/src/main/scala/cats/laws/ApplicativeLaws.scala index a1405f09a08..d059de65bc7 100644 --- a/laws/src/main/scala/cats/laws/ApplicativeLaws.scala +++ b/laws/src/main/scala/cats/laws/ApplicativeLaws.scala @@ -5,8 +5,8 @@ import cats.syntax.apply._ import cats.syntax.functor._ /** - * Laws that must be obeyed by any `Applicative`. - */ + * Laws that must be obeyed by any `Applicative`. + */ trait ApplicativeLaws[F[_]] extends ApplyLaws[F] { implicit override def F: Applicative[F] @@ -23,10 +23,10 @@ trait ApplicativeLaws[F[_]] extends ApplyLaws[F] { fa.map(f) <-> F.pure(f).ap(fa) /** - * This law is [[applyComposition]] stated in terms of `pure`. It is a - * combination of [[applyComposition]] and [[applicativeMap]] and hence not - * strictly necessary. - */ + * This law is [[applyComposition]] stated in terms of `pure`. It is a + * combination of [[applyComposition]] and [[applicativeMap]] and hence not + * strictly necessary. + */ def applicativeComposition[A, B, C](fa: F[A], fab: F[A => B], fbc: F[B => C]): IsEq[F[C]] = { val compose: (B => C) => (A => B) => (A => C) = _.compose F.pure(compose).ap(fbc).ap(fab).ap(fa) <-> fbc.ap(fab.ap(fa)) diff --git a/laws/src/main/scala/cats/laws/ApplyLaws.scala b/laws/src/main/scala/cats/laws/ApplyLaws.scala index 0d96699131c..c52221abc72 100644 --- a/laws/src/main/scala/cats/laws/ApplyLaws.scala +++ b/laws/src/main/scala/cats/laws/ApplyLaws.scala @@ -5,8 +5,8 @@ import cats.syntax.apply._ import cats.syntax.functor._ /** - * Laws that must be obeyed by any `Apply`. - */ + * Laws that must be obeyed by any `Apply`. + */ trait ApplyLaws[F[_]] extends FunctorLaws[F] with SemigroupalLaws[F] { implicit override def F: Apply[F] diff --git a/laws/src/main/scala/cats/laws/ArrowChoiceLaws.scala b/laws/src/main/scala/cats/laws/ArrowChoiceLaws.scala index b6b2546e825..1605c2afa07 100644 --- a/laws/src/main/scala/cats/laws/ArrowChoiceLaws.scala +++ b/laws/src/main/scala/cats/laws/ArrowChoiceLaws.scala @@ -7,17 +7,17 @@ import cats.syntax.compose._ import cats.syntax.profunctor._ /** - * Laws that must be obeyed by any `cats.arrow.ArrowChoice`. - */ + * Laws that must be obeyed by any `cats.arrow.ArrowChoice`. + */ trait ArrowChoiceLaws[F[_, _]] extends ArrowLaws[F] with ChoiceLaws[F] { implicit override def F: ArrowChoice[F] implicit def Function: ArrowChoice[Function1] def sumAssoc[A, B, C](e: Either[Either[A, B], C]): Either[A, Either[B, C]] = e match { - case Left(Left(x)) => Left(x) + case Left(Left(x)) => Left(x) case Left(Right(y)) => Right(Left(y)) - case Right(z) => Right(Right(z)) + case Right(z) => Right(Right(z)) } def leftLiftCommute[A, B, C](f: A => B): IsEq[F[Either[A, C], Either[B, C]]] = @@ -36,7 +36,9 @@ trait ArrowChoiceLaws[F[_, _]] extends ArrowLaws[F] with ChoiceLaws[F] { def leftAndThenRightIdentityCommutes[A, B, C, D](f: F[A, B], g: C => D): IsEq[F[Either[A, C], Either[B, D]]] = (F.left(f) >>> F.lift(identity[B] _ +++ g)) <-> (F.lift(identity[A] _ +++ g) >>> F.left(f)) - def leftTwiceCommutesWithSumAssociation[A, B, C, D](f: F[A, D]): IsEq[F[Either[Either[A, B], C], Either[D, Either[B, C]]]] = + def leftTwiceCommutesWithSumAssociation[A, B, C, D]( + f: F[A, D] + ): IsEq[F[Either[Either[A, B], C], Either[D, Either[B, C]]]] = (F.left(F.left[A, D, B](f)) >>> F.lift(sumAssoc[D, B, C])) <-> (F.lift(sumAssoc[A, B, C]) >>> F.left(f)) } diff --git a/laws/src/main/scala/cats/laws/ArrowLaws.scala b/laws/src/main/scala/cats/laws/ArrowLaws.scala index e2ea3ed4c66..df8865334e0 100644 --- a/laws/src/main/scala/cats/laws/ArrowLaws.scala +++ b/laws/src/main/scala/cats/laws/ArrowLaws.scala @@ -8,8 +8,8 @@ import cats.syntax.compose._ import cats.syntax.strong._ /** - * Laws that must be obeyed by any `cats.arrow.Arrow`. - */ + * Laws that must be obeyed by any `cats.arrow.Arrow`. + */ trait ArrowLaws[F[_, _]] extends CategoryLaws[F] with StrongLaws[F] { implicit override def F: Arrow[F] @@ -17,28 +17,28 @@ trait ArrowLaws[F[_, _]] extends CategoryLaws[F] with StrongLaws[F] { F.lift(identity[A]) <-> F.id[A] def arrowComposition[A, B, C](f: A => B, g: B => C): IsEq[F[A, C]] = - F.lift(f andThen g) <-> (F.lift(f) andThen F.lift(g)) + F.lift(f.andThen(g)) <-> (F.lift(f).andThen(F.lift(g))) def arrowExtension[A, B, C](g: A => B): IsEq[F[(A, C), (B, C)]] = - F.lift(g).first[C] <-> F.lift(g split identity[C]) + F.lift(g).first[C] <-> F.lift(g.split(identity[C])) def arrowFunctor[A, B, C, D](f: F[A, B], g: F[B, C]): IsEq[F[(A, D), (C, D)]] = - (f andThen g).first[D] <-> (f.first[D] andThen g.first[D]) + f.andThen(g).first[D] <-> (f.first[D].andThen(g.first[D])) def arrowExchange[A, B, C, D](f: F[A, B], g: C => D): IsEq[F[(A, C), (B, D)]] = - (f.first[C] andThen F.lift(identity[B] _ split g)) <-> (F.lift(identity[A] _ split g) andThen f.first[D]) + (f.first[C].andThen(F.lift((identity[B] _).split(g)))) <-> (F.lift((identity[A] _).split(g)).andThen(f.first[D])) def arrowUnit[A, B, C](f: F[A, B]): IsEq[F[(A, C), B]] = - (f.first[C] andThen F.lift(fst[B, C])) <-> (F.lift(fst[A, C]) andThen f) + (f.first[C].andThen(F.lift(fst[B, C]))) <-> (F.lift(fst[A, C]).andThen(f)) def arrowAssociation[A, B, C, D](f: F[A, B]): IsEq[F[((A, C), D), (B, (C, D))]] = - (f.first[C].first[D] andThen F.lift(assoc[B, C, D])) <-> (F.lift(assoc[A, C, D]) andThen f.first[(C, D)]) + (f.first[C].first[D].andThen(F.lift(assoc[B, C, D]))) <-> (F.lift(assoc[A, C, D]).andThen(f.first[(C, D)])) def splitConsistentWithAndThen[A, B, C, D](f: F[A, B], g: F[C, D]): IsEq[F[(A, C), (B, D)]] = - F.split(f, g) <-> (f.first andThen g.second) + F.split(f, g) <-> (f.first.andThen(g.second)) def mergeConsistentWithAndThen[A, B, C](f: F[A, B], g: F[A, C]): IsEq[F[A, (B, C)]] = - F.merge(f, g) <-> ((F.lift((x: A) => (x, x))) andThen F.split(f, g)) + F.merge(f, g) <-> ((F.lift((x: A) => (x, x))).andThen(F.split(f, g))) private def fst[A, B](p: (A, B)): A = p._1 diff --git a/laws/src/main/scala/cats/laws/BifoldableLaws.scala b/laws/src/main/scala/cats/laws/BifoldableLaws.scala index 783eefa7c06..d82c490bdf9 100644 --- a/laws/src/main/scala/cats/laws/BifoldableLaws.scala +++ b/laws/src/main/scala/cats/laws/BifoldableLaws.scala @@ -12,7 +12,9 @@ trait BifoldableLaws[F[_, _]] { expected <-> F.bifoldMap(fab)(f, g) } - def bifoldRightConsistentWithBifoldMap[A, B, C](fab: F[A, B], f: A => C, g: B => C)(implicit C: Monoid[C]): IsEq[C] = { + def bifoldRightConsistentWithBifoldMap[A, B, C](fab: F[A, B], f: A => C, g: B => C)( + implicit C: Monoid[C] + ): IsEq[C] = { val expected = F.bifoldRight(fab, Later(C.empty))( (a: A, ec: Eval[C]) => ec.map(c => C.combine(f(a), c)), (b: B, ec: Eval[C]) => ec.map(c => C.combine(g(b), c)) diff --git a/laws/src/main/scala/cats/laws/BifunctorLaws.scala b/laws/src/main/scala/cats/laws/BifunctorLaws.scala index f356d39d4c1..e8c26b7da80 100644 --- a/laws/src/main/scala/cats/laws/BifunctorLaws.scala +++ b/laws/src/main/scala/cats/laws/BifunctorLaws.scala @@ -4,24 +4,22 @@ import cats.Bifunctor import cats.syntax.bifunctor._ /** - * Laws that must be obeyed by any `Bifunctor`. - */ + * Laws that must be obeyed by any `Bifunctor`. + */ trait BifunctorLaws[F[_, _]] { implicit def F: Bifunctor[F] def bifunctorIdentity[A, B](fa: F[A, B]): IsEq[F[A, B]] = fa.bimap(identity, identity) <-> fa - def bifunctorComposition[A, B, C, X, Y, Z](fa: F[A, X], f: A => B, f2: B => C, g: X => Y, g2: Y => Z): IsEq[F[C, Z]] = { - fa.bimap(f, g).bimap(f2, g2) <-> fa.bimap(f andThen f2, g andThen g2) - } + def bifunctorComposition[A, B, C, X, Y, Z](fa: F[A, X], f: A => B, f2: B => C, g: X => Y, g2: Y => Z): IsEq[F[C, Z]] = + fa.bimap(f, g).bimap(f2, g2) <-> fa.bimap(f.andThen(f2), g.andThen(g2)) def bifunctorLeftMapIdentity[A, B](fa: F[A, B]): IsEq[F[A, B]] = fa.leftMap(identity) <-> fa - def bifunctorLeftMapComposition[A, B, C, D](fa: F[A, B], f: A => C, g: C => D): IsEq[F[D, B]] = { - fa.leftMap(f).leftMap(g) <-> fa.leftMap(f andThen g) - } + def bifunctorLeftMapComposition[A, B, C, D](fa: F[A, B], f: A => C, g: C => D): IsEq[F[D, B]] = + fa.leftMap(f).leftMap(g) <-> fa.leftMap(f.andThen(g)) } diff --git a/laws/src/main/scala/cats/laws/BimonadLaws.scala b/laws/src/main/scala/cats/laws/BimonadLaws.scala index 244d51361c8..17a6307e52c 100644 --- a/laws/src/main/scala/cats/laws/BimonadLaws.scala +++ b/laws/src/main/scala/cats/laws/BimonadLaws.scala @@ -2,11 +2,11 @@ package cats package laws /** - * Laws that must be obeyed by any `Bimonad`. - * - * For more information, see definition 4.1 from this paper: - * http://arxiv.org/pdf/0710.1163v3.pdf - */ + * Laws that must be obeyed by any `Bimonad`. + * + * For more information, see definition 4.1 from this paper: + * http://arxiv.org/pdf/0710.1163v3.pdf + */ trait BimonadLaws[F[_]] extends MonadLaws[F] with ComonadLaws[F] { implicit override def F: Bimonad[F] diff --git a/laws/src/main/scala/cats/laws/BitraverseLaws.scala b/laws/src/main/scala/cats/laws/BitraverseLaws.scala index d22172d4f3c..a2e08bbc177 100644 --- a/laws/src/main/scala/cats/laws/BitraverseLaws.scala +++ b/laws/src/main/scala/cats/laws/BitraverseLaws.scala @@ -16,8 +16,7 @@ trait BitraverseLaws[F[_, _]] extends BifoldableLaws[F] with BifunctorLaws[F] { h: C => G[E], i: D => G[H] )(implicit - G: Applicative[G] - ): IsEq[G[G[F[E, H]]]] = { + G: Applicative[G]): IsEq[G[G[F[E, H]]]] = { val fg = F.bitraverse(fab)(f, g) val hi = G.map(fg)(f => F.bitraverse(f)(h, i)) diff --git a/laws/src/main/scala/cats/laws/CategoryLaws.scala b/laws/src/main/scala/cats/laws/CategoryLaws.scala index 85d85a738ce..d4bae3bc9ae 100644 --- a/laws/src/main/scala/cats/laws/CategoryLaws.scala +++ b/laws/src/main/scala/cats/laws/CategoryLaws.scala @@ -5,16 +5,16 @@ import cats.arrow.Category import cats.syntax.compose._ /** - * Laws that must be obeyed by any `cats.arrow.Category`. - */ + * Laws that must be obeyed by any `cats.arrow.Category`. + */ trait CategoryLaws[F[_, _]] extends ComposeLaws[F] { implicit override def F: Category[F] def categoryLeftIdentity[A, B](f: F[A, B]): IsEq[F[A, B]] = - (F.id[A] andThen f) <-> f + (F.id[A].andThen(f)) <-> f def categoryRightIdentity[A, B](f: F[A, B]): IsEq[F[A, B]] = - (f andThen F.id[B]) <-> f + (f.andThen(F.id[B])) <-> f } object CategoryLaws { diff --git a/laws/src/main/scala/cats/laws/ChoiceLaws.scala b/laws/src/main/scala/cats/laws/ChoiceLaws.scala index 3f083625d56..dd856d0c594 100644 --- a/laws/src/main/scala/cats/laws/ChoiceLaws.scala +++ b/laws/src/main/scala/cats/laws/ChoiceLaws.scala @@ -6,8 +6,8 @@ import cats.syntax.choice._ import cats.syntax.compose._ /** - * Laws that must be obeyed by any `cats.arrow.Choice`. - */ + * Laws that must be obeyed by any `cats.arrow.Choice`. + */ trait ChoiceLaws[F[_, _]] extends CategoryLaws[F] { implicit override def F: Choice[F] diff --git a/laws/src/main/scala/cats/laws/CoflatMapLaws.scala b/laws/src/main/scala/cats/laws/CoflatMapLaws.scala index 7591959d8fb..7de2cd580bf 100644 --- a/laws/src/main/scala/cats/laws/CoflatMapLaws.scala +++ b/laws/src/main/scala/cats/laws/CoflatMapLaws.scala @@ -5,8 +5,8 @@ import cats.data.Cokleisli import cats.implicits._ /** - * Laws that must be obeyed by any `CoflatMap`. - */ + * Laws that must be obeyed by any `CoflatMap`. + */ trait CoflatMapLaws[F[_]] extends FunctorLaws[F] { implicit override def F: CoflatMap[F] @@ -23,12 +23,12 @@ trait CoflatMapLaws[F[_]] extends FunctorLaws[F] { fa.coflatten <-> fa.coflatMap(identity) /** - * The composition of `cats.data.Cokleisli` arrows is associative. This is - * analogous to [[coflatMapAssociativity]]. - */ + * The composition of `cats.data.Cokleisli` arrows is associative. This is + * analogous to [[coflatMapAssociativity]]. + */ def cokleisliAssociativity[A, B, C, D](f: F[A] => B, g: F[B] => C, h: F[C] => D, fa: F[A]): IsEq[D] = { val (cf, cg, ch) = (Cokleisli(f), Cokleisli(g), Cokleisli(h)) - ((cf andThen cg) andThen ch).run(fa) <-> (cf andThen (cg andThen ch)).run(fa) + (cf.andThen(cg)).andThen(ch).run(fa) <-> cf.andThen(cg.andThen(ch)).run(fa) } } diff --git a/laws/src/main/scala/cats/laws/CommutativeFlatMapLaws.scala b/laws/src/main/scala/cats/laws/CommutativeFlatMapLaws.scala index 1ed46cd511b..4bc7e293637 100644 --- a/laws/src/main/scala/cats/laws/CommutativeFlatMapLaws.scala +++ b/laws/src/main/scala/cats/laws/CommutativeFlatMapLaws.scala @@ -2,14 +2,14 @@ package cats package laws /** - * Laws that must be obeyed by any `CommutativeFlatMap`. - */ + * Laws that must be obeyed by any `CommutativeFlatMap`. + */ trait CommutativeFlatMapLaws[F[_]] extends CommutativeApplyLaws[F] with FlatMapLaws[F] { implicit override def F: CommutativeFlatMap[F] def flatmapCommutative[A, B, C](fa: F[A], fb: F[B], g: (A, B) => F[C]): IsEq[F[C]] = - F.flatMap(fa)( a => F.flatMap(fb)( b => g(a, b))) <-> - F.flatMap(fb)( b => F.flatMap(fa)( a => g(a, b))) + F.flatMap(fa)(a => F.flatMap(fb)(b => g(a, b))) <-> + F.flatMap(fb)(b => F.flatMap(fa)(a => g(a, b))) } diff --git a/laws/src/main/scala/cats/laws/CommutativeMonadLaws.scala b/laws/src/main/scala/cats/laws/CommutativeMonadLaws.scala index 7333a994efb..8fb3cfc9a4c 100644 --- a/laws/src/main/scala/cats/laws/CommutativeMonadLaws.scala +++ b/laws/src/main/scala/cats/laws/CommutativeMonadLaws.scala @@ -2,9 +2,12 @@ package cats package laws /** - * Laws that must be obeyed by any `CommutativeMonad`. - */ -trait CommutativeMonadLaws[F[_]] extends MonadLaws[F] with CommutativeFlatMapLaws[F] with CommutativeApplicativeLaws[F] { + * Laws that must be obeyed by any `CommutativeMonad`. + */ +trait CommutativeMonadLaws[F[_]] + extends MonadLaws[F] + with CommutativeFlatMapLaws[F] + with CommutativeApplicativeLaws[F] { implicit override def F: CommutativeMonad[F] } diff --git a/laws/src/main/scala/cats/laws/ComonadLaws.scala b/laws/src/main/scala/cats/laws/ComonadLaws.scala index d594c44155a..43992048235 100644 --- a/laws/src/main/scala/cats/laws/ComonadLaws.scala +++ b/laws/src/main/scala/cats/laws/ComonadLaws.scala @@ -5,8 +5,8 @@ import cats.data.Cokleisli import cats.implicits._ /** - * Laws that must be obeyed by any `Comonad`. - */ + * Laws that must be obeyed by any `Comonad`. + */ trait ComonadLaws[F[_]] extends CoflatMapLaws[F] { implicit override def F: Comonad[F] @@ -26,18 +26,18 @@ trait ComonadLaws[F[_]] extends CoflatMapLaws[F] { fa.coflatMap(f).extract <-> f(fa) /** - * `extract` is the left identity element under left-to-right composition of - * `cats.data.Cokleisli` arrows. This is analogous to [[comonadLeftIdentity]]. - */ + * `extract` is the left identity element under left-to-right composition of + * `cats.data.Cokleisli` arrows. This is analogous to [[comonadLeftIdentity]]. + */ def cokleisliLeftIdentity[A, B](fa: F[A], f: F[A] => B): IsEq[B] = - (Cokleisli(F.extract[A]) andThen Cokleisli(f)).run(fa) <-> f(fa) + Cokleisli(F.extract[A]).andThen(Cokleisli(f)).run(fa) <-> f(fa) /** - * `extract` is the right identity element under left-to-right composition of - * `cats.data.Cokleisli` arrows. This is analogous to [[comonadRightIdentity]]. - */ + * `extract` is the right identity element under left-to-right composition of + * `cats.data.Cokleisli` arrows. This is analogous to [[comonadRightIdentity]]. + */ def cokleisliRightIdentity[A, B](fa: F[A], f: F[A] => B): IsEq[B] = - (Cokleisli(f) andThen Cokleisli(F.extract[B])).run(fa) <-> f(fa) + Cokleisli(f).andThen(Cokleisli(F.extract[B])).run(fa) <-> f(fa) } object ComonadLaws { diff --git a/laws/src/main/scala/cats/laws/ComposeLaws.scala b/laws/src/main/scala/cats/laws/ComposeLaws.scala index e6b35191568..a55ffcbbb2a 100644 --- a/laws/src/main/scala/cats/laws/ComposeLaws.scala +++ b/laws/src/main/scala/cats/laws/ComposeLaws.scala @@ -5,13 +5,13 @@ import cats.arrow.Compose import cats.syntax.compose._ /** - * Laws that must be obeyed by any `cats.arrow.Compose`. - */ + * Laws that must be obeyed by any `cats.arrow.Compose`. + */ trait ComposeLaws[F[_, _]] { implicit def F: Compose[F] def composeAssociativity[A, B, C, D](fab: F[A, B], fbc: F[B, C], fcd: F[C, D]): IsEq[F[A, D]] = - ((fab andThen fbc) andThen fcd) <-> (fab andThen (fbc andThen fcd)) + ((fab.andThen(fbc)).andThen(fcd)) <-> (fab.andThen(fbc.andThen(fcd))) } object ComposeLaws { diff --git a/laws/src/main/scala/cats/laws/ContravariantLaws.scala b/laws/src/main/scala/cats/laws/ContravariantLaws.scala index 234ffc707b7..2e79ac7847c 100644 --- a/laws/src/main/scala/cats/laws/ContravariantLaws.scala +++ b/laws/src/main/scala/cats/laws/ContravariantLaws.scala @@ -5,8 +5,8 @@ import cats.Contravariant import cats.syntax.contravariant._ /** - * Laws that must be obeyed by any `cats.Contravariant`. - */ + * Laws that must be obeyed by any `cats.Contravariant`. + */ trait ContravariantLaws[F[_]] extends InvariantLaws[F] { implicit override def F: Contravariant[F] @@ -14,7 +14,7 @@ trait ContravariantLaws[F[_]] extends InvariantLaws[F] { fa.contramap(identity[A]) <-> fa def contravariantComposition[A, B, C](fa: F[A], f: B => A, g: C => B): IsEq[F[C]] = - fa.contramap(f).contramap(g) <-> fa.contramap(f compose g) + fa.contramap(f).contramap(g) <-> fa.contramap(f.compose(g)) } object ContravariantLaws { diff --git a/laws/src/main/scala/cats/laws/ContravariantMonoidalLaws.scala b/laws/src/main/scala/cats/laws/ContravariantMonoidalLaws.scala index ef99653482c..f7a348fd47c 100644 --- a/laws/src/main/scala/cats/laws/ContravariantMonoidalLaws.scala +++ b/laws/src/main/scala/cats/laws/ContravariantMonoidalLaws.scala @@ -6,8 +6,8 @@ import cats.syntax.contravariant._ import cats.syntax.contravariantSemigroupal._ /** - * Laws that must hold for any `cats.ContravariantMonoidal`. - */ + * Laws that must hold for any `cats.ContravariantMonoidal`. + */ trait ContravariantMonoidalLaws[F[_]] extends ContravariantSemigroupalLaws[F] { implicit override def F: ContravariantMonoidal[F] @@ -18,10 +18,10 @@ trait ContravariantMonoidalLaws[F[_]] extends ContravariantSemigroupalLaws[F] { (F.trivial[A], fa).contramapN(delta[A]) <-> fa def contravariantMonoidalContramap2CompatibleContramapLeft[A, B, C](fa: F[A], f: B => (A, C)): IsEq[F[B]] = - (fa, F.trivial[C]).contramapN(f) <-> fa.contramap(f andThen (_._1)) + (fa, F.trivial[C]).contramapN(f) <-> fa.contramap(f.andThen(_._1)) def contravariantMonoidalContramap2CompatibleContramapRight[A, B, C](fa: F[A], f: C => (B, A)): IsEq[F[C]] = - (F.trivial[B], fa).contramapN(f) <-> fa.contramap(f andThen (_._2)) + (F.trivial[B], fa).contramapN(f) <-> fa.contramap(f.andThen(_._2)) } object ContravariantMonoidalLaws { diff --git a/laws/src/main/scala/cats/laws/ContravariantSemigroupalLaws.scala b/laws/src/main/scala/cats/laws/ContravariantSemigroupalLaws.scala index 4ba3a6990d0..0bbbc0bbfb9 100644 --- a/laws/src/main/scala/cats/laws/ContravariantSemigroupalLaws.scala +++ b/laws/src/main/scala/cats/laws/ContravariantSemigroupalLaws.scala @@ -5,8 +5,8 @@ import cats.ContravariantSemigroupal import cats.syntax.contravariantSemigroupal._ /** - * Laws that are expected for any `cats.ContravariantSemigroupal`. - */ + * Laws that are expected for any `cats.ContravariantSemigroupal`. + */ trait ContravariantSemigroupalLaws[F[_]] extends ContravariantLaws[F] with SemigroupalLaws[F] { implicit override def F: ContravariantSemigroupal[F] diff --git a/laws/src/main/scala/cats/laws/DeferLaws.scala b/laws/src/main/scala/cats/laws/DeferLaws.scala index 5e24cf7fe8b..646bc26a3a1 100644 --- a/laws/src/main/scala/cats/laws/DeferLaws.scala +++ b/laws/src/main/scala/cats/laws/DeferLaws.scala @@ -2,9 +2,10 @@ package cats package laws import catalysts.Platform + /** - * Laws that must be obeyed by any `Defer`. - */ + * Laws that must be obeyed by any `Defer`. + */ trait DeferLaws[F[_]] { implicit def F: Defer[F] diff --git a/laws/src/main/scala/cats/laws/DistributiveLaws.scala b/laws/src/main/scala/cats/laws/DistributiveLaws.scala index 1df311b4457..744bcefff6c 100644 --- a/laws/src/main/scala/cats/laws/DistributiveLaws.scala +++ b/laws/src/main/scala/cats/laws/DistributiveLaws.scala @@ -8,13 +8,11 @@ import cats.syntax.distributive._ trait DistributiveLaws[F[_]] extends FunctorLaws[F] { implicit override def F: Distributive[F] - def distributeIdentity[A, B](fa: F[A], f: A => B): IsEq[F[B]] = { + def distributeIdentity[A, B](fa: F[A], f: A => B): IsEq[F[B]] = fa.distribute[Id, B](f) <-> F.map(fa)(f) - } - def cosequenceIdentity[A](fa: F[A]): IsEq[F[A]] = { + def cosequenceIdentity[A](fa: F[A]): IsEq[F[A]] = F.cosequence[Id, A](fa) <-> fa - } def cosequenceTwiceIsId[A, M[_]](fma: F[M[A]])(implicit M: Distributive[M]): IsEq[F[M[A]]] = { val result = F.cosequence(M.cosequence(fma)) @@ -27,8 +25,7 @@ trait DistributiveLaws[F[_]] extends FunctorLaws[F] { g: B => N[C] )(implicit N: Distributive[N], - M: Functor[M] - ): IsEq[Nested[F, N, M[C]]] = { + M: Functor[M]): IsEq[Nested[F, N, M[C]]] = { val rhs = ma.distribute[Nested[F, N, ?], C](a => Nested(F.map(f(a))(g))) val lhs = Nested(F.map(ma.distribute(f))(fb => fb.distribute(g))) lhs <-> rhs diff --git a/laws/src/main/scala/cats/laws/FlatMapLaws.scala b/laws/src/main/scala/cats/laws/FlatMapLaws.scala index 93d0da15af0..e261011d176 100644 --- a/laws/src/main/scala/cats/laws/FlatMapLaws.scala +++ b/laws/src/main/scala/cats/laws/FlatMapLaws.scala @@ -7,8 +7,8 @@ import cats.syntax.flatMap._ import cats.syntax.functor._ /** - * Laws that must be obeyed by any `FlatMap`. - */ + * Laws that must be obeyed by any `FlatMap`. + */ trait FlatMapLaws[F[_]] extends ApplyLaws[F] { implicit override def F: FlatMap[F] @@ -18,23 +18,23 @@ trait FlatMapLaws[F[_]] extends ApplyLaws[F] { def flatMapConsistentApply[A, B](fa: F[A], fab: F[A => B]): IsEq[F[B]] = fab.ap(fa) <-> fab.flatMap(f => fa.map(f)) - /** - * The composition of `cats.data.Kleisli` arrows is associative. This is - * analogous to [[flatMapAssociativity]]. - */ + * The composition of `cats.data.Kleisli` arrows is associative. This is + * analogous to [[flatMapAssociativity]]. + */ def kleisliAssociativity[A, B, C, D](f: A => F[B], g: B => F[C], h: C => F[D], a: A): IsEq[F[D]] = { val (kf, kg, kh) = (Kleisli(f), Kleisli(g), Kleisli(h)) - ((kf andThen kg) andThen kh).run(a) <-> (kf andThen (kg andThen kh)).run(a) + (kf.andThen(kg)).andThen(kh).run(a) <-> kf.andThen(kg.andThen(kh)).run(a) } def mproductConsistency[A, B](fa: F[A], fb: A => F[B]): IsEq[F[(A, B)]] = F.mproduct(fa)(fb) <-> F.flatMap(fa)(a => F.map(fb(a))((a, _))) def tailRecMConsistentFlatMap[A](a: A, f: A => F[A]): IsEq[F[A]] = { - def bounce(n: Int) = F.tailRecM[(A, Int), A]((a, n)) { case (a0, i) => - if (i > 0) f(a0).map(a1 => Left((a1, i-1))) - else f(a0).map(Right(_)) + def bounce(n: Int) = F.tailRecM[(A, Int), A]((a, n)) { + case (a0, i) => + if (i > 0) f(a0).map(a1 => Left((a1, i - 1))) + else f(a0).map(Right(_)) } /* * The law is for n >= 1 @@ -47,13 +47,19 @@ trait FlatMapLaws[F[_]] extends ApplyLaws[F] { } /** - * It is possible to implement flatMap from tailRecM and map - * and it should agree with the flatMap implementation. - */ + * It is possible to implement flatMap from tailRecM and map + * and it should agree with the flatMap implementation. + */ def flatMapFromTailRecMConsistency[A, B](fa: F[A], fn: A => F[B]): IsEq[F[B]] = { val tailRecMFlatMap = F.tailRecM[Option[A], B](Option.empty[A]) { - case None => F.map(fa) { a => Left(Some(a)) } - case Some(a) => F.map(fn(a)) { b => Right(b) } + case None => + F.map(fa) { a => + Left(Some(a)) + } + case Some(a) => + F.map(fn(a)) { b => + Right(b) + } } F.flatMap(fa)(fn) <-> tailRecMFlatMap diff --git a/laws/src/main/scala/cats/laws/FoldableLaws.scala b/laws/src/main/scala/cats/laws/FoldableLaws.scala index 2d7d261956f..6773fb56f56 100644 --- a/laws/src/main/scala/cats/laws/FoldableLaws.scala +++ b/laws/src/main/scala/cats/laws/FoldableLaws.scala @@ -12,49 +12,43 @@ trait FoldableLaws[F[_]] extends UnorderedFoldableLaws[F] { fa: F[A], f: A => B )(implicit - M: Monoid[B] - ): IsEq[B] = { - fa.foldMap(f) <-> fa.foldLeft(M.empty) { (b, a) => b |+| f(a) } - } + M: Monoid[B]): IsEq[B] = + fa.foldMap(f) <-> fa.foldLeft(M.empty) { (b, a) => + b |+| f(a) + } def rightFoldConsistentWithFoldMap[A, B]( fa: F[A], f: A => B )(implicit - M: Monoid[B] - ): IsEq[B] = { + M: Monoid[B]): IsEq[B] = fa.foldMap(f) <-> fa.foldRight(Later(M.empty))((a, lb) => lb.map(f(a) |+| _)).value - } - def existsConsistentWithFind[A](fa: F[A], p: A => Boolean): Boolean = { + def existsConsistentWithFind[A](fa: F[A], p: A => Boolean): Boolean = F.exists(fa)(p) == F.find(fa)(p).isDefined - } - /** - * Monadic folding with identity monad is analogous to `foldLeft`. - */ + * Monadic folding with identity monad is analogous to `foldLeft`. + */ def foldMIdentity[A, B]( fa: F[A], b: B, f: (B, A) => B - ): IsEq[B] = { + ): IsEq[B] = F.foldM[Id, A, B](fa, b)(f) <-> F.foldLeft(fa, b)(f) - } /** - * `reduceLeftOption` consistent with `reduceLeftToOption` - */ + * `reduceLeftOption` consistent with `reduceLeftToOption` + */ def reduceLeftOptionConsistentWithReduceLeftToOption[A]( fa: F[A], f: (A, A) => A - ): IsEq[Option[A]] = { + ): IsEq[Option[A]] = F.reduceLeftOption(fa)(f) <-> F.reduceLeftToOption(fa)(identity)(f) - } /** - * `reduceRightOption` consistent with `reduceRightToOption` - */ + * `reduceRightOption` consistent with `reduceRightToOption` + */ def reduceRightOptionConsistentWithReduceRightToOption[A]( fa: F[A], f: (A, A) => A @@ -64,40 +58,52 @@ trait FoldableLaws[F[_]] extends UnorderedFoldableLaws[F] { } def getRef[A](fa: F[A], idx: Long): IsEq[Option[A]] = - F.get(fa)(idx) <-> ( - if (idx < 0L) None - else F.foldM[Either[A, ?], A, Long](fa, 0L) { (i, a) => - if (i == idx) Left(a) else Right(i + 1L) - } match { - case Left(a) => Some(a) - case Right(_) => None - }) + F.get(fa)(idx) <-> (if (idx < 0L) None + else + F.foldM[Either[A, ?], A, Long](fa, 0L) { (i, a) => + if (i == idx) Left(a) else Right(i + 1L) + } match { + case Left(a) => Some(a) + case Right(_) => None + }) def foldRef[A](fa: F[A])(implicit A: Monoid[A]): IsEq[A] = - F.fold(fa) <-> F.foldLeft(fa, A.empty) { (acc, a) => A.combine(acc, a) } + F.fold(fa) <-> F.foldLeft(fa, A.empty) { (acc, a) => + A.combine(acc, a) + } def toListRef[A](fa: F[A]): IsEq[List[A]] = - F.toList(fa) <-> F.foldLeft(fa, mutable.ListBuffer.empty[A]) { (buf, a) => - buf += a - }.toList + F.toList(fa) <-> F + .foldLeft(fa, mutable.ListBuffer.empty[A]) { (buf, a) => + buf += a + } + .toList def filter_Ref[A](fa: F[A], p: A => Boolean): IsEq[List[A]] = - F.filter_(fa)(p) <-> F.foldLeft(fa, mutable.ListBuffer.empty[A]) { (buf, a) => - if (p(a)) buf += a else buf - }.toList + F.filter_(fa)(p) <-> F + .foldLeft(fa, mutable.ListBuffer.empty[A]) { (buf, a) => + if (p(a)) buf += a else buf + } + .toList def takeWhile_Ref[A](fa: F[A], p: A => Boolean): IsEq[List[A]] = - F.takeWhile_(fa)(p) <-> F.foldRight(fa, Now(List.empty[A])) { (a, llst) => - if (p(a)) llst.map(a :: _) else Now(Nil) - }.value + F.takeWhile_(fa)(p) <-> F + .foldRight(fa, Now(List.empty[A])) { (a, llst) => + if (p(a)) llst.map(a :: _) else Now(Nil) + } + .value def dropWhile_Ref[A](fa: F[A], p: A => Boolean): IsEq[List[A]] = - F.dropWhile_(fa)(p) <-> F.foldLeft(fa, mutable.ListBuffer.empty[A]) { (buf, a) => - if (buf.nonEmpty || !p(a)) buf += a else buf - }.toList + F.dropWhile_(fa)(p) <-> F + .foldLeft(fa, mutable.ListBuffer.empty[A]) { (buf, a) => + if (buf.nonEmpty || !p(a)) buf += a else buf + } + .toList def collectFirstSome_Ref[A, B](fa: F[A], f: A => Option[B]): IsEq[Option[B]] = - F.collectFirstSome(fa)(f) <-> F.foldLeft(fa, Option.empty[B]){ (ob, a) => if (ob.isDefined) ob else f(a) } + F.collectFirstSome(fa)(f) <-> F.foldLeft(fa, Option.empty[B]) { (ob, a) => + if (ob.isDefined) ob else f(a) + } def collectFirst_Ref[A, B](fa: F[A], pf: PartialFunction[A, B]): IsEq[Option[B]] = F.collectFirst(fa)(pf) <-> F.collectFirstSome(fa)(pf.lift) diff --git a/laws/src/main/scala/cats/laws/FunctorFilterLaws.scala b/laws/src/main/scala/cats/laws/FunctorFilterLaws.scala index 32af361b1d7..a3e65012dab 100644 --- a/laws/src/main/scala/cats/laws/FunctorFilterLaws.scala +++ b/laws/src/main/scala/cats/laws/FunctorFilterLaws.scala @@ -1,11 +1,9 @@ package cats package laws - trait FunctorFilterLaws[F[_]] { implicit def F: FunctorFilter[F] - implicit def functor: Functor[F] = F.functor def mapFilterComposition[A, B, C](fa: F[A], f: A => Option[B], g: B => Option[C]): IsEq[F[C]] = { @@ -14,22 +12,18 @@ trait FunctorFilterLaws[F[_]] { lhs <-> rhs } - def mapFilterMapConsistency[A, B](fa: F[A], f: A => B): IsEq[F[B]] = { - F.mapFilter(fa)(f andThen (x => Some(x): Option[B])) <-> functor.map(fa)(f) - } + def mapFilterMapConsistency[A, B](fa: F[A], f: A => B): IsEq[F[B]] = + F.mapFilter(fa)(f.andThen(x => Some(x): Option[B])) <-> functor.map(fa)(f) - def collectConsistentWithMapFilter[A, B](fa: F[A], f: PartialFunction[A, B]): IsEq[F[B]] = { + def collectConsistentWithMapFilter[A, B](fa: F[A], f: PartialFunction[A, B]): IsEq[F[B]] = F.collect(fa)(f) <-> F.mapFilter(fa)(f.lift) - } - def flattenOptionConsistentWithMapFilter[A](fa: F[Option[A]]): IsEq[F[A]] = { + def flattenOptionConsistentWithMapFilter[A](fa: F[Option[A]]): IsEq[F[A]] = F.flattenOption(fa) <-> F.mapFilter(fa)(identity) - } - def filterConsistentWithMapFilter[A](fa: F[A], f: A => Boolean): IsEq[F[A]] = { + def filterConsistentWithMapFilter[A](fa: F[A], f: A => Boolean): IsEq[F[A]] = F.filter(fa)(f) <-> F.mapFilter(fa)(a => if (f(a)) Some(a) else None) - } } object FunctorFilterLaws { diff --git a/laws/src/main/scala/cats/laws/FunctorLaws.scala b/laws/src/main/scala/cats/laws/FunctorLaws.scala index 48f9f9ff562..14f6d71e86f 100644 --- a/laws/src/main/scala/cats/laws/FunctorLaws.scala +++ b/laws/src/main/scala/cats/laws/FunctorLaws.scala @@ -4,8 +4,8 @@ package laws import cats.syntax.functor._ /** - * Laws that must be obeyed by any `Functor`. - */ + * Laws that must be obeyed by any `Functor`. + */ trait FunctorLaws[F[_]] extends InvariantLaws[F] { implicit override def F: Functor[F] @@ -13,7 +13,7 @@ trait FunctorLaws[F[_]] extends InvariantLaws[F] { fa.map(identity) <-> fa def covariantComposition[A, B, C](fa: F[A], f: A => B, g: B => C): IsEq[F[C]] = - fa.map(f).map(g) <-> fa.map(f andThen g) + fa.map(f).map(g) <-> fa.map(f.andThen(g)) } object FunctorLaws { diff --git a/laws/src/main/scala/cats/laws/InjectKLaws.scala b/laws/src/main/scala/cats/laws/InjectKLaws.scala index 01049c69803..b5b77c90b17 100644 --- a/laws/src/main/scala/cats/laws/InjectKLaws.scala +++ b/laws/src/main/scala/cats/laws/InjectKLaws.scala @@ -5,7 +5,7 @@ trait InjectKLaws[F[_], G[_]] { def injectK: InjectK[F, G] def injectKRoundTripInj[A](fa: F[A]): IsEq[Option[F[A]]] = - (injectK.prj compose injectK.inj).apply(fa) <-> Some(fa) + injectK.prj.compose(injectK.inj).apply(fa) <-> Some(fa) def injectKRoundTripPrj[A](ga: G[A]): IsEq[Option[G[A]]] = injectK.prj(ga) match { @@ -16,5 +16,5 @@ trait InjectKLaws[F[_], G[_]] { object InjectKLaws { def apply[F[_], G[_]](implicit ev: InjectK[F, G]): InjectKLaws[F, G] = - new InjectKLaws[F, G]{ val injectK: InjectK[F, G] = ev } + new InjectKLaws[F, G] { val injectK: InjectK[F, G] = ev } } diff --git a/laws/src/main/scala/cats/laws/InjectLaws.scala b/laws/src/main/scala/cats/laws/InjectLaws.scala index 694e16edc80..956793698be 100644 --- a/laws/src/main/scala/cats/laws/InjectLaws.scala +++ b/laws/src/main/scala/cats/laws/InjectLaws.scala @@ -5,7 +5,7 @@ trait InjectLaws[A, B] { def inject: Inject[A, B] def injectRoundTripInj(a: A): IsEq[Option[A]] = - (inject.prj compose inject.inj).apply(a) <-> Some(a) + inject.prj.compose(inject.inj).apply(a) <-> Some(a) def injectRoundTripPrj(b: B): IsEq[Option[B]] = inject.prj(b) match { @@ -16,5 +16,5 @@ trait InjectLaws[A, B] { object InjectLaws { def apply[A, B](implicit ev: Inject[A, B]): InjectLaws[A, B] = - new InjectLaws[A, B]{ val inject: Inject[A, B] = ev } + new InjectLaws[A, B] { val inject: Inject[A, B] = ev } } diff --git a/laws/src/main/scala/cats/laws/InvariantLaws.scala b/laws/src/main/scala/cats/laws/InvariantLaws.scala index b6f762679b9..7b61f5bc563 100644 --- a/laws/src/main/scala/cats/laws/InvariantLaws.scala +++ b/laws/src/main/scala/cats/laws/InvariantLaws.scala @@ -5,8 +5,8 @@ import cats.Invariant import cats.syntax.invariant._ /** - * Laws that must be obeyed by any `cats.Invariant`. - */ + * Laws that must be obeyed by any `cats.Invariant`. + */ trait InvariantLaws[F[_]] { implicit def F: Invariant[F] @@ -14,7 +14,7 @@ trait InvariantLaws[F[_]] { fa.imap(identity[A])(identity[A]) <-> fa def invariantComposition[A, B, C](fa: F[A], f1: A => B, f2: B => A, g1: B => C, g2: C => B): IsEq[F[C]] = - fa.imap(f1)(f2).imap(g1)(g2) <-> fa.imap(g1 compose f1)(f2 compose g2) + fa.imap(f1)(f2).imap(g1)(g2) <-> fa.imap(g1.compose(f1))(f2.compose(g2)) } object InvariantLaws { diff --git a/laws/src/main/scala/cats/laws/InvariantMonoidalLaws.scala b/laws/src/main/scala/cats/laws/InvariantMonoidalLaws.scala index 528bd7ae72e..151c90aebb5 100644 --- a/laws/src/main/scala/cats/laws/InvariantMonoidalLaws.scala +++ b/laws/src/main/scala/cats/laws/InvariantMonoidalLaws.scala @@ -2,10 +2,10 @@ package cats package laws /** - * Laws that must be obeyed by any `cats.InvariantMonoidal`. - */ + * Laws that must be obeyed by any `cats.InvariantMonoidal`. + */ trait InvariantMonoidalLaws[F[_]] extends InvariantSemigroupalLaws[F] { - override implicit def F: InvariantMonoidal[F] + implicit override def F: InvariantMonoidal[F] import cats.syntax.semigroupal._ import cats.syntax.invariant._ @@ -15,10 +15,11 @@ trait InvariantMonoidalLaws[F[_]] extends InvariantSemigroupalLaws[F] { def invariantMonoidalRightIdentity[A, B](fa: F[A]): IsEq[F[A]] = fa.product(F.unit).imap(_._1)(a => (a, ())) <-> fa - def invariantMonoidalAssociativity[A, B, C](fa: F[A], fb: F[B], fc: F[C]): - IsEq[F[(A, (B, C))]] = - fa.product(fb.product(fc)) <-> fa.product(fb).product(fc) - .imap { case ((a, b), c) => (a, (b, c)) } { case (a, (b, c)) => ((a, b), c) } + def invariantMonoidalAssociativity[A, B, C](fa: F[A], fb: F[B], fc: F[C]): IsEq[F[(A, (B, C))]] = + fa.product(fb.product(fc)) <-> fa + .product(fb) + .product(fc) + .imap { case ((a, b), c) => (a, (b, c)) } { case (a, (b, c)) => ((a, b), c) } } object InvariantMonoidalLaws { diff --git a/laws/src/main/scala/cats/laws/InvariantSemigroupalLaws.scala b/laws/src/main/scala/cats/laws/InvariantSemigroupalLaws.scala index f1c301787c4..34202fdb948 100644 --- a/laws/src/main/scala/cats/laws/InvariantSemigroupalLaws.scala +++ b/laws/src/main/scala/cats/laws/InvariantSemigroupalLaws.scala @@ -1,7 +1,6 @@ package cats package laws - /** * Laws that are expected for any `cats.InvariantSemigroupal`. */ diff --git a/laws/src/main/scala/cats/laws/MonadLaws.scala b/laws/src/main/scala/cats/laws/MonadLaws.scala index f6e8e304aa4..fc2791aacf0 100644 --- a/laws/src/main/scala/cats/laws/MonadLaws.scala +++ b/laws/src/main/scala/cats/laws/MonadLaws.scala @@ -5,8 +5,8 @@ import cats.data.Kleisli import cats.implicits._ /** - * Laws that must be obeyed by any `Monad`. - */ + * Laws that must be obeyed by any `Monad`. + */ trait MonadLaws[F[_]] extends ApplicativeLaws[F] with FlatMapLaws[F] { implicit override def F: Monad[F] @@ -17,22 +17,22 @@ trait MonadLaws[F[_]] extends ApplicativeLaws[F] with FlatMapLaws[F] { fa.flatMap(F.pure) <-> fa /** - * `pure` is the left identity element under left-to-right composition of - * `cats.data.Kleisli` arrows. This is analogous to [[monadLeftIdentity]]. - */ + * `pure` is the left identity element under left-to-right composition of + * `cats.data.Kleisli` arrows. This is analogous to [[monadLeftIdentity]]. + */ def kleisliLeftIdentity[A, B](a: A, f: A => F[B]): IsEq[F[B]] = - (Kleisli(F.pure[A]) andThen Kleisli(f)).run(a) <-> f(a) + Kleisli(F.pure[A]).andThen(Kleisli(f)).run(a) <-> f(a) /** - * `pure` is the right identity element under left-to-right composition of - * `cats.data.Kleisli` arrows. This is analogous to [[monadRightIdentity]]. - */ + * `pure` is the right identity element under left-to-right composition of + * `cats.data.Kleisli` arrows. This is analogous to [[monadRightIdentity]]. + */ def kleisliRightIdentity[A, B](a: A, f: A => F[B]): IsEq[F[B]] = - (Kleisli(f) andThen Kleisli(F.pure[B])).run(a) <-> f(a) + Kleisli(f).andThen(Kleisli(F.pure[B])).run(a) <-> f(a) /** - * Make sure that map and flatMap are consistent. - */ + * Make sure that map and flatMap are consistent. + */ def mapFlatMapCoherence[A, B](fa: F[A], f: A => B): IsEq[F[B]] = fa.flatMap(a => F.pure(f(a))) <-> fa.map(f) diff --git a/laws/src/main/scala/cats/laws/MonoidKLaws.scala b/laws/src/main/scala/cats/laws/MonoidKLaws.scala index 8f2f3b600c8..5ed1f9d04df 100644 --- a/laws/src/main/scala/cats/laws/MonoidKLaws.scala +++ b/laws/src/main/scala/cats/laws/MonoidKLaws.scala @@ -2,10 +2,10 @@ package cats package laws /** - * Laws that must be obeyed by any `cats.MonoidK`. - */ + * Laws that must be obeyed by any `cats.MonoidK`. + */ trait MonoidKLaws[F[_]] extends SemigroupKLaws[F] { - override implicit def F: MonoidK[F] + implicit override def F: MonoidK[F] def monoidKLeftIdentity[A](a: F[A]): IsEq[F[A]] = F.combineK(F.empty, a) <-> a diff --git a/laws/src/main/scala/cats/laws/NonEmptyParallelLaws.scala b/laws/src/main/scala/cats/laws/NonEmptyParallelLaws.scala index f3251d0b565..ded8d6f66c3 100644 --- a/laws/src/main/scala/cats/laws/NonEmptyParallelLaws.scala +++ b/laws/src/main/scala/cats/laws/NonEmptyParallelLaws.scala @@ -1,7 +1,6 @@ package cats package laws - /** * Laws that must be obeyed by any `cats.NonEmptyParallel`. */ diff --git a/laws/src/main/scala/cats/laws/NonEmptyTraverseLaws.scala b/laws/src/main/scala/cats/laws/NonEmptyTraverseLaws.scala index cf0423cb2bd..b9b8b4c16b4 100644 --- a/laws/src/main/scala/cats/laws/NonEmptyTraverseLaws.scala +++ b/laws/src/main/scala/cats/laws/NonEmptyTraverseLaws.scala @@ -1,7 +1,6 @@ package cats.laws - -import cats.{Apply, Id, Semigroup, NonEmptyTraverse} +import cats.{Apply, Id, NonEmptyTraverse, Semigroup} import cats.data.{Const, Nested} import cats.syntax.nonEmptyTraverse._ import cats.syntax.reducible._ @@ -9,18 +8,16 @@ import cats.syntax.reducible._ trait NonEmptyTraverseLaws[F[_]] extends TraverseLaws[F] with ReducibleLaws[F] { implicit override def F: NonEmptyTraverse[F] - def nonEmptyTraverseIdentity[A, B](fa: F[A], f: A => B): IsEq[F[B]] = { + def nonEmptyTraverseIdentity[A, B](fa: F[A], f: A => B): IsEq[F[B]] = fa.nonEmptyTraverse[Id, B](f) <-> F.map(fa)(f) - } def nonEmptyTraverseSequentialComposition[A, B, C, M[_], N[_]]( - fa: F[A], - f: A => M[B], - g: B => N[C] - )(implicit - N: Apply[N], - M: Apply[M] - ): IsEq[Nested[M, N, F[C]]] = { + fa: F[A], + f: A => M[B], + g: B => N[C] + )(implicit + N: Apply[N], + M: Apply[M]): IsEq[Nested[M, N, F[C]]] = { val lhs = Nested(M.map(fa.nonEmptyTraverse(f))(fb => fb.nonEmptyTraverse(g))) val rhs = fa.nonEmptyTraverse[Nested[M, N, ?], C](a => Nested(M.map(f(a))(g))) @@ -28,13 +25,12 @@ trait NonEmptyTraverseLaws[F[_]] extends TraverseLaws[F] with ReducibleLaws[F] { } def nonEmptyTraverseParallelComposition[A, B, M[_], N[_]]( - fa: F[A], - f: A => M[B], - g: A => N[B] - )(implicit - N: Apply[N], - M: Apply[M] - ): IsEq[(M[F[B]], N[F[B]])] = { + fa: F[A], + f: A => M[B], + g: A => N[B] + )(implicit + N: Apply[N], + M: Apply[M]): IsEq[(M[F[B]], N[F[B]])] = { type MN[Z] = (M[Z], N[Z]) implicit val MN = new Apply[MN] { def ap[X, Y](f: MN[X => Y])(fa: MN[X]): MN[Y] = { @@ -58,9 +54,9 @@ trait NonEmptyTraverseLaws[F[_]] extends TraverseLaws[F] with ReducibleLaws[F] { } def reduceMapDerived[A, B]( - fa: F[A], - f: A => B - )(implicit B: Semigroup[B]): IsEq[B] = { + fa: F[A], + f: A => B + )(implicit B: Semigroup[B]): IsEq[B] = { val lhs: B = fa.nonEmptyTraverse[Const[B, ?], B](a => Const(f(a))).getConst val rhs: B = fa.reduceMap(f) lhs <-> rhs diff --git a/laws/src/main/scala/cats/laws/ParallelLaws.scala b/laws/src/main/scala/cats/laws/ParallelLaws.scala index d750064cc09..5987a025f0f 100644 --- a/laws/src/main/scala/cats/laws/ParallelLaws.scala +++ b/laws/src/main/scala/cats/laws/ParallelLaws.scala @@ -1,7 +1,6 @@ package cats package laws - /** * Laws that must be obeyed by any `cats.Parallel`. */ diff --git a/laws/src/main/scala/cats/laws/ProfunctorLaws.scala b/laws/src/main/scala/cats/laws/ProfunctorLaws.scala index 003b1eb6189..fa82615c5af 100644 --- a/laws/src/main/scala/cats/laws/ProfunctorLaws.scala +++ b/laws/src/main/scala/cats/laws/ProfunctorLaws.scala @@ -5,8 +5,8 @@ import cats.arrow.Profunctor import cats.syntax.profunctor._ /** - * Laws that must be obeyed by any `cats.functor.Profunctor`. - */ + * Laws that must be obeyed by any `cats.functor.Profunctor`. + */ trait ProfunctorLaws[F[_, _]] { implicit def F: Profunctor[F] @@ -14,9 +14,11 @@ trait ProfunctorLaws[F[_, _]] { fab.dimap(identity[A])(identity[B]) <-> fab def profunctorComposition[A2, A1, A0, B0, B1, B2](fab: F[A0, B0], - f2: A2 => A1, f1: A1 => A0, - g1: B0 => B1, g2: B1 => B2): IsEq[F[A2, B2]] = - fab.dimap(f1)(g1).dimap(f2)(g2) <-> fab.dimap(f1 compose f2)(g2 compose g1) + f2: A2 => A1, + f1: A1 => A0, + g1: B0 => B1, + g2: B1 => B2): IsEq[F[A2, B2]] = + fab.dimap(f1)(g1).dimap(f2)(g2) <-> fab.dimap(f1.compose(f2))(g2.compose(g1)) def profunctorLmapIdentity[A, B](fab: F[A, B]): IsEq[F[A, B]] = fab.lmap(identity[A]) <-> fab @@ -24,13 +26,11 @@ trait ProfunctorLaws[F[_, _]] { def profunctorRmapIdentity[A, B](fab: F[A, B]): IsEq[F[A, B]] = fab.rmap(identity[B]) <-> fab - def profunctorLmapComposition[A2, A1, A0, B](fab: F[A0, B], - f: A2 => A1, g: A1 => A0): IsEq[F[A2, B]] = - fab.lmap(g).lmap(f) <-> fab.lmap(g compose f) + def profunctorLmapComposition[A2, A1, A0, B](fab: F[A0, B], f: A2 => A1, g: A1 => A0): IsEq[F[A2, B]] = + fab.lmap(g).lmap(f) <-> fab.lmap(g.compose(f)) - def profunctorRmapComposition[A, B2, B1, B0](fab: F[A, B0], - f: B0 => B1, g: B1 => B2): IsEq[F[A, B2]] = - fab.rmap(f).rmap(g) <-> fab.rmap(g compose f) + def profunctorRmapComposition[A, B2, B1, B0](fab: F[A, B0], f: B0 => B1, g: B1 => B2): IsEq[F[A, B2]] = + fab.rmap(f).rmap(g) <-> fab.rmap(g.compose(f)) } diff --git a/laws/src/main/scala/cats/laws/ReducibleLaws.scala b/laws/src/main/scala/cats/laws/ReducibleLaws.scala index bd74e04e0d1..4d52ebd9e0c 100644 --- a/laws/src/main/scala/cats/laws/ReducibleLaws.scala +++ b/laws/src/main/scala/cats/laws/ReducibleLaws.scala @@ -10,24 +10,21 @@ trait ReducibleLaws[F[_]] extends FoldableLaws[F] { fa: F[A], f: A => B )(implicit - B: Semigroup[B] - ): IsEq[B] = + B: Semigroup[B]): IsEq[B] = fa.reduceMap(f) <-> fa.reduceLeftTo(f)((b, a) => b |+| f(a)) def reduceRightToConsistentWithReduceMap[A, B]( fa: F[A], f: A => B )(implicit - B: Semigroup[B] - ): IsEq[B] = + B: Semigroup[B]): IsEq[B] = fa.reduceMap(f) <-> fa.reduceRightTo(f)((a, eb) => eb.map(f(a) |+| _)).value def reduceRightToConsistentWithReduceRightToOption[A, B]( fa: F[A], f: A => B )(implicit - B: Semigroup[B] - ): IsEq[Option[B]] = + B: Semigroup[B]): IsEq[Option[B]] = fa.reduceRightToOption(f)((a, eb) => eb.map(f(a) |+| _)).value <-> fa.reduceRightTo(f)((a, eb) => eb.map(f(a) |+| _)).map(Option(_)).value diff --git a/laws/src/main/scala/cats/laws/RepresentableLaws.scala b/laws/src/main/scala/cats/laws/RepresentableLaws.scala index ed997a2ef44..75e567e7c64 100644 --- a/laws/src/main/scala/cats/laws/RepresentableLaws.scala +++ b/laws/src/main/scala/cats/laws/RepresentableLaws.scala @@ -1,24 +1,21 @@ package cats package laws - /** - * Laws that must be obeyed by any `Representable` functor. - */ + * Laws that must be obeyed by any `Representable` functor. + */ trait RepresentableLaws[F[_], R] { - implicit val R: Representable.Aux[F, R] + implicit val R: Representable.Aux[F, R] - def indexTabulateIsId[B](fb: F[B]): IsEq[F[B]] = { - R.tabulate(R.index(fb)) <-> fb - } + def indexTabulateIsId[B](fb: F[B]): IsEq[F[B]] = + R.tabulate(R.index(fb)) <-> fb - def tabulateIndexIsId[B](f: R => B, x: R): IsEq[B] = { - R.index(R.tabulate(f))(x) <-> f(x) - } + def tabulateIndexIsId[B](f: R => B, x: R): IsEq[B] = + R.index(R.tabulate(f))(x) <-> f(x) } object RepresentableLaws { - def apply[F[_], R](implicit ev: Representable.Aux[F, R]): RepresentableLaws[F, R] = - new RepresentableLaws[F, R] { val R: Representable.Aux[F, R] = ev } + def apply[F[_], R](implicit ev: Representable.Aux[F, R]): RepresentableLaws[F, R] = + new RepresentableLaws[F, R] { val R: Representable.Aux[F, R] = ev } } diff --git a/laws/src/main/scala/cats/laws/SemigroupKLaws.scala b/laws/src/main/scala/cats/laws/SemigroupKLaws.scala index 34cd1792ced..88e18d86f38 100644 --- a/laws/src/main/scala/cats/laws/SemigroupKLaws.scala +++ b/laws/src/main/scala/cats/laws/SemigroupKLaws.scala @@ -2,8 +2,8 @@ package cats package laws /** - * Laws that must be obeyed by any `cats.SemigroupK`. - */ + * Laws that must be obeyed by any `cats.SemigroupK`. + */ trait SemigroupKLaws[F[_]] { implicit def F: SemigroupK[F] diff --git a/laws/src/main/scala/cats/laws/SemigroupalLaws.scala b/laws/src/main/scala/cats/laws/SemigroupalLaws.scala index 59cdbc363f9..a1d31965566 100644 --- a/laws/src/main/scala/cats/laws/SemigroupalLaws.scala +++ b/laws/src/main/scala/cats/laws/SemigroupalLaws.scala @@ -2,8 +2,8 @@ package cats package laws /** - * Laws that must be obeyed by any `cats.Semigroupal`. - */ + * Laws that must be obeyed by any `cats.Semigroupal`. + */ trait SemigroupalLaws[F[_]] { implicit def F: Semigroupal[F] diff --git a/laws/src/main/scala/cats/laws/StrongLaws.scala b/laws/src/main/scala/cats/laws/StrongLaws.scala index 82a66d317e8..069d91a530c 100644 --- a/laws/src/main/scala/cats/laws/StrongLaws.scala +++ b/laws/src/main/scala/cats/laws/StrongLaws.scala @@ -7,15 +7,19 @@ import cats.syntax.strong._ import cats.instances.function._ /** - * Laws that must be obeyed by any `cats.functor.Strong`. - */ + * Laws that must be obeyed by any `cats.functor.Strong`. + */ trait StrongLaws[F[_, _]] extends ProfunctorLaws[F] { implicit override def F: Strong[F] - def strongFirstDistributivity[A0, A1, B1, B2, C](fab: F[A1, B1], f: A0 => A1, g: B1 => B2): IsEq[F[(A0, C), (B2, C)]] = + def strongFirstDistributivity[A0, A1, B1, B2, C](fab: F[A1, B1], + f: A0 => A1, + g: B1 => B2): IsEq[F[(A0, C), (B2, C)]] = fab.dimap(f)(g).first[C] <-> fab.first[C].dimap(f.first[C])(g.first[C]) - def strongSecondDistributivity[A0, A1, B1, B2, C](fab: F[A1, B1], f: A0 => A1, g: B1 => B2): IsEq[F[(C, A0), (C, B2)]] = + def strongSecondDistributivity[A0, A1, B1, B2, C](fab: F[A1, B1], + f: A0 => A1, + g: B1 => B2): IsEq[F[(C, A0), (C, B2)]] = fab.dimap(f)(g).second[C] <-> fab.second[C].dimap(f.second[C])(g.second[C]) } diff --git a/laws/src/main/scala/cats/laws/TraverseFilterLaws.scala b/laws/src/main/scala/cats/laws/TraverseFilterLaws.scala index bd799fa8f67..d3c093c8385 100644 --- a/laws/src/main/scala/cats/laws/TraverseFilterLaws.scala +++ b/laws/src/main/scala/cats/laws/TraverseFilterLaws.scala @@ -8,31 +8,25 @@ import cats.instances.option._ trait TraverseFilterLaws[F[_]] extends FunctorFilterLaws[F] { implicit override def F: TraverseFilter[F] - def traverseFilterIdentity[G[_]: Applicative, A](fa: F[A]): IsEq[G[F[A]]] = { + def traverseFilterIdentity[G[_]: Applicative, A](fa: F[A]): IsEq[G[F[A]]] = fa.traverseFilter(_.some.pure[G]) <-> fa.pure[G] - } - def traverseFilterConsistentWithTraverse[G[_]: Applicative, A](fa: F[A], f: A => G[A]): IsEq[G[F[A]]] = { + def traverseFilterConsistentWithTraverse[G[_]: Applicative, A](fa: F[A], f: A => G[A]): IsEq[G[F[A]]] = fa.traverseFilter(a => f(a).map(_.some)) <-> F.traverse.traverse(fa)(f) - } - def traverseFilterComposition[A, B, C, M[_], N[_]](fa: F[A], - f: A => M[Option[B]], - g: B => N[Option[C]] - )(implicit - M: Applicative[M], - N: Applicative[N] - ): IsEq[Nested[M, N, F[C]]] = { + def traverseFilterComposition[A, B, C, M[_], N[_]](fa: F[A], f: A => M[Option[B]], g: B => N[Option[C]])( + implicit + M: Applicative[M], + N: Applicative[N] + ): IsEq[Nested[M, N, F[C]]] = { val lhs = Nested[M, N, F[C]](fa.traverseFilter(f).map(_.traverseFilter(g))) - val rhs: Nested[M, N, F[C]] = fa.traverseFilter[Nested[M, N, ?], C](a => - Nested[M, N, Option[C]](f(a).map(_.traverseFilter(g))) - ) + val rhs: Nested[M, N, F[C]] = + fa.traverseFilter[Nested[M, N, ?], C](a => Nested[M, N, Option[C]](f(a).map(_.traverseFilter(g)))) lhs <-> rhs } - def filterAConsistentWithTraverseFilter[G[_]: Applicative, A](fa: F[A], f: A => G[Boolean]): IsEq[G[F[A]]] = { + def filterAConsistentWithTraverseFilter[G[_]: Applicative, A](fa: F[A], f: A => G[Boolean]): IsEq[G[F[A]]] = fa.filterA(f) <-> fa.traverseFilter(a => f(a).map(if (_) Some(a) else None)) - } } object TraverseFilterLaws { diff --git a/laws/src/main/scala/cats/laws/TraverseLaws.scala b/laws/src/main/scala/cats/laws/TraverseLaws.scala index e796b9070ca..2658928dbf3 100644 --- a/laws/src/main/scala/cats/laws/TraverseLaws.scala +++ b/laws/src/main/scala/cats/laws/TraverseLaws.scala @@ -9,9 +9,8 @@ import cats.syntax.foldable._ trait TraverseLaws[F[_]] extends FunctorLaws[F] with FoldableLaws[F] with UnorderedTraverseLaws[F] { implicit override def F: Traverse[F] - def traverseIdentity[A, B](fa: F[A], f: A => B): IsEq[F[B]] = { + def traverseIdentity[A, B](fa: F[A], f: A => B): IsEq[F[B]] = fa.traverse[Id, B](f) <-> F.map(fa)(f) - } def traverseSequentialComposition[A, B, C, M[_], N[_]]( fa: F[A], @@ -19,8 +18,7 @@ trait TraverseLaws[F[_]] extends FunctorLaws[F] with FoldableLaws[F] with Unorde g: B => N[C] )(implicit N: Applicative[N], - M: Applicative[M] - ): IsEq[Nested[M, N, F[C]]] = { + M: Applicative[M]): IsEq[Nested[M, N, F[C]]] = { val lhs = Nested(M.map(fa.traverse(f))(fb => fb.traverse(g))) val rhs = fa.traverse[Nested[M, N, ?], C](a => Nested(M.map(f(a))(g))) @@ -33,8 +31,7 @@ trait TraverseLaws[F[_]] extends FunctorLaws[F] with FoldableLaws[F] with Unorde g: A => N[B] )(implicit N: Applicative[N], - M: Applicative[M] - ): IsEq[(M[F[B]], N[F[B]])] = { + M: Applicative[M]): IsEq[(M[F[B]], N[F[B]])] = { type MN[Z] = (M[Z], N[Z]) implicit val MN = new Applicative[MN] { def pure[X](x: X): MN[X] = (M.pure(x), N.pure(x)) @@ -79,23 +76,24 @@ trait TraverseLaws[F[_]] extends FunctorLaws[F] with FoldableLaws[F] with Unorde def store[T](a: T): Const[FirstOption[T], T] = Const(new FirstOption(Some(a))) val first = F.traverse[Const[FirstOption[A], ?], A, A](fa)(store).getConst.o - val traverseFirst = F.traverse[Const[FirstOption[A], ?], A, A]( - F.traverse(fa)(liftId) - )(store).getConst.o + val traverseFirst = F + .traverse[Const[FirstOption[A], ?], A, A]( + F.traverse(fa)(liftId) + )(store) + .getConst + .o first <-> traverseFirst } def mapWithIndexRef[A, B](fa: F[A], f: (A, Int) => B): IsEq[F[B]] = { val lhs = F.mapWithIndex(fa)(f) - val rhs = F.traverse(fa)(a => - State((s: Int) => (s + 1, f(a, s)))).runA(0).value + val rhs = F.traverse(fa)(a => State((s: Int) => (s + 1, f(a, s)))).runA(0).value lhs <-> rhs } def traverseWithIndexMRef[G[_], A, B](fa: F[A], f: (A, Int) => G[B])(implicit G: Monad[G]): IsEq[G[F[B]]] = { val lhs = F.traverseWithIndexM(fa)(f) - val rhs = F.traverse(fa)(a => - StateT((s: Int) => G.map(f(a, s))(b => (s + 1, b)))).runA(0) + val rhs = F.traverse(fa)(a => StateT((s: Int) => G.map(f(a, s))(b => (s + 1, b)))).runA(0) lhs <-> rhs } diff --git a/laws/src/main/scala/cats/laws/UnorderedFoldableLaws.scala b/laws/src/main/scala/cats/laws/UnorderedFoldableLaws.scala index ee98a977089..78b003aac33 100644 --- a/laws/src/main/scala/cats/laws/UnorderedFoldableLaws.scala +++ b/laws/src/main/scala/cats/laws/UnorderedFoldableLaws.scala @@ -9,24 +9,21 @@ trait UnorderedFoldableLaws[F[_]] { def unorderedFoldConsistentWithUnorderedFoldMap[A: CommutativeMonoid](fa: F[A]): IsEq[A] = F.unorderedFoldMap(fa)(identity) <-> F.unorderedFold(fa) - - - def forallConsistentWithExists[A](fa: F[A], p: A => Boolean): Boolean = { + def forallConsistentWithExists[A](fa: F[A], p: A => Boolean): Boolean = if (F.forall(fa)(p)) { val negationExists = F.exists(fa)(a => !(p(a))) // if p is true for all elements, then there cannot be an element for which // it does not hold. !negationExists && - // if p is true for all elements, then either there must be no elements - // or there must exist an element for which it is true. - (F.isEmpty(fa) || F.exists(fa)(p)) + // if p is true for all elements, then either there must be no elements + // or there must exist an element for which it is true. + (F.isEmpty(fa) || F.exists(fa)(p)) } else true // can't test much in this case - } def existsLazy[A](fa: F[A]): Boolean = { var i = 0 - F.exists(fa){ _ => + F.exists(fa) { _ => i = i + 1 true } @@ -35,7 +32,7 @@ trait UnorderedFoldableLaws[F[_]] { def forallLazy[A](fa: F[A]): Boolean = { var i = 0 - F.forall(fa){ _ => + F.forall(fa) { _ => i = i + 1 false } @@ -45,10 +42,8 @@ trait UnorderedFoldableLaws[F[_]] { /** * If `F[A]` is empty, forall must return true. */ - def forallEmpty[A](fa: F[A], p: A => Boolean): Boolean = { + def forallEmpty[A](fa: F[A], p: A => Boolean): Boolean = !F.isEmpty(fa) || F.forall(fa)(p) - } - def nonEmptyRef[A](fa: F[A]): IsEq[Boolean] = F.nonEmpty(fa) <-> !F.isEmpty(fa) diff --git a/laws/src/main/scala/cats/laws/UnorderedTraverseLaws.scala b/laws/src/main/scala/cats/laws/UnorderedTraverseLaws.scala index 0841f4255b3..0ec264284b6 100644 --- a/laws/src/main/scala/cats/laws/UnorderedTraverseLaws.scala +++ b/laws/src/main/scala/cats/laws/UnorderedTraverseLaws.scala @@ -7,26 +7,22 @@ trait UnorderedTraverseLaws[F[_]] extends UnorderedFoldableLaws[F] { implicit def F: UnorderedTraverse[F] def unorderedTraverseIdentity[A, B](fa: F[A])(f: A => B)(implicit ev: Functor[F]): IsEq[F[B]] = - F.unorderedTraverse[Id, A, B](fa)(f) <-> (ev.map(fa)(f)) + F.unorderedTraverse[Id, A, B](fa)(f) <-> (ev.map(fa)(f)) - def unorderedTraverseSequentialComposition[A, B, C, M[_], N[_]] - (fa: F[A], - f: A => M[B], - g: B => N[C]) - (implicit N: CommutativeApplicative[N], - M: CommutativeApplicative[M]): IsEq[Nested[M, N, F[C]]] = { + def unorderedTraverseSequentialComposition[A, B, C, M[_], N[_]](fa: F[A], f: A => M[B], g: B => N[C])( + implicit N: CommutativeApplicative[N], + M: CommutativeApplicative[M] + ): IsEq[Nested[M, N, F[C]]] = { val lhs = Nested(M.map(F.unorderedTraverse(fa)(f))(fb => F.unorderedTraverse(fb)(g))) val rhs = F.unorderedTraverse[Nested[M, N, ?], A, C](fa)(a => Nested(M.map(f(a))(g))) lhs <-> rhs } - def unorderedTraverseParallelComposition[A, B, M[_], N[_]] - (fa: F[A], - f: A => M[B], - g: A => N[B]) - (implicit N: CommutativeApplicative[N], - M: CommutativeApplicative[M]): IsEq[(M[F[B]], N[F[B]])] = { + def unorderedTraverseParallelComposition[A, B, M[_], N[_]](fa: F[A], f: A => M[B], g: A => N[B])( + implicit N: CommutativeApplicative[N], + M: CommutativeApplicative[M] + ): IsEq[(M[F[B]], N[F[B]])] = { type MN[Z] = (M[Z], N[Z]) implicit val MN = new CommutativeApplicative[MN] { diff --git a/laws/src/main/scala/cats/laws/discipline/AlternativeTests.scala b/laws/src/main/scala/cats/laws/discipline/AlternativeTests.scala index 832ad97efb5..848710a2dd2 100644 --- a/laws/src/main/scala/cats/laws/discipline/AlternativeTests.scala +++ b/laws/src/main/scala/cats/laws/discipline/AlternativeTests.scala @@ -6,24 +6,23 @@ import cats.laws.discipline.SemigroupalTests.Isomorphisms import org.scalacheck.{Arbitrary, Cogen, Prop} import Prop._ -trait AlternativeTests[F[_]] extends ApplicativeTests[F] with MonoidKTests[F] { +trait AlternativeTests[F[_]] extends ApplicativeTests[F] with MonoidKTests[F] { def laws: AlternativeLaws[F] def alternative[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]], - CogenA: Cogen[A], - CogenB: Cogen[B], - CogenC: Cogen[C], - EqFA: Eq[F[A]], - EqFB: Eq[F[B]], - EqFC: Eq[F[C]], - EqFABC: Eq[F[(A, B, C)]], - iso: Isomorphisms[F] - ): RuleSet = { + ArbFA: Arbitrary[F[A]], + ArbFB: Arbitrary[F[B]], + ArbFC: Arbitrary[F[C]], + ArbFAtoB: Arbitrary[F[A => B]], + ArbFBtoC: Arbitrary[F[B => C]], + CogenA: Cogen[A], + CogenB: Cogen[B], + CogenC: Cogen[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 { val name: String = "alternative" val bases: Seq[(String, RuleSet)] = Nil @@ -34,7 +33,6 @@ trait AlternativeTests[F[_]] extends ApplicativeTests[F] with MonoidKTests[F] { "right absorption" -> forAll(laws.alternativeRightAbsorption[A, B] _) ) } -} } diff --git a/laws/src/main/scala/cats/laws/discipline/ApplicativeErrorTests.scala b/laws/src/main/scala/cats/laws/discipline/ApplicativeErrorTests.scala index 6edc466d0b6..e417b0f5de7 100644 --- a/laws/src/main/scala/cats/laws/discipline/ApplicativeErrorTests.scala +++ b/laws/src/main/scala/cats/laws/discipline/ApplicativeErrorTests.scala @@ -12,27 +12,26 @@ trait ApplicativeErrorTests[F[_], E] extends ApplicativeTests[F] { def laws: ApplicativeErrorLaws[F, E] def applicativeError[A: Arbitrary: Eq, B: Arbitrary: Eq, C: Arbitrary: Eq](implicit - ArbFA: Arbitrary[F[A]], - ArbFB: Arbitrary[F[B]], - ArbFC: Arbitrary[F[C]], - ArbFU: Arbitrary[F[Unit]], - ArbFAtoB: Arbitrary[F[A => B]], - ArbFBtoC: Arbitrary[F[B => C]], - ArbE: Arbitrary[E], - CogenA: Cogen[A], - CogenB: Cogen[B], - CogenC: Cogen[C], - CogenE: Cogen[E], - EqFA: Eq[F[A]], - EqFB: Eq[F[B]], - EqFC: Eq[F[C]], - EqE: Eq[E], - EqFEitherEU: Eq[F[Either[E, Unit]]], - EqFEitherEA: Eq[F[Either[E, A]]], - EqEitherTFEA: Eq[EitherT[F, E, A]], - EqFABC: Eq[F[(A, B, C)]], - iso: Isomorphisms[F] - ): RuleSet = { + ArbFA: Arbitrary[F[A]], + ArbFB: Arbitrary[F[B]], + ArbFC: Arbitrary[F[C]], + ArbFU: Arbitrary[F[Unit]], + ArbFAtoB: Arbitrary[F[A => B]], + ArbFBtoC: Arbitrary[F[B => C]], + ArbE: Arbitrary[E], + CogenA: Cogen[A], + CogenB: Cogen[B], + CogenC: Cogen[C], + CogenE: Cogen[E], + EqFA: Eq[F[A]], + EqFB: Eq[F[B]], + EqFC: Eq[F[C]], + EqE: Eq[E], + EqFEitherEU: Eq[F[Either[E, Unit]]], + EqFEitherEA: Eq[F[Either[E, A]]], + EqEitherTFEA: Eq[EitherT[F, E, A]], + EqFABC: Eq[F[(A, B, C)]], + iso: Isomorphisms[F]): RuleSet = new RuleSet { def name: String = "applicativeError" def bases: Seq[(String, RuleSet)] = Nil @@ -44,16 +43,19 @@ trait ApplicativeErrorTests[F[_], E] extends ApplicativeTests[F] { "applicativeError handleError pure" -> forAll(laws.handleErrorPure[A] _), "applicativeError raiseError attempt" -> forAll(laws.raiseErrorAttempt _), "applicativeError pure attempt" -> forAll(laws.pureAttempt[A] _), - "applicativeError handleErrorWith consistent with recoverWith" -> forAll(laws.handleErrorWithConsistentWithRecoverWith[A] _), + "applicativeError handleErrorWith consistent with recoverWith" -> forAll( + laws.handleErrorWithConsistentWithRecoverWith[A] _ + ), "applicativeError handleError consistent with recover" -> forAll(laws.handleErrorConsistentWithRecover[A] _), "applicativeError recover consistent with recoverWith" -> forAll(laws.recoverConsistentWithRecoverWith[A] _), "applicativeError attempt consistent with attemptT" -> forAll(laws.attemptConsistentWithAttemptT[A] _), - "applicativeError attempt fromEither consistent with pure" -> forAll(laws.attemptFromEitherConsistentWithPure[A] _), + "applicativeError attempt fromEither consistent with pure" -> forAll( + laws.attemptFromEitherConsistentWithPure[A] _ + ), "applicativeError onError pure" -> forAll(laws.onErrorPure[A] _), "applicativeError onError raise" -> forAll(laws.onErrorRaise[A] _) ) } - } } object ApplicativeErrorTests { diff --git a/laws/src/main/scala/cats/laws/discipline/ApplicativeTests.scala b/laws/src/main/scala/cats/laws/discipline/ApplicativeTests.scala index e7990de5172..62852aad980 100644 --- a/laws/src/main/scala/cats/laws/discipline/ApplicativeTests.scala +++ b/laws/src/main/scala/cats/laws/discipline/ApplicativeTests.scala @@ -10,20 +10,19 @@ trait ApplicativeTests[F[_]] extends ApplyTests[F] { def laws: ApplicativeLaws[F] def applicative[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]], - CogenA: Cogen[A], - CogenB: Cogen[B], - CogenC: Cogen[C], - EqFA: Eq[F[A]], - EqFB: Eq[F[B]], - EqFC: Eq[F[C]], - EqFABC: Eq[F[(A, B, C)]], - iso: Isomorphisms[F] - ): RuleSet = { + ArbFA: Arbitrary[F[A]], + ArbFB: Arbitrary[F[B]], + ArbFC: Arbitrary[F[C]], + ArbFAtoB: Arbitrary[F[A => B]], + ArbFBtoC: Arbitrary[F[B => C]], + CogenA: Cogen[A], + CogenB: Cogen[B], + CogenC: Cogen[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 = "applicative", parent = Some(apply[A, B, C]), @@ -34,8 +33,8 @@ trait ApplicativeTests[F[_]] extends ApplyTests[F] { "applicative unit" -> forAll(laws.applicativeUnit[A] _), "ap consistent with product + map" -> forAll(laws.apProductConsistent[A, B] _), "monoidal left identity" -> forAll((fa: F[A]) => iso.leftIdentity(laws.monoidalLeftIdentity(fa))), - "monoidal right identity" -> forAll((fa: F[A]) => iso.rightIdentity(laws.monoidalRightIdentity(fa)))) - } + "monoidal right identity" -> forAll((fa: F[A]) => iso.rightIdentity(laws.monoidalRightIdentity(fa))) + ) } object ApplicativeTests { diff --git a/laws/src/main/scala/cats/laws/discipline/ApplyTests.scala b/laws/src/main/scala/cats/laws/discipline/ApplyTests.scala index 0d75d8a7031..2a43c3c4bef 100644 --- a/laws/src/main/scala/cats/laws/discipline/ApplyTests.scala +++ b/laws/src/main/scala/cats/laws/discipline/ApplyTests.scala @@ -10,19 +10,18 @@ trait ApplyTests[F[_]] extends FunctorTests[F] with SemigroupalTests[F] { def laws: ApplyLaws[F] def apply[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]], - CogenA: Cogen[A], - CogenB: Cogen[B], - CogenC: Cogen[C], - EqFA: Eq[F[A]], - EqFC: Eq[F[C]], - EqFABC: Eq[F[(A, B, C)]], - iso: Isomorphisms[F] - ): RuleSet = new RuleSet { + ArbFA: Arbitrary[F[A]], + ArbFB: Arbitrary[F[B]], + ArbFC: Arbitrary[F[C]], + ArbFAtoB: Arbitrary[F[A => B]], + ArbFBtoC: Arbitrary[F[B => C]], + CogenA: Cogen[A], + CogenB: Cogen[B], + CogenC: Cogen[C], + EqFA: Eq[F[A]], + EqFC: Eq[F[C]], + EqFABC: Eq[F[(A, B, C)]], + iso: Isomorphisms[F]): RuleSet = new RuleSet { val name = "apply" val parents = Seq(functor[A, B, C], semigroupal[A, B, C]) val bases = Seq.empty @@ -31,7 +30,8 @@ trait ApplyTests[F[_]] extends FunctorTests[F] with SemigroupalTests[F] { "map2/product-map consistency" -> forAll(laws.map2ProductConsistency[A, B, C] _), "map2/map2Eval consistency" -> forAll(laws.map2EvalConsistency[A, B, C] _), "productR consistent map2" -> forAll(laws.productRConsistency[A, C] _), - "productL consistent map2" -> forAll(laws.productLConsistency[A, C] _)) + "productL consistent map2" -> forAll(laws.productLConsistency[A, C] _) + ) } } diff --git a/laws/src/main/scala/cats/laws/discipline/Arbitrary.scala b/laws/src/main/scala/cats/laws/discipline/Arbitrary.scala index 80675a42970..4ea2691c728 100644 --- a/laws/src/main/scala/cats/laws/discipline/Arbitrary.scala +++ b/laws/src/main/scala/cats/laws/discipline/Arbitrary.scala @@ -11,8 +11,8 @@ import org.scalacheck.{Arbitrary, Cogen, Gen} import org.scalacheck.Arbitrary.{arbitrary => getArbitrary} /** - * Arbitrary instances for cats.data - */ + * Arbitrary instances for cats.data + */ object arbitrary extends ArbitraryInstances0 { // this instance is not available in scalacheck 1.13.2. @@ -23,10 +23,13 @@ object arbitrary extends ArbitraryInstances0 { // this instance is not available in scalacheck 1.13.2. // remove this once a newer version is available. implicit def catsLawsCogenForTry[A](implicit A: Cogen[A]): Cogen[Try[A]] = - Cogen((seed, x) => x match { - case Success(a) => A.perturb(seed, a) - case Failure(e) => Cogen[Throwable].perturb(seed, e) - }) + Cogen( + (seed, x) => + x match { + case Success(a) => A.perturb(seed, a) + case Failure(e) => Cogen[Throwable].perturb(seed, e) + } + ) // this instance is not available in scalacheck 1.13.2. // remove this once a newer version is available. @@ -39,7 +42,8 @@ object arbitrary extends ArbitraryInstances0 { implicit def catsLawsCogenForConst[A, B](implicit A: Cogen[A]): Cogen[Const[A, B]] = A.contramap(_.getConst) - implicit def catsLawsArbitraryForOneAnd[F[_], A](implicit A: Arbitrary[A], F: Arbitrary[F[A]]): Arbitrary[OneAnd[F, A]] = + implicit def catsLawsArbitraryForOneAnd[F[_], A](implicit A: Arbitrary[A], + F: Arbitrary[F[A]]): Arbitrary[OneAnd[F, A]] = Arbitrary(F.arbitrary.flatMap(fa => A.arbitrary.map(a => OneAnd(a, fa)))) implicit def catsLawsCogenForOneAnd[F[_], A](implicit A: Cogen[A], F: Cogen[F[A]]): Cogen[OneAnd[F, A]] = @@ -52,8 +56,7 @@ object arbitrary extends ArbitraryInstances0 { Cogen[Vector[A]].contramap(_.toVector) implicit def catsLawsArbitraryForNonEmptySet[A: Order](implicit A: Arbitrary[A]): Arbitrary[NonEmptySet[A]] = - Arbitrary(implicitly[Arbitrary[SortedSet[A]]].arbitrary.flatMap(fa => - A.arbitrary.map(a => NonEmptySet(a, fa)))) + Arbitrary(implicitly[Arbitrary[SortedSet[A]]].arbitrary.flatMap(fa => A.arbitrary.map(a => NonEmptySet(a, fa)))) implicit def catsLawsCogenForNonEmptySet[A: Order: Cogen]: Cogen[NonEmptySet[A]] = Cogen[SortedSet[A]].contramap(_.toSortedSet) @@ -79,7 +82,7 @@ object arbitrary extends ArbitraryInstances0 { implicit def catsLawsArbitraryForNonEmptyChain[A](implicit A: Arbitrary[A]): Arbitrary[NonEmptyChain[A]] = Arbitrary(implicitly[Arbitrary[Chain[A]]].arbitrary.flatMap { chain => NonEmptyChain.fromChain(chain) match { - case None => A.arbitrary.map(NonEmptyChain.one) + case None => A.arbitrary.map(NonEmptyChain.one) case Some(ne) => Gen.const(ne) } }) @@ -87,7 +90,6 @@ object arbitrary extends ArbitraryInstances0 { implicit def catsLawsCogenForNonEmptyChain[A](implicit A: Cogen[A]): Cogen[NonEmptyChain[A]] = Cogen[Chain[A]].contramap(_.toChain) - implicit def catsLawsArbitraryForZipNonEmptyList[A](implicit A: Arbitrary[A]): Arbitrary[ZipNonEmptyList[A]] = Arbitrary(implicitly[Arbitrary[NonEmptyList[A]]].arbitrary.map(nel => new ZipNonEmptyList(nel))) @@ -98,29 +100,31 @@ object arbitrary extends ArbitraryInstances0 { a <- A.arbitrary } yield NonEmptyMap((k, a), fa)) - implicit def cogenNonEmptyMap[K: Order : Cogen, A: Order : Cogen]: Cogen[NonEmptyMap[K, A]] = + implicit def cogenNonEmptyMap[K: Order: Cogen, A: Order: Cogen]: Cogen[NonEmptyMap[K, A]] = Cogen[SortedMap[K, A]].contramap(_.toSortedMap) - implicit def catsLawsArbitraryForEitherT[F[_], A, B](implicit F: Arbitrary[F[Either[A, B]]]): Arbitrary[EitherT[F, A, B]] = + implicit def catsLawsArbitraryForEitherT[F[_], A, B]( + implicit F: Arbitrary[F[Either[A, B]]] + ): Arbitrary[EitherT[F, A, B]] = Arbitrary(F.arbitrary.map(EitherT(_))) implicit def catsLawsCogenForEitherT[F[_], A, B](implicit F: Cogen[F[Either[A, B]]]): Cogen[EitherT[F, A, B]] = F.contramap(_.value) - implicit def catsLawsArbitraryForValidated[A, B](implicit A: Arbitrary[A], B: Arbitrary[B]): Arbitrary[Validated[A, B]] = + implicit def catsLawsArbitraryForValidated[A, B](implicit A: Arbitrary[A], + B: Arbitrary[B]): Arbitrary[Validated[A, B]] = Arbitrary(Gen.oneOf(A.arbitrary.map(Validated.invalid), B.arbitrary.map(Validated.valid))) implicit def catsLawsCogenForValidated[A, B](implicit A: Cogen[A], B: Cogen[B]): Cogen[Validated[A, B]] = Cogen((seed, x) => x.fold(A.perturb(seed, _), B.perturb(seed, _))) implicit def catsLawsArbitraryForIor[A, B](implicit A: Arbitrary[A], B: Arbitrary[B]): Arbitrary[A Ior B] = - Arbitrary(Gen.oneOf(A.arbitrary.map(Ior.left), B.arbitrary.map(Ior.right), for { a <- A.arbitrary; b <- B.arbitrary } yield Ior.both(a, b))) + Arbitrary(Gen.oneOf(A.arbitrary.map(Ior.left), B.arbitrary.map(Ior.right), for { + a <- A.arbitrary; b <- B.arbitrary + } yield Ior.both(a, b))) implicit def catsLawsCogenForIor[A, B](implicit A: Cogen[A], B: Cogen[B]): Cogen[A Ior B] = - Cogen((seed, x) => x.fold( - A.perturb(seed, _), - B.perturb(seed, _), - (a, b) => A.perturb(B.perturb(seed, b), a))) + Cogen((seed, x) => x.fold(A.perturb(seed, _), B.perturb(seed, _), (a, b) => A.perturb(B.perturb(seed, b), a))) implicit def catsLawsArbitraryForIorT[F[_], A, B](implicit F: Arbitrary[F[Ior[A, B]]]): Arbitrary[IorT[F, A, B]] = Arbitrary(F.arbitrary.map(IorT(_))) @@ -141,39 +145,48 @@ object arbitrary extends ArbitraryInstances0 { F.contramap(_.value) implicit def catsLawsArbitraryForEval[A: Arbitrary]: Arbitrary[Eval[A]] = - Arbitrary(Gen.oneOf( - getArbitrary[A].map(a => Eval.now(a)), - getArbitrary[() => A].map(f => Eval.later(f())), - getArbitrary[() => A].map(f => Eval.always(f())))) + Arbitrary( + Gen.oneOf(getArbitrary[A].map(a => Eval.now(a)), + getArbitrary[() => A].map(f => Eval.later(f())), + getArbitrary[() => A].map(f => Eval.always(f()))) + ) implicit def catsLawsCogenForEval[A: Cogen]: Cogen[Eval[A]] = Cogen[A].contramap(_.value) - implicit def catsLawsArbitraryForTuple2K[F[_], G[_], A](implicit F: Arbitrary[F[A]], G: Arbitrary[G[A]]): Arbitrary[Tuple2K[F, G, A]] = + implicit def catsLawsArbitraryForTuple2K[F[_], G[_], A](implicit F: Arbitrary[F[A]], + G: Arbitrary[G[A]]): Arbitrary[Tuple2K[F, G, A]] = Arbitrary(F.arbitrary.flatMap(fa => G.arbitrary.map(ga => Tuple2K[F, G, A](fa, ga)))) - implicit def catsLawsArbitraryForFunc[F[_], A, B](implicit AA: Arbitrary[A], CA: Cogen[A], F: Arbitrary[F[B]]): Arbitrary[Func[F, A, B]] = + implicit def catsLawsArbitraryForFunc[F[_], A, B](implicit AA: Arbitrary[A], + CA: Cogen[A], + F: Arbitrary[F[B]]): Arbitrary[Func[F, A, B]] = Arbitrary(Arbitrary.arbitrary[A => F[B]].map(Func.func)) - implicit def catsLawsArbitraryForAppFunc[F[_], A, B](implicit AA: Arbitrary[A], CA: Cogen[A], F: Arbitrary[F[B]], FF: Applicative[F]): Arbitrary[AppFunc[F, A, B]] = + implicit def catsLawsArbitraryForAppFunc[F[_], A, B](implicit AA: Arbitrary[A], + CA: Cogen[A], + F: Arbitrary[F[B]], + FF: Applicative[F]): Arbitrary[AppFunc[F, A, B]] = Arbitrary(Arbitrary.arbitrary[A => F[B]].map(Func.appFunc(_))) - implicit def catsLawsArbitraryForWriter[L:Arbitrary, V:Arbitrary]: Arbitrary[Writer[L, V]] = + implicit def catsLawsArbitraryForWriter[L: Arbitrary, V: Arbitrary]: Arbitrary[Writer[L, V]] = catsLawsArbitraryForWriterT[Id, L, V] implicit def catsLawsCogenForWriter[L: Cogen, V: Cogen]: Cogen[Writer[L, V]] = Cogen[(L, V)].contramap(_.run) // until this is provided by scalacheck - implicit def catsLawsArbitraryForPartialFunction[A, B](implicit F: Arbitrary[A => Option[B]]): Arbitrary[PartialFunction[A, B]] = + implicit def catsLawsArbitraryForPartialFunction[A, B]( + implicit F: Arbitrary[A => Option[B]] + ): Arbitrary[PartialFunction[A, B]] = Arbitrary(F.arbitrary.map(Function.unlift)) - implicit def catsLawsArbitraryForEitherK[F[_], G[_], A](implicit F: Arbitrary[F[A]], G: Arbitrary[G[A]]): Arbitrary[EitherK[F, G, A]] = - Arbitrary(Gen.oneOf( - F.arbitrary.map(EitherK.leftc[F, G, A]), - G.arbitrary.map(EitherK.rightc[F, G, A]))) + implicit def catsLawsArbitraryForEitherK[F[_], G[_], A](implicit F: Arbitrary[F[A]], + G: Arbitrary[G[A]]): Arbitrary[EitherK[F, G, A]] = + Arbitrary(Gen.oneOf(F.arbitrary.map(EitherK.leftc[F, G, A]), G.arbitrary.map(EitherK.rightc[F, G, A]))) - implicit def catsLawsCogenForEitherK[F[_], G[_], A](implicit F: Cogen[F[A]], G: Cogen[G[A]]): Cogen[EitherK[F, G, A]] = + implicit def catsLawsCogenForEitherK[F[_], G[_], A](implicit F: Cogen[F[A]], + G: Cogen[G[A]]): Cogen[EitherK[F, G, A]] = Cogen((seed, x) => x.run.fold(F.perturb(seed, _), G.perturb(seed, _))) implicit def catLawsCogenForTuple2K[F[_], G[_], A](implicit F: Cogen[F[A]], G: Cogen[G[A]]): Cogen[Tuple2K[F, G, A]] = @@ -190,26 +203,41 @@ object arbitrary extends ArbitraryInstances0 { // implies equal, in order to avoid producing invalid instances. implicit def catsLawsArbitraryForEq[A: Arbitrary]: Arbitrary[Eq[A]] = - Arbitrary(getArbitrary[Int => Int].map(f => new Eq[A] { - def eqv(x: A, y: A): Boolean = f(x.##) == f(y.##) - })) + Arbitrary( + getArbitrary[Int => Int].map( + f => + new Eq[A] { + def eqv(x: A, y: A): Boolean = f(x.##) == f(y.##) + } + ) + ) implicit def catsLawsArbitraryForEquiv[A: Arbitrary]: Arbitrary[Equiv[A]] = Arbitrary(getArbitrary[Eq[A]].map(Eq.catsKernelEquivForEq(_))) implicit def catsLawsArbitraryForPartialOrder[A: Arbitrary]: Arbitrary[PartialOrder[A]] = - Arbitrary(getArbitrary[Int => Double].map(f => new PartialOrder[A] { - def partialCompare(x: A, y: A): Double = - if (x.## == y.##) 0.0 else f(x.##) - f(y.##) - })) + Arbitrary( + getArbitrary[Int => Double].map( + f => + new PartialOrder[A] { + def partialCompare(x: A, y: A): Double = + if (x.## == y.##) 0.0 else f(x.##) - f(y.##) + } + ) + ) implicit def catsLawsArbitraryForPartialOrdering[A: Arbitrary]: Arbitrary[PartialOrdering[A]] = Arbitrary(getArbitrary[PartialOrder[A]].map(PartialOrder.catsKernelPartialOrderingForPartialOrder(_))) implicit def catsLawsArbitraryForOrder[A: Arbitrary]: Arbitrary[Order[A]] = - Arbitrary(getArbitrary[Int => Int].map(f => new Order[A] { - def compare(x: A, y: A): Int = java.lang.Integer.compare(f(x.##), f(y.##)) - })) + Arbitrary( + getArbitrary[Int => Int].map( + f => + new Order[A] { + def compare(x: A, y: A): Int = java.lang.Integer.compare(f(x.##), f(y.##)) + } + ) + ) implicit def catsLawsArbitraryForSortedMap[K: Arbitrary: Order, V: Arbitrary]: Arbitrary[SortedMap[K, V]] = Arbitrary(getArbitrary[Map[K, V]].map(s => SortedMap.empty[K, V](implicitly[Order[K]].toOrdering) ++ s)) @@ -239,7 +267,9 @@ object arbitrary extends ArbitraryInstances0 { implicit def catsLawsArbitraryForNested[F[_], G[_], A](implicit FG: Arbitrary[F[G[A]]]): Arbitrary[Nested[F, G, A]] = Arbitrary(FG.arbitrary.map(Nested(_))) - implicit def catsLawsArbitraryForBinested[F[_, _], G[_], H[_], A, B](implicit F: Arbitrary[F[G[A], H[B]]]): Arbitrary[Binested[F, G, H, A, B]] = + implicit def catsLawsArbitraryForBinested[F[_, _], G[_], H[_], A, B]( + implicit F: Arbitrary[F[G[A], H[B]]] + ): Arbitrary[Binested[F, G, H, A, B]] = Arbitrary(F.arbitrary.map(Binested(_))) implicit def catsLawArbitraryForState[S: Arbitrary: Cogen, A: Arbitrary]: Arbitrary[State[S, A]] = @@ -257,16 +287,18 @@ object arbitrary extends ArbitraryInstances0 { implicit def catsLawsCogenForOp[Arr[_, _], A, B](implicit Arr: Cogen[Arr[B, A]]): Cogen[Op[Arr, A, B]] = Arr.contramap(_.run) - implicit def catsLawsArbitraryForIRWST[F[_]: Applicative, E, L, SA, SB, A](implicit - F: Arbitrary[(E, SA) => F[(L, SB, A)]]): Arbitrary[IndexedReaderWriterStateT[F, E, L, SA, SB, A]] = + implicit def catsLawsArbitraryForIRWST[F[_]: Applicative, E, L, SA, SB, A]( + implicit + F: Arbitrary[(E, SA) => F[(L, SB, A)]] + ): Arbitrary[IndexedReaderWriterStateT[F, E, L, SA, SB, A]] = Arbitrary(F.arbitrary.map(IndexedReaderWriterStateT(_))) - - implicit def catsLawsArbitraryForRepresentableStore[F[_], S, A](implicit + implicit def catsLawsArbitraryForRepresentableStore[F[_], S, A]( + implicit R: Representable.Aux[F, S], ArbS: Arbitrary[S], ArbFA: Arbitrary[F[A]] - ): Arbitrary[RepresentableStore[F, S, A]] = { + ): Arbitrary[RepresentableStore[F, S, A]] = Arbitrary { for { fa <- ArbFA.arbitrary @@ -275,11 +307,11 @@ object arbitrary extends ArbitraryInstances0 { RepresentableStore[F, S, A](fa, s) } } - } - implicit def catsLawsCogenForRepresentableStore[F[_]: Representable, S, A](implicit CA: Cogen[A]): Cogen[RepresentableStore[F, S, A]] = { + implicit def catsLawsCogenForRepresentableStore[F[_]: Representable, S, A]( + implicit CA: Cogen[A] + ): Cogen[RepresentableStore[F, S, A]] = CA.contramap(_.extract) - } implicit def catsLawsArbitraryForAndThen[A, B](implicit F: Arbitrary[A => B]): Arbitrary[AndThen[A, B]] = Arbitrary(F.arbitrary.map(AndThen(_))) @@ -299,7 +331,7 @@ object arbitrary extends ArbitraryInstances0 { case n => // Here we concat two chains for { - n0 <- Gen.choose(1, n-1) + n0 <- Gen.choose(1, n - 1) n1 = n - n0 left <- genSize(n0) right <- genSize(n1) @@ -319,9 +351,11 @@ object arbitrary extends ArbitraryInstances0 { } -private[discipline] sealed trait ArbitraryInstances0 { +sealed private[discipline] trait ArbitraryInstances0 { - implicit def catsLawArbitraryForIndexedStateT[F[_], SA, SB, A](implicit F: Arbitrary[F[SA => F[(SB, A)]]]): Arbitrary[IndexedStateT[F, SA, SB, A]] = + implicit def catsLawArbitraryForIndexedStateT[F[_], SA, SB, A]( + implicit F: Arbitrary[F[SA => F[(SB, A)]]] + ): Arbitrary[IndexedStateT[F, SA, SB, A]] = Arbitrary(F.arbitrary.map(IndexedStateT.applyF)) implicit def catsLawsArbitraryForWriterT[F[_], L, V](implicit F: Arbitrary[F[(L, V)]]): Arbitrary[WriterT[F, L, V]] = @@ -330,9 +364,13 @@ private[discipline] sealed trait ArbitraryInstances0 { implicit def catsLawsCogenForWriterT[F[_], L, V](implicit F: Cogen[F[(L, V)]]): Cogen[WriterT[F, L, V]] = F.contramap(_.run) - implicit def catsLawsArbitraryForKleisli[F[_], A, B](implicit AA: Arbitrary[A], CA: Cogen[A], F: Arbitrary[F[B]]): Arbitrary[Kleisli[F, A, B]] = + implicit def catsLawsArbitraryForKleisli[F[_], A, B](implicit AA: Arbitrary[A], + CA: Cogen[A], + F: Arbitrary[F[B]]): Arbitrary[Kleisli[F, A, B]] = Arbitrary(Arbitrary.arbitrary[A => F[B]].map(Kleisli(_))) - implicit def catsLawsArbitraryForCokleisli[F[_], A, B](implicit AFA: Arbitrary[F[A]], CFA: Cogen[F[A]], B: Arbitrary[B]): Arbitrary[Cokleisli[F, A, B]] = + implicit def catsLawsArbitraryForCokleisli[F[_], A, B](implicit AFA: Arbitrary[F[A]], + CFA: Cogen[F[A]], + B: Arbitrary[B]): Arbitrary[Cokleisli[F, A, B]] = Arbitrary(Arbitrary.arbitrary[F[A] => B].map(Cokleisli(_))) } diff --git a/laws/src/main/scala/cats/laws/discipline/ArrowChoiceTests.scala b/laws/src/main/scala/cats/laws/discipline/ArrowChoiceTests.scala index 8a2c61f181f..234ef9889a7 100644 --- a/laws/src/main/scala/cats/laws/discipline/ArrowChoiceTests.scala +++ b/laws/src/main/scala/cats/laws/discipline/ArrowChoiceTests.scala @@ -10,7 +10,8 @@ import Prop._ trait ArrowChoiceTests[F[_, _]] extends ArrowTests[F] with ChoiceTests[F] { def laws: ArrowChoiceLaws[F] - def arrowChoice[A: Arbitrary, B: Arbitrary, C: Arbitrary, D: Arbitrary, E: Arbitrary, G: Arbitrary](implicit + def arrowChoice[A: Arbitrary, B: Arbitrary, C: Arbitrary, D: Arbitrary, E: Arbitrary, G: Arbitrary]( + implicit ArbFAB: Arbitrary[F[A, B]], ArbFBC: Arbitrary[F[B, C]], ArbFAC: Arbitrary[F[A, C]], diff --git a/laws/src/main/scala/cats/laws/discipline/ArrowTests.scala b/laws/src/main/scala/cats/laws/discipline/ArrowTests.scala index 0f215cc706e..26db8bac4b2 100644 --- a/laws/src/main/scala/cats/laws/discipline/ArrowTests.scala +++ b/laws/src/main/scala/cats/laws/discipline/ArrowTests.scala @@ -9,7 +9,8 @@ import Prop._ trait ArrowTests[F[_, _]] extends CategoryTests[F] with StrongTests[F] { def laws: ArrowLaws[F] - def arrow[A: Arbitrary, B: Arbitrary, C: Arbitrary, D: Arbitrary, E: Arbitrary, G: Arbitrary](implicit + def arrow[A: Arbitrary, B: Arbitrary, C: Arbitrary, D: Arbitrary, E: Arbitrary, G: Arbitrary]( + implicit ArbFAB: Arbitrary[F[A, B]], ArbFBC: Arbitrary[F[B, C]], ArbFAC: Arbitrary[F[A, C]], diff --git a/laws/src/main/scala/cats/laws/discipline/BifoldableTests.scala b/laws/src/main/scala/cats/laws/discipline/BifoldableTests.scala index 2e391109f1d..c53e83db48d 100644 --- a/laws/src/main/scala/cats/laws/discipline/BifoldableTests.scala +++ b/laws/src/main/scala/cats/laws/discipline/BifoldableTests.scala @@ -10,10 +10,9 @@ trait BifoldableTests[F[_, _]] extends Laws { def laws: BifoldableLaws[F] def bifoldable[A: Arbitrary, B: Arbitrary, C: Arbitrary: Monoid: Eq](implicit - ArbFAB: Arbitrary[F[A, B]], - CogenA: Cogen[A], - CogenB: Cogen[B] - ): RuleSet = + ArbFAB: Arbitrary[F[A, B]], + CogenA: Cogen[A], + CogenB: Cogen[B]): RuleSet = new DefaultRuleSet( name = "bifoldable", parent = None, diff --git a/laws/src/main/scala/cats/laws/discipline/BifunctorTests.scala b/laws/src/main/scala/cats/laws/discipline/BifunctorTests.scala index 58b8bd4f8b7..a8f5c351198 100644 --- a/laws/src/main/scala/cats/laws/discipline/BifunctorTests.scala +++ b/laws/src/main/scala/cats/laws/discipline/BifunctorTests.scala @@ -10,16 +10,15 @@ trait BifunctorTests[F[_, _]] extends Laws { def laws: BifunctorLaws[F] def bifunctor[A, A2, A3, B, B2, B3](implicit - ArbFAB: Arbitrary[F[A, B]], - ArbA2: Arbitrary[A => A2], - ArbA3: Arbitrary[A2 => A3], - ArbB2: Arbitrary[B => B2], - ArbB3: Arbitrary[B2 => B3], - EqFAB: Eq[F[A, B]], - EqFCZ: Eq[F[A3, B3]], - EqFA3B: Eq[F[A3, B]], - EqFAB3: Eq[F[A, B3]] - ): RuleSet = { + ArbFAB: Arbitrary[F[A, B]], + ArbA2: Arbitrary[A => A2], + ArbA3: Arbitrary[A2 => A3], + ArbB2: Arbitrary[B => B2], + ArbB3: Arbitrary[B2 => B3], + EqFAB: Eq[F[A, B]], + EqFCZ: Eq[F[A3, B3]], + EqFA3B: Eq[F[A3, B]], + EqFAB3: Eq[F[A, B3]]): RuleSet = new DefaultRuleSet( name = "Bifunctor", parent = None, @@ -28,11 +27,10 @@ trait BifunctorTests[F[_, _]] extends Laws { "Bifunctor leftMap Identity" -> forAll(laws.bifunctorLeftMapIdentity[A, B] _), "Bifunctor leftMap associativity" -> forAll(laws.bifunctorLeftMapComposition[A, B, A2, A3] _) ) - } } object BifunctorTests { - def apply[F[_, _] : Bifunctor]: BifunctorTests[F] = + def apply[F[_, _]: Bifunctor]: BifunctorTests[F] = new BifunctorTests[F] { def laws: BifunctorLaws[F] = BifunctorLaws[F] } diff --git a/laws/src/main/scala/cats/laws/discipline/BimonadTests.scala b/laws/src/main/scala/cats/laws/discipline/BimonadTests.scala index a8f3dd21fc7..85e6713b3d1 100644 --- a/laws/src/main/scala/cats/laws/discipline/BimonadTests.scala +++ b/laws/src/main/scala/cats/laws/discipline/BimonadTests.scala @@ -10,26 +10,25 @@ trait BimonadTests[F[_]] extends MonadTests[F] with ComonadTests[F] { def laws: BimonadLaws[F] def bimonad[A: Arbitrary: Eq, B: Arbitrary: Eq, C: Arbitrary: Eq](implicit - ArbFA: Arbitrary[F[A]], - ArbFFA: Arbitrary[F[F[A]]], - ArbFB: Arbitrary[F[B]], - ArbFC: Arbitrary[F[C]], - ArbFAtoB: Arbitrary[F[A => B]], - ArbFBtoC: Arbitrary[F[B => C]], - CogenA: Cogen[A], - CogenB: Cogen[B], - CogenC: Cogen[C], - CogenFA: Cogen[F[A]], - CogenFB: Cogen[F[B]], - EqFFFA: Eq[F[F[A]]], - EqFFA: Eq[F[F[F[A]]]], - EqFA: Eq[F[A]], - EqFB: Eq[F[B]], - EqFC: Eq[F[C]], - EqFABC: Eq[F[(A, B, C)]], - EqFInt: Eq[F[Int]], - iso: Isomorphisms[F] - ): RuleSet = { + ArbFA: Arbitrary[F[A]], + ArbFFA: Arbitrary[F[F[A]]], + ArbFB: Arbitrary[F[B]], + ArbFC: Arbitrary[F[C]], + ArbFAtoB: Arbitrary[F[A => B]], + ArbFBtoC: Arbitrary[F[B => C]], + CogenA: Cogen[A], + CogenB: Cogen[B], + CogenC: Cogen[C], + CogenFA: Cogen[F[A]], + CogenFB: Cogen[F[B]], + EqFFFA: Eq[F[F[A]]], + EqFFA: Eq[F[F[F[A]]]], + EqFA: Eq[F[A]], + EqFB: Eq[F[B]], + EqFC: Eq[F[C]], + EqFABC: Eq[F[(A, B, C)]], + EqFInt: Eq[F[Int]], + iso: Isomorphisms[F]): RuleSet = new RuleSet { def name: String = "bimonad" def bases: Seq[(String, RuleSet)] = Nil @@ -40,7 +39,6 @@ trait BimonadTests[F[_]] extends MonadTests[F] with ComonadTests[F] { "pure/coflatMap entwining" -> forAll(laws.pureCoflatMapEntwining[A] _) ) } - } } object BimonadTests { diff --git a/laws/src/main/scala/cats/laws/discipline/BitraverseTests.scala b/laws/src/main/scala/cats/laws/discipline/BitraverseTests.scala index 706077f7a9e..a8083298d26 100644 --- a/laws/src/main/scala/cats/laws/discipline/BitraverseTests.scala +++ b/laws/src/main/scala/cats/laws/discipline/BitraverseTests.scala @@ -9,32 +9,31 @@ trait BitraverseTests[F[_, _]] extends BifoldableTests[F] with BifunctorTests[F] def laws: BitraverseLaws[F] def bitraverse[G[_], A, B, C, D, E, H](implicit - G: Applicative[G], - C: Monoid[C], - ArbFAB: Arbitrary[F[A, B]], - ArbFAD: Arbitrary[F[A, D]], - ArbGC: Arbitrary[G[C]], - ArbGD: Arbitrary[G[D]], - ArbGE: Arbitrary[G[E]], - ArbGH: Arbitrary[G[H]], - ArbA: Arbitrary[A], - ArbB: Arbitrary[B], - ArbC: Arbitrary[C], - ArbE: Arbitrary[E], - ArbH: Arbitrary[H], - CogenA: Cogen[A], - CogenB: Cogen[B], - CogenC: Cogen[C], - CogenD: Cogen[D], - CogenE: Cogen[E], - EqFAB: Eq[F[A, B]], - EqFAD: Eq[F[A, D]], - EqFAH: Eq[F[A, H]], - EqFCD: Eq[F[C, D]], - EqFCH: Eq[F[C, H]], - EqGGFEH: Eq[G[G[F[E, H]]]], - EqC: Eq[C] - ): RuleSet = + G: Applicative[G], + C: Monoid[C], + ArbFAB: Arbitrary[F[A, B]], + ArbFAD: Arbitrary[F[A, D]], + ArbGC: Arbitrary[G[C]], + ArbGD: Arbitrary[G[D]], + ArbGE: Arbitrary[G[E]], + ArbGH: Arbitrary[G[H]], + ArbA: Arbitrary[A], + ArbB: Arbitrary[B], + ArbC: Arbitrary[C], + ArbE: Arbitrary[E], + ArbH: Arbitrary[H], + CogenA: Cogen[A], + CogenB: Cogen[B], + CogenC: Cogen[C], + CogenD: Cogen[D], + CogenE: Cogen[E], + EqFAB: Eq[F[A, B]], + EqFAD: Eq[F[A, D]], + EqFAH: Eq[F[A, H]], + EqFCD: Eq[F[C, D]], + EqFCH: Eq[F[C, H]], + EqGGFEH: Eq[G[G[F[E, H]]]], + EqC: Eq[C]): RuleSet = new RuleSet { val name = "bitraverse" val parents = Seq(bifoldable[A, B, C], bifunctor[A, B, C, D, E, H]) diff --git a/laws/src/main/scala/cats/laws/discipline/CategoryTests.scala b/laws/src/main/scala/cats/laws/discipline/CategoryTests.scala index bf397fea1a2..013420d3dcf 100644 --- a/laws/src/main/scala/cats/laws/discipline/CategoryTests.scala +++ b/laws/src/main/scala/cats/laws/discipline/CategoryTests.scala @@ -11,17 +11,17 @@ trait CategoryTests[F[_, _]] extends ComposeTests[F] { def laws: CategoryLaws[F] def category[A, B, C, D](implicit - ArbFAB: Arbitrary[F[A, B]], - ArbFBC: Arbitrary[F[B, C]], - ArbFCD: Arbitrary[F[C, D]], - EqFAB: Eq[F[A, B]], - EqFAD: Eq[F[A, D]] - ): RuleSet = + ArbFAB: Arbitrary[F[A, B]], + ArbFBC: Arbitrary[F[B, C]], + ArbFCD: Arbitrary[F[C, D]], + EqFAB: Eq[F[A, B]], + EqFAD: Eq[F[A, D]]): RuleSet = new DefaultRuleSet( name = "category", parent = Some(compose[A, B, C, D]), "category left identity" -> forAll(laws.categoryLeftIdentity[A, B] _), - "category right identity" -> forAll(laws.categoryRightIdentity[A, B] _)) + "category right identity" -> forAll(laws.categoryRightIdentity[A, B] _) + ) } object CategoryTests { diff --git a/laws/src/main/scala/cats/laws/discipline/ChoiceTests.scala b/laws/src/main/scala/cats/laws/discipline/ChoiceTests.scala index 0244679d670..97f0ebcc264 100644 --- a/laws/src/main/scala/cats/laws/discipline/ChoiceTests.scala +++ b/laws/src/main/scala/cats/laws/discipline/ChoiceTests.scala @@ -10,18 +10,18 @@ trait ChoiceTests[F[_, _]] extends CategoryTests[F] { def laws: ChoiceLaws[F] def choice[A, B, C, D](implicit - ArbFAB: Arbitrary[F[A, B]], - ArbFAC: Arbitrary[F[A, C]], - ArbFBC: Arbitrary[F[B, C]], - ArbFCD: Arbitrary[F[C, D]], - EqFAB: Eq[F[A, B]], - EqFAD: Eq[F[A, D]], - EqFEitherABD: Eq[F[Either[A, B], D]] - ): RuleSet = + ArbFAB: Arbitrary[F[A, B]], + ArbFAC: Arbitrary[F[A, C]], + ArbFBC: Arbitrary[F[B, C]], + ArbFCD: Arbitrary[F[C, D]], + EqFAB: Eq[F[A, B]], + EqFAD: Eq[F[A, D]], + EqFEitherABD: Eq[F[Either[A, B], D]]): RuleSet = new DefaultRuleSet( name = "choice", parent = Some(category[A, B, C, D]), - "choice composition distributivity" -> forAll(laws.choiceCompositionDistributivity[A, B, C, D] _)) + "choice composition distributivity" -> forAll(laws.choiceCompositionDistributivity[A, B, C, D] _) + ) } object ChoiceTests { diff --git a/laws/src/main/scala/cats/laws/discipline/CoflatMapTests.scala b/laws/src/main/scala/cats/laws/discipline/CoflatMapTests.scala index 91b05182cb4..e9f067fe477 100644 --- a/laws/src/main/scala/cats/laws/discipline/CoflatMapTests.scala +++ b/laws/src/main/scala/cats/laws/discipline/CoflatMapTests.scala @@ -10,18 +10,17 @@ 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]], - CogenA: Cogen[A], - CogenB: Cogen[B], - CogenC: Cogen[C], - CogenFA: Cogen[F[A]], - CogenFB: Cogen[F[B]], - EqFA: Eq[F[A]], - EqFC: Eq[F[C]], - EqFFA: Eq[F[F[A]]], - EqFB: Eq[F[B]], - EqFFFA: Eq[F[F[F[A]]]] - ): RuleSet = { + ArbFA: Arbitrary[F[A]], + CogenA: Cogen[A], + CogenB: Cogen[B], + CogenC: Cogen[C], + CogenFA: Cogen[F[A]], + CogenFB: Cogen[F[B]], + EqFA: Eq[F[A]], + 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 = Some(functor[A, B, C]), @@ -30,7 +29,6 @@ trait CoflatMapTests[F[_]] extends Laws with FunctorTests[F] { "coflatten coherence" -> forAll(laws.coflattenCoherence[A, B] _), "coflatten throughMap" -> forAll(laws.coflattenThroughMap[A] _) ) - } } object CoflatMapTests { diff --git a/laws/src/main/scala/cats/laws/discipline/CommutativeApplicativeTests.scala b/laws/src/main/scala/cats/laws/discipline/CommutativeApplicativeTests.scala index 8c6cc54f2c3..0f453416a67 100644 --- a/laws/src/main/scala/cats/laws/discipline/CommutativeApplicativeTests.scala +++ b/laws/src/main/scala/cats/laws/discipline/CommutativeApplicativeTests.scala @@ -10,32 +10,30 @@ trait CommutativeApplicativeTests[F[_]] extends CommutativeApplyTests[F] with Ap def laws: CommutativeApplicativeLaws[F] def commutativeApplicative[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]], - CogenA: Cogen[A], - CogenB: Cogen[B], - CogenC: Cogen[C], - EqFA: Eq[F[A]], - EqFB: Eq[F[B]], - EqFC: Eq[F[C]], - EqFABC: Eq[F[(A, B, C)]], - EqFInt: Eq[F[Int]], - iso: Isomorphisms[F] - ): RuleSet = { + ArbFA: Arbitrary[F[A]], + ArbFB: Arbitrary[F[B]], + ArbFC: Arbitrary[F[C]], + ArbFAtoB: Arbitrary[F[A => B]], + ArbFBtoC: Arbitrary[F[B => C]], + CogenA: Cogen[A], + CogenB: Cogen[B], + CogenC: Cogen[C], + EqFA: Eq[F[A]], + EqFB: Eq[F[B]], + EqFC: Eq[F[C]], + EqFABC: Eq[F[(A, B, C)]], + EqFInt: Eq[F[Int]], + iso: Isomorphisms[F]): RuleSet = new RuleSet { def name: String = "commutative applicative" def bases: Seq[(String, RuleSet)] = Nil def parents: Seq[RuleSet] = Seq(applicative[A, B, C], commutativeApply[A, B, C]) def props: Seq[(String, Prop)] = Nil } - } } object CommutativeApplicativeTests { - def apply[F[_]: CommutativeApplicative]: CommutativeApplicativeTests[F] = + def apply[F[_]: CommutativeApplicative]: CommutativeApplicativeTests[F] = new CommutativeApplicativeTests[F] { def laws: CommutativeApplicativeLaws[F] = CommutativeApplicativeLaws[F] } diff --git a/laws/src/main/scala/cats/laws/discipline/CommutativeApplyTests.scala b/laws/src/main/scala/cats/laws/discipline/CommutativeApplyTests.scala index aec569c1eea..9daa9fd3095 100644 --- a/laws/src/main/scala/cats/laws/discipline/CommutativeApplyTests.scala +++ b/laws/src/main/scala/cats/laws/discipline/CommutativeApplyTests.scala @@ -10,21 +10,20 @@ trait CommutativeApplyTests[F[_]] extends ApplyTests[F] { def laws: CommutativeApplyLaws[F] def commutativeApply[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]], - CogenA: Cogen[A], - CogenB: Cogen[B], - CogenC: Cogen[C], - EqFA: Eq[F[A]], - EqFB: Eq[F[B]], - EqFC: Eq[F[C]], - EqFABC: Eq[F[(A, B, C)]], - EqFInt: Eq[F[Int]], - iso: Isomorphisms[F] - ): RuleSet = { + ArbFA: Arbitrary[F[A]], + ArbFB: Arbitrary[F[B]], + ArbFC: Arbitrary[F[C]], + ArbFAtoB: Arbitrary[F[A => B]], + ArbFBtoC: Arbitrary[F[B => C]], + CogenA: Cogen[A], + CogenB: Cogen[B], + CogenC: Cogen[C], + EqFA: Eq[F[A]], + EqFB: Eq[F[B]], + EqFC: Eq[F[C]], + EqFABC: Eq[F[(A, B, C)]], + EqFInt: Eq[F[Int]], + iso: Isomorphisms[F]): RuleSet = new RuleSet { def name: String = "commutative apply" def bases: Seq[(String, RuleSet)] = Nil @@ -33,12 +32,11 @@ trait CommutativeApplyTests[F[_]] extends ApplyTests[F] { "apply commutativity" -> forAll(laws.applyCommutative[A, B, C] _) ) } - } } object CommutativeApplyTests { - def apply[F[_]: CommutativeApply]: CommutativeApplyTests[F] = + def apply[F[_]: CommutativeApply]: CommutativeApplyTests[F] = new CommutativeApplyTests[F] { def laws: CommutativeApplyLaws[F] = CommutativeApplyLaws[F] } diff --git a/laws/src/main/scala/cats/laws/discipline/CommutativeArrowTests.scala b/laws/src/main/scala/cats/laws/discipline/CommutativeArrowTests.scala index 044af01a251..0185d7ff8b8 100644 --- a/laws/src/main/scala/cats/laws/discipline/CommutativeArrowTests.scala +++ b/laws/src/main/scala/cats/laws/discipline/CommutativeArrowTests.scala @@ -9,7 +9,8 @@ import Prop._ trait CommutativeArrowTests[F[_, _]] extends ArrowTests[F] { def laws: CommutativeArrowLaws[F] - def commutativeArrow[A: Arbitrary, B: Arbitrary, C: Arbitrary, D: Arbitrary, E: Arbitrary, G: Arbitrary](implicit + def commutativeArrow[A: Arbitrary, B: Arbitrary, C: Arbitrary, D: Arbitrary, E: Arbitrary, G: Arbitrary]( + implicit ArbFAB: Arbitrary[F[A, B]], ArbFAC: Arbitrary[F[A, C]], ArbFBC: Arbitrary[F[B, C]], @@ -36,10 +37,9 @@ trait CommutativeArrowTests[F[_, _]] extends ArrowTests[F] { EqFEAED: Eq[F[(E, A), (E, D)]], EqFACDBCD: Eq[F[((A, C), D), (B, (C, D))]] ): RuleSet = - new DefaultRuleSet( - name = "commutative arrow", - parent = Some(arrow[A, B, C, D, E, G]), - "arrow commutativity" -> forAll(laws.arrowCommutative[A, B, C, D] _)) + new DefaultRuleSet(name = "commutative arrow", + parent = Some(arrow[A, B, C, D, E, G]), + "arrow commutativity" -> forAll(laws.arrowCommutative[A, B, C, D] _)) } object CommutativeArrowTests { diff --git a/laws/src/main/scala/cats/laws/discipline/CommutativeFlatMapTests.scala b/laws/src/main/scala/cats/laws/discipline/CommutativeFlatMapTests.scala index 028b00efa31..15a763b1ae8 100644 --- a/laws/src/main/scala/cats/laws/discipline/CommutativeFlatMapTests.scala +++ b/laws/src/main/scala/cats/laws/discipline/CommutativeFlatMapTests.scala @@ -10,21 +10,20 @@ trait CommutativeFlatMapTests[F[_]] extends FlatMapTests[F] with CommutativeAppl def laws: CommutativeFlatMapLaws[F] def commutativeFlatMap[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]], - CogenA: Cogen[A], - CogenB: Cogen[B], - CogenC: Cogen[C], - EqFA: Eq[F[A]], - EqFB: Eq[F[B]], - EqFC: Eq[F[C]], - EqFABC: Eq[F[(A, B, C)]], - EqFInt: Eq[F[Int]], - iso: Isomorphisms[F] - ): RuleSet = { + ArbFA: Arbitrary[F[A]], + ArbFB: Arbitrary[F[B]], + ArbFC: Arbitrary[F[C]], + ArbFAtoB: Arbitrary[F[A => B]], + ArbFBtoC: Arbitrary[F[B => C]], + CogenA: Cogen[A], + CogenB: Cogen[B], + CogenC: Cogen[C], + EqFA: Eq[F[A]], + EqFB: Eq[F[B]], + EqFC: Eq[F[C]], + EqFABC: Eq[F[(A, B, C)]], + EqFInt: Eq[F[Int]], + iso: Isomorphisms[F]): RuleSet = new RuleSet { def name: String = "commutative flatMap" def bases: Seq[(String, RuleSet)] = Nil @@ -33,12 +32,11 @@ trait CommutativeFlatMapTests[F[_]] extends FlatMapTests[F] with CommutativeAppl "flatmap commutativity" -> forAll(laws.flatmapCommutative[A, B, C] _) ) } - } } object CommutativeFlatMapTests { - def apply[F[_]: CommutativeFlatMap]: CommutativeFlatMapTests[F] = + def apply[F[_]: CommutativeFlatMap]: CommutativeFlatMapTests[F] = new CommutativeFlatMapTests[F] { def laws: CommutativeFlatMapLaws[F] = CommutativeFlatMapLaws[F] } diff --git a/laws/src/main/scala/cats/laws/discipline/CommutativeMonadTests.scala b/laws/src/main/scala/cats/laws/discipline/CommutativeMonadTests.scala index e654691470c..3ae9a5c6948 100644 --- a/laws/src/main/scala/cats/laws/discipline/CommutativeMonadTests.scala +++ b/laws/src/main/scala/cats/laws/discipline/CommutativeMonadTests.scala @@ -5,37 +5,38 @@ package discipline import cats.laws.discipline.SemigroupalTests.Isomorphisms import org.scalacheck.{Arbitrary, Cogen, Prop} -trait CommutativeMonadTests[F[_]] extends MonadTests[F] with CommutativeFlatMapTests[F] with CommutativeApplicativeTests[F] { +trait CommutativeMonadTests[F[_]] + extends MonadTests[F] + with CommutativeFlatMapTests[F] + with CommutativeApplicativeTests[F] { def laws: CommutativeMonadLaws[F] def commutativeMonad[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]], - CogenA: Cogen[A], - CogenB: Cogen[B], - CogenC: Cogen[C], - EqFA: Eq[F[A]], - EqFB: Eq[F[B]], - EqFC: Eq[F[C]], - EqFABC: Eq[F[(A, B, C)]], - EqFInt: Eq[F[Int]], - iso: Isomorphisms[F] - ): RuleSet = { + ArbFA: Arbitrary[F[A]], + ArbFB: Arbitrary[F[B]], + ArbFC: Arbitrary[F[C]], + ArbFAtoB: Arbitrary[F[A => B]], + ArbFBtoC: Arbitrary[F[B => C]], + CogenA: Cogen[A], + CogenB: Cogen[B], + CogenC: Cogen[C], + EqFA: Eq[F[A]], + EqFB: Eq[F[B]], + EqFC: Eq[F[C]], + EqFABC: Eq[F[(A, B, C)]], + EqFInt: Eq[F[Int]], + iso: Isomorphisms[F]): RuleSet = new RuleSet { def name: String = "commutative monad" def bases: Seq[(String, RuleSet)] = Nil def parents: Seq[RuleSet] = Seq(monad[A, B, C], commutativeFlatMap[A, B, C], commutativeApplicative[A, B, C]) def props: Seq[(String, Prop)] = Nil } - } } object CommutativeMonadTests { - def apply[F[_]: CommutativeMonad]: CommutativeMonadTests[F] = + def apply[F[_]: CommutativeMonad]: CommutativeMonadTests[F] = new CommutativeMonadTests[F] { def laws: CommutativeMonadLaws[F] = CommutativeMonadLaws[F] } diff --git a/laws/src/main/scala/cats/laws/discipline/ComonadTests.scala b/laws/src/main/scala/cats/laws/discipline/ComonadTests.scala index d3b5aa405cf..9fa4c9b2abd 100644 --- a/laws/src/main/scala/cats/laws/discipline/ComonadTests.scala +++ b/laws/src/main/scala/cats/laws/discipline/ComonadTests.scala @@ -10,33 +10,29 @@ trait ComonadTests[F[_]] extends CoflatMapTests[F] { def laws: ComonadLaws[F] def comonad[A: Arbitrary: Eq, B: Arbitrary: Eq, C: Arbitrary: Eq](implicit - ArbFA: Arbitrary[F[A]], - CogenA: Cogen[A], - CogenB: Cogen[B], - CogenC: Cogen[C], - CogenFA: Cogen[F[A]], - CogenFB: Cogen[F[B]], - EqFA: Eq[F[A]], - EqFFA: Eq[F[F[A]]], - EqFFFA: Eq[F[F[F[A]]]], - EqFB: Eq[F[B]], - EqFC: Eq[F[C]] - ): RuleSet = { + ArbFA: Arbitrary[F[A]], + CogenA: Cogen[A], + CogenB: Cogen[B], + CogenC: Cogen[C], + CogenFA: Cogen[F[A]], + CogenFB: Cogen[F[B]], + EqFA: Eq[F[A]], + EqFFA: Eq[F[F[A]]], + EqFFFA: Eq[F[F[F[A]]]], + EqFB: Eq[F[B]], + EqFC: Eq[F[C]]): RuleSet = new DefaultRuleSet( name = "comonad", parent = Some(coflatMap[A, B, C]), - "extractCoflattenIdentity" -> forAll(laws.extractCoflattenIdentity[A] _), "mapCoflattenIdentity" -> forAll(laws.mapCoflattenIdentity[A] _), "coflattenThroughMap" -> forAll(laws.coflattenThroughMap[A] _), - "coflattenCoherence" -> forAll(laws.coflattenCoherence[A, B] _), "coflatMapIdentity" -> forAll(laws.coflatMapIdentity[A, B] _), "mapCoflatMapCoherence" -> forAll(laws.mapCoflatMapCoherence[A, B] _), - "comonad left identity" -> forAll(laws.comonadLeftIdentity[A] _), - "comonad right identity" -> forAll(laws.comonadRightIdentity[A, B] _)) - } + "comonad right identity" -> forAll(laws.comonadRightIdentity[A, B] _) + ) } object ComonadTests { diff --git a/laws/src/main/scala/cats/laws/discipline/ComposeTests.scala b/laws/src/main/scala/cats/laws/discipline/ComposeTests.scala index 13d14b3e4ed..335f5dfd0a8 100644 --- a/laws/src/main/scala/cats/laws/discipline/ComposeTests.scala +++ b/laws/src/main/scala/cats/laws/discipline/ComposeTests.scala @@ -12,15 +12,13 @@ trait ComposeTests[F[_, _]] extends Laws { def laws: ComposeLaws[F] def compose[A, B, C, D](implicit - ArbFAB: Arbitrary[F[A, B]], - ArbFBC: Arbitrary[F[B, C]], - ArbFCD: Arbitrary[F[C, D]], - EqFAD: Eq[F[A, D]] - ): RuleSet = - new DefaultRuleSet( - name = "compose", - parent = None, - "compose associativity" -> forAll(laws.composeAssociativity[A, B, C, D] _)) + ArbFAB: Arbitrary[F[A, B]], + ArbFBC: Arbitrary[F[B, C]], + ArbFCD: Arbitrary[F[C, D]], + EqFAD: Eq[F[A, D]]): RuleSet = + new DefaultRuleSet(name = "compose", + parent = None, + "compose associativity" -> forAll(laws.composeAssociativity[A, B, C, D] _)) } object ComposeTests { diff --git a/laws/src/main/scala/cats/laws/discipline/ContravariantMonoidalTests.scala b/laws/src/main/scala/cats/laws/discipline/ContravariantMonoidalTests.scala index 21b30dc8604..bf5c9101c07 100644 --- a/laws/src/main/scala/cats/laws/discipline/ContravariantMonoidalTests.scala +++ b/laws/src/main/scala/cats/laws/discipline/ContravariantMonoidalTests.scala @@ -11,34 +11,32 @@ trait ContravariantMonoidalTests[F[_]] extends ContravariantSemigroupalTests[F] def laws: ContravariantMonoidalLaws[F] def contravariantMonoidal[A: Arbitrary, B: Arbitrary, C: Arbitrary](implicit - arbFA: Arbitrary[F[A]], - arbFB: Arbitrary[F[B]], - arbFC: Arbitrary[F[C]], - CogenA: Cogen[A], - CogenB: Cogen[B], - CogenC: Cogen[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 { - val name = "contravariantMonoidal" - val parents = Seq(contravariantSemigroupal[A, B, C]) - val bases = Seq.empty - val props = Seq( - "contravariantMonoidal right unit" -> - forAll(laws.contravariantMonoidalUnitRight[A] _), - "contravariantMonoidal left unit" -> - forAll(laws.contravariantMonoidalUnitLeft[A] _), - "contravariantMonoidal contramap2 compatible contramap left" -> - forAll(laws.contravariantMonoidalContramap2CompatibleContramapLeft[A, B, C] _), - "contravariantMonoidal contramap2 compatible contramap right" -> - forAll(laws.contravariantMonoidalContramap2CompatibleContramapRight[A, B, C] _) - ) - } - } + arbFA: Arbitrary[F[A]], + arbFB: Arbitrary[F[B]], + arbFC: Arbitrary[F[C]], + CogenA: Cogen[A], + CogenB: Cogen[B], + CogenC: Cogen[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 { + val name = "contravariantMonoidal" + val parents = Seq(contravariantSemigroupal[A, B, C]) + val bases = Seq.empty + val props = Seq( + "contravariantMonoidal right unit" -> + forAll(laws.contravariantMonoidalUnitRight[A] _), + "contravariantMonoidal left unit" -> + forAll(laws.contravariantMonoidalUnitLeft[A] _), + "contravariantMonoidal contramap2 compatible contramap left" -> + forAll(laws.contravariantMonoidalContramap2CompatibleContramapLeft[A, B, C] _), + "contravariantMonoidal contramap2 compatible contramap right" -> + forAll(laws.contravariantMonoidalContramap2CompatibleContramapRight[A, B, C] _) + ) + } } object ContravariantMonoidalTests { diff --git a/laws/src/main/scala/cats/laws/discipline/ContravariantSemigroupalTests.scala b/laws/src/main/scala/cats/laws/discipline/ContravariantSemigroupalTests.scala index 581fd342258..5394409591b 100644 --- a/laws/src/main/scala/cats/laws/discipline/ContravariantSemigroupalTests.scala +++ b/laws/src/main/scala/cats/laws/discipline/ContravariantSemigroupalTests.scala @@ -11,28 +11,26 @@ trait ContravariantSemigroupalTests[F[_]] extends ContravariantTests[F] with Sem def laws: ContravariantSemigroupalLaws[F] def contravariantSemigroupal[A: Arbitrary, B: Arbitrary, C: Arbitrary](implicit - arbFA: Arbitrary[F[A]], - arbFB: Arbitrary[F[B]], - arbFC: Arbitrary[F[C]], - CogenA: Cogen[A], - CogenB: Cogen[B], - CogenC: Cogen[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 { - val name = "contravariantSemigroupal" - val parents = Seq(contravariant[A, B, C], semigroupal[A, B, C]) - val bases = Seq.empty - val props = Seq( - "contravariantSemigroupal contramap2 delta associates" -> - forAll(laws.contravariantSemigroupalContramap2DiagonalAssociates[A] _) - ) - } - } + arbFA: Arbitrary[F[A]], + arbFB: Arbitrary[F[B]], + arbFC: Arbitrary[F[C]], + CogenA: Cogen[A], + CogenB: Cogen[B], + CogenC: Cogen[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 { + val name = "contravariantSemigroupal" + val parents = Seq(contravariant[A, B, C], semigroupal[A, B, C]) + val bases = Seq.empty + val props = Seq( + "contravariantSemigroupal contramap2 delta associates" -> + forAll(laws.contravariantSemigroupalContramap2DiagonalAssociates[A] _) + ) + } } object ContravariantSemigroupalTests { diff --git a/laws/src/main/scala/cats/laws/discipline/ContravariantTests.scala b/laws/src/main/scala/cats/laws/discipline/ContravariantTests.scala index 2cb1c333df1..35be0addc03 100644 --- a/laws/src/main/scala/cats/laws/discipline/ContravariantTests.scala +++ b/laws/src/main/scala/cats/laws/discipline/ContravariantTests.scala @@ -10,19 +10,18 @@ trait ContravariantTests[F[_]] extends InvariantTests[F] { def laws: ContravariantLaws[F] def contravariant[A: Arbitrary, B: Arbitrary, C: Arbitrary](implicit - ArbFA: Arbitrary[F[A]], - CogenA: Cogen[A], - CogenB: Cogen[B], - CogenC: Cogen[C], - EqFA: Eq[F[A]], - EqFC: Eq[F[C]] - ): RuleSet = { + ArbFA: Arbitrary[F[A]], + CogenA: Cogen[A], + CogenB: Cogen[B], + CogenC: Cogen[C], + EqFA: Eq[F[A]], + EqFC: Eq[F[C]]): RuleSet = new DefaultRuleSet( name = "contravariant", parent = Some(invariant[A, B, C]), "contravariant identity" -> forAll(laws.contravariantIdentity[A] _), - "contravariant composition" -> forAll(laws.contravariantComposition[A, B, C] _)) - } + "contravariant composition" -> forAll(laws.contravariantComposition[A, B, C] _) + ) } object ContravariantTests { diff --git a/laws/src/main/scala/cats/laws/discipline/DeferTests.scala b/laws/src/main/scala/cats/laws/discipline/DeferTests.scala index 63e679e7ba7..d90bf87193d 100644 --- a/laws/src/main/scala/cats/laws/discipline/DeferTests.scala +++ b/laws/src/main/scala/cats/laws/discipline/DeferTests.scala @@ -10,17 +10,16 @@ trait DeferTests[F[_]] extends Laws { def laws: DeferLaws[F] def defer[A: Arbitrary](implicit - ArbFA: Arbitrary[F[A]], - EqFA: Eq[F[A]], - EqBool: Eq[Boolean] - ): RuleSet = { + ArbFA: Arbitrary[F[A]], + EqFA: Eq[F[A]], + EqBool: Eq[Boolean]): RuleSet = new DefaultRuleSet( name = "defer", parent = None, "defer Identity" -> forAll(laws.deferIdentity[A] _), "defer does not evaluate" -> forAll(laws.deferDoesNotEvaluate[A] _), - "defer is stack safe" -> forAll(laws.deferIsStackSafe[A] _)) - } + "defer is stack safe" -> forAll(laws.deferIsStackSafe[A] _) + ) } object DeferTests { diff --git a/laws/src/main/scala/cats/laws/discipline/DistributiveTests.scala b/laws/src/main/scala/cats/laws/discipline/DistributiveTests.scala index c4a54479d88..5f7da0243f2 100644 --- a/laws/src/main/scala/cats/laws/discipline/DistributiveTests.scala +++ b/laws/src/main/scala/cats/laws/discipline/DistributiveTests.scala @@ -8,7 +8,8 @@ import Prop._ trait DistributiveTests[F[_]] extends FunctorTests[F] { def laws: DistributiveLaws[F] - def distributive[A: Arbitrary, B: Arbitrary, C: Arbitrary, X[_]: Functor, Y[_]: Distributive](implicit + def distributive[A: Arbitrary, B: Arbitrary, C: Arbitrary, X[_]: Functor, Y[_]: Distributive]( + implicit ArbFA: Arbitrary[F[A]], ArbFB: Arbitrary[F[B]], ArbXA: Arbitrary[X[A]], @@ -24,7 +25,7 @@ trait DistributiveTests[F[_]] extends FunctorTests[F] { EqFYXC: Eq[F[Y[X[C]]]], EqFYA: Eq[F[Y[A]]], EqYFB: Eq[Y[F[B]]] - ): RuleSet = { + ): RuleSet = new RuleSet { def name: String = "distributive" def bases: Seq[(String, RuleSet)] = Nil @@ -36,7 +37,6 @@ trait DistributiveTests[F[_]] extends FunctorTests[F] { "distributive double cosequence identity" -> forAll(laws.cosequenceTwiceIsId[A, Y] _) ) } - } } object DistributiveTests { diff --git a/laws/src/main/scala/cats/laws/discipline/Eq.scala b/laws/src/main/scala/cats/laws/discipline/Eq.scala index 6c7b7c60985..74162919194 100644 --- a/laws/src/main/scala/cats/laws/discipline/Eq.scala +++ b/laws/src/main/scala/cats/laws/discipline/Eq.scala @@ -17,18 +17,18 @@ import org.scalacheck.Arbitrary object eq { /** - * Create an approximation of Eq[A => B] by generating 100 values for A - * and comparing the application of the two functions. - */ + * Create an approximation of Eq[A => B] by generating 100 values for A + * and comparing the application of the two functions. + */ implicit def catsLawsEqForFn1[A, B](implicit A: Arbitrary[A], B: Eq[B]): Eq[A => B] = new Eq[A => B] { val sampleCnt: Int = if (Platform.isJvm) 50 else 30 def eqv(f: A => B, g: A => B): Boolean = { - val samples = List.fill(sampleCnt)(A.arbitrary.sample).collect{ + val samples = List.fill(sampleCnt)(A.arbitrary.sample).collect { case Some(a) => a - case None => sys.error("Could not generate arbitrary values to compare two functions") + case None => sys.error("Could not generate arbitrary values to compare two functions") } - samples.forall(s => B.eqv(f(s), g(s)) ) + samples.forall(s => B.eqv(f(s), g(s))) } } @@ -37,40 +37,43 @@ object eq { Eq.instance(catsLawsEqForFn1[A, B].eqv(_, _)) /** - * Create an approximation of Eq[(A, B) => C] by generating 100 values for A and B - * and comparing the application of the two functions. - */ - implicit def catsLawsEqForFn2[A, B, C](implicit A: Arbitrary[A], B: Arbitrary[B], C: Eq[C]): Eq[(A, B) => C] = new Eq[(A, B) => C] { - val sampleCnt: Int = if (Platform.isJvm) 50 else 5 - - def eqv(f: (A, B) => C, g: (A, B) => C): Boolean = { - val samples = List.fill(sampleCnt)((A.arbitrary.sample, B.arbitrary.sample)).collect{ - case (Some(a), Some(b)) => (a, b) - case _ => sys.error("Could not generate arbitrary values to compare two functions") + * Create an approximation of Eq[(A, B) => C] by generating 100 values for A and B + * and comparing the application of the two functions. + */ + implicit def catsLawsEqForFn2[A, B, C](implicit A: Arbitrary[A], B: Arbitrary[B], C: Eq[C]): Eq[(A, B) => C] = + new Eq[(A, B) => C] { + val sampleCnt: Int = if (Platform.isJvm) 50 else 5 + + def eqv(f: (A, B) => C, g: (A, B) => C): Boolean = { + val samples = List.fill(sampleCnt)((A.arbitrary.sample, B.arbitrary.sample)).collect { + case (Some(a), Some(b)) => (a, b) + case _ => sys.error("Could not generate arbitrary values to compare two functions") + } + samples.forall { case (a, b) => C.eqv(f(a, b), g(a, b)) } } - samples.forall { case (a, b) => C.eqv(f(a, b), g(a, b)) } } - } /** Create an approximation of Eq[Show[A]] by using catsLawsEqForFn1[A, String] */ - implicit def catsLawsEqForShow[A: Arbitrary]: Eq[Show[A]] = { - Eq.by[Show[A], A => String] { showInstance => - (a: A) => showInstance.show(a) + implicit def catsLawsEqForShow[A: Arbitrary]: Eq[Show[A]] = + Eq.by[Show[A], A => String] { showInstance => (a: A) => + showInstance.show(a) } - } /** - * Create an approximate Eq instance for some type A, by comparing - * the behavior of `f(x, b)` and `f(y, b)` across many `b` samples. - */ + * Create an approximate Eq instance for some type A, by comparing + * the behavior of `f(x, b)` and `f(y, b)` across many `b` samples. + */ def sampledEq[A, B: Arbitrary, C: Eq](samples: Int)(f: (A, B) => C): Eq[A] = new Eq[A] { val gen = Arbitrary.arbitrary[B] def eqv(x: A, y: A): Boolean = - Iterator.range(1, samples) + Iterator + .range(1, samples) .map(_ => gen.sample) .map(_.getOrElse(sys.error(s"generator $gen failed"))) - .forall { b => f(x, b) === f(y, b) } + .forall { b => + f(x, b) === f(y, b) + } } implicit def catsLawsEqForEq[A](implicit arbA: Arbitrary[(A, A)]): Eq[Eq[A]] = @@ -79,10 +82,12 @@ object eq { implicit def catsLawsEqForEquiv[A](implicit arbA: Arbitrary[(A, A)]): Eq[Equiv[A]] = sampledEq[Equiv[A], (A, A), Boolean](100) { case (e, (l, r)) => e.equiv(l, r) } - implicit def catsLawsEqForPartialOrder[A](implicit arbA: Arbitrary[(A, A)], optIntEq: Eq[Option[Int]]): Eq[PartialOrder[A]] = + implicit def catsLawsEqForPartialOrder[A](implicit arbA: Arbitrary[(A, A)], + optIntEq: Eq[Option[Int]]): Eq[PartialOrder[A]] = sampledEq[PartialOrder[A], (A, A), Option[Int]](100) { case (p, (l, r)) => p.tryCompare(l, r) } - implicit def catsLawsEqForPartialOrdering[A](implicit arbA: Arbitrary[(A, A)], optIntEq: Eq[Option[Int]]): Eq[PartialOrdering[A]] = + implicit def catsLawsEqForPartialOrdering[A](implicit arbA: Arbitrary[(A, A)], + optIntEq: Eq[Option[Int]]): Eq[PartialOrdering[A]] = sampledEq[PartialOrdering[A], (A, A), Option[Int]](100) { case (p, (l, r)) => p.tryCompare(l, r) } implicit def catsLawsEqForOrder[A](implicit arbA: Arbitrary[(A, A)]): Eq[Order[A]] = @@ -92,80 +97,97 @@ object eq { sampledEq[Ordering[A], (A, A), Int](100) { case (p, (l, r)) => p.compare(l, r) } /** - * Creates an approximation of Eq[Hash[A]] by generating 100 values for A - * and comparing the application of the two hash functions. - */ + * Creates an approximation of Eq[Hash[A]] by generating 100 values for A + * and comparing the application of the two hash functions. + */ implicit def catsLawsEqForHash[A](implicit arbA: Arbitrary[A]): Eq[Hash[A]] = new Eq[Hash[A]] { def eqv(f: Hash[A], g: Hash[A]): Boolean = { val samples = List.fill(100)(arbA.arbitrary.sample).collect { case Some(a) => a - case None => sys.error("Could not generate arbitrary values to compare two Hash[A]") + case None => sys.error("Could not generate arbitrary values to compare two Hash[A]") + } + samples.forall { x => + f.hash(x) == g.hash(x) } - samples.forall { x => f.hash(x) == g.hash(x) } } } /** - * Create an approximation of Eq[Semigroup[A]] by generating values for A - * and comparing the application of the two combine functions. - */ + * Create an approximation of Eq[Semigroup[A]] by generating values for A + * and comparing the application of the two combine functions. + */ implicit def catsLawsEqForSemigroup[A](implicit arbAA: Arbitrary[(A, A)], eqA: Eq[A]): Eq[Semigroup[A]] = { val instance: Eq[((A, A)) => A] = catsLawsEqForFn1[(A, A), A] - Eq.by[Semigroup[A], ((A, A)) => A]( f => Function.tupled((x, y) => f.combine(x, y)))(instance) + Eq.by[Semigroup[A], ((A, A)) => A](f => Function.tupled((x, y) => f.combine(x, y)))(instance) } - implicit def catsLawsEqForCommutativeSemigroup[A](implicit arbAA: Arbitrary[(A, A)], eqA: Eq[A]): Eq[CommutativeSemigroup[A]] = { + implicit def catsLawsEqForCommutativeSemigroup[A](implicit arbAA: Arbitrary[(A, A)], + eqA: Eq[A]): Eq[CommutativeSemigroup[A]] = { implicit val eqABool: Eq[(A, Boolean)] = Eq.instance { case ((x, boolX), (y, boolY)) => x === y && boolX === boolY } - Eq.by[CommutativeSemigroup[A], ((A, A)) => (A, Boolean)](f => - Function.tupled((x, y) => (f.combine(x, y), f.combine(x, y) === f.combine(y, x))) + Eq.by[CommutativeSemigroup[A], ((A, A)) => (A, Boolean)]( + f => Function.tupled((x, y) => (f.combine(x, y), f.combine(x, y) === f.combine(y, x))) )(catsLawsEqForFn1[(A, A), (A, Boolean)]) } - implicit def catsLawsEqForBand[A](implicit arbAA: Arbitrary[(A, A)], eqSA: Eq[Semigroup[A]], eqA: Eq[A]): Eq[Band[A]] = { - Eq.by[Band[A], ((A, A)) => Boolean](f => - Function.tupled((x, y) => f.combine(x, y) === f.combine(f.combine(x, y), y)) + implicit def catsLawsEqForBand[A](implicit arbAA: Arbitrary[(A, A)], + eqSA: Eq[Semigroup[A]], + eqA: Eq[A]): Eq[Band[A]] = + Eq.by[Band[A], ((A, A)) => Boolean]( + f => Function.tupled((x, y) => f.combine(x, y) === f.combine(f.combine(x, y), y)) )(catsLawsEqForFn1[(A, A), Boolean]) - } implicit def catsLawsEqForMonoid[A](implicit eqSA: Eq[Semigroup[A]], eqA: Eq[A]): Eq[Monoid[A]] = new Eq[Monoid[A]] { - def eqv(f: Monoid[A], g: Monoid[A]): Boolean = { + def eqv(f: Monoid[A], g: Monoid[A]): Boolean = eqSA.eqv(f, g) && eqA.eqv(f.empty, g.empty) - } } - implicit def catsLawsEqForSemilattice[A](implicit eqBA: Eq[Band[A]], eqCA: Eq[CommutativeSemigroup[A]], eqA: Eq[A]): Eq[Semilattice[A]] = + implicit def catsLawsEqForSemilattice[A](implicit eqBA: Eq[Band[A]], + eqCA: Eq[CommutativeSemigroup[A]], + eqA: Eq[A]): Eq[Semilattice[A]] = Eq.instance((f, g) => eqBA.eqv(f, g) && eqCA.eqv(f, g)) - implicit def catsLawsEqForCommutativeMonoid[A](implicit eqSA: Eq[CommutativeSemigroup[A]], eqMA: Eq[Monoid[A]], eqA: Eq[A]): Eq[CommutativeMonoid[A]] = + implicit def catsLawsEqForCommutativeMonoid[A](implicit eqSA: Eq[CommutativeSemigroup[A]], + eqMA: Eq[Monoid[A]], + eqA: Eq[A]): Eq[CommutativeMonoid[A]] = Eq.instance((f, g) => eqSA.eqv(f, g) && eqMA.eqv(f, g)) - implicit def catsLawsEqForBoundedSemilattice[A](implicit eqSA: Eq[Semilattice[A]], eqCA: Eq[CommutativeMonoid[A]], eqA: Eq[A]): Eq[BoundedSemilattice[A]] = + implicit def catsLawsEqForBoundedSemilattice[A](implicit eqSA: Eq[Semilattice[A]], + eqCA: Eq[CommutativeMonoid[A]], + eqA: Eq[A]): Eq[BoundedSemilattice[A]] = Eq.instance((f, g) => eqSA.eqv(f, g) && eqCA.eqv(f, g)) - implicit def catsLawsEqForGroup[A](implicit arbAA: Arbitrary[(A, A)], eqMA: Eq[Monoid[A]], eqA: Eq[A]): Eq[Group[A]] = { + implicit def catsLawsEqForGroup[A](implicit arbAA: Arbitrary[(A, A)], + eqMA: Eq[Monoid[A]], + eqA: Eq[A]): Eq[Group[A]] = { implicit val eqABool: Eq[(A, Boolean)] = Eq.instance { case ((x, boolX), (y, boolY)) => x === y && boolX === boolY } - val inverseEq = Eq.by[Group[A], ((A, A)) => (A, Boolean)](f => - Function.tupled((x, y) => ( - f.combine(x, y), - f.combine(f.inverse(x), x) === f.empty && f.combine(x, f.inverse(x)) === f.empty && - f.combine(f.inverse(y), y) === f.empty && f.combine(y, f.inverse(y)) === f.empty && - f.inverse(f.empty) == f.empty + val inverseEq = Eq.by[Group[A], ((A, A)) => (A, Boolean)]( + f => + Function.tupled( + (x, y) => + ( + f.combine(x, y), + f.combine(f.inverse(x), x) === f.empty && f.combine(x, f.inverse(x)) === f.empty && + f.combine(f.inverse(y), y) === f.empty && f.combine(y, f.inverse(y)) === f.empty && + f.inverse(f.empty) == f.empty + ) ) - ))(catsLawsEqForFn1[(A, A), (A, Boolean)]) + )(catsLawsEqForFn1[(A, A), (A, Boolean)]) Eq.instance((f, g) => eqMA.eqv(f, g) && inverseEq.eqv(f, g)) } - implicit def catsLawsEqForCommutativeGroup[A](implicit eqMA: Eq[CommutativeMonoid[A]], eqGA: Eq[Group[A]], eqA: Eq[A]): Eq[CommutativeGroup[A]] = + implicit def catsLawsEqForCommutativeGroup[A](implicit eqMA: Eq[CommutativeMonoid[A]], + eqGA: Eq[Group[A]], + eqA: Eq[A]): Eq[CommutativeGroup[A]] = Eq.instance((f, g) => eqMA.eqv(f, g) && eqGA.eqv(f, g)) - implicit def catsLawsEqForRepresentableStore[F[_]: Representable, S, A](implicit eqFA: Eq[F[A]], eqS: Eq[S]): Eq[RepresentableStore[F, S, A]] = { + implicit def catsLawsEqForRepresentableStore[F[_]: Representable, S, A](implicit eqFA: Eq[F[A]], + eqS: Eq[S]): Eq[RepresentableStore[F, S, A]] = Eq.instance((s1, s2) => eqFA.eqv(s1.fa, s2.fa) && eqS.eqv(s1.index, s2.index)) - } } diff --git a/laws/src/main/scala/cats/laws/discipline/FlatMapTests.scala b/laws/src/main/scala/cats/laws/discipline/FlatMapTests.scala index 834fadcb27f..57a9f176025 100644 --- a/laws/src/main/scala/cats/laws/discipline/FlatMapTests.scala +++ b/laws/src/main/scala/cats/laws/discipline/FlatMapTests.scala @@ -12,20 +12,19 @@ trait FlatMapTests[F[_]] extends ApplyTests[F] { def laws: FlatMapLaws[F] def flatMap[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]], - CogenA: Cogen[A], - CogenB: Cogen[B], - CogenC: Cogen[C], - EqFA: Eq[F[A]], - EqFB: Eq[F[B]], - EqFC: Eq[F[C]], - EqFABC: Eq[F[(A, B, C)]], - iso: Isomorphisms[F] - ): RuleSet = { + ArbFA: Arbitrary[F[A]], + ArbFB: Arbitrary[F[B]], + ArbFC: Arbitrary[F[C]], + ArbFAtoB: Arbitrary[F[A => B]], + ArbFBtoC: Arbitrary[F[B => C]], + CogenA: Cogen[A], + CogenB: Cogen[B], + CogenC: Cogen[C], + EqFA: Eq[F[A]], + EqFB: Eq[F[B]], + EqFC: Eq[F[C]], + EqFABC: Eq[F[(A, B, C)]], + iso: Isomorphisms[F]): RuleSet = { implicit def functorF: Functor[F] = laws.F implicit val EqFAB: Eq[F[(A, B)]] = ContravariantSemigroupal[Eq].composeFunctor[F].product(EqFA, EqFB) @@ -37,7 +36,8 @@ trait FlatMapTests[F[_]] extends ApplyTests[F] { "flatMap consistent apply" -> forAll(laws.flatMapConsistentApply[A, B] _), "flatMap from tailRecM consistency" -> forAll(laws.flatMapFromTailRecMConsistency[A, B] _), "mproduct consistent flatMap" -> forAll(laws.mproductConsistency[A, B] _), - "tailRecM consistent flatMap" -> forAll(laws.tailRecMConsistentFlatMap[A] _)) + "tailRecM consistent flatMap" -> forAll(laws.tailRecMConsistentFlatMap[A] _) + ) } } diff --git a/laws/src/main/scala/cats/laws/discipline/FoldableTests.scala b/laws/src/main/scala/cats/laws/discipline/FoldableTests.scala index ebc68c82d5a..65d10b20810 100644 --- a/laws/src/main/scala/cats/laws/discipline/FoldableTests.scala +++ b/laws/src/main/scala/cats/laws/discipline/FoldableTests.scala @@ -12,17 +12,16 @@ trait FoldableTests[F[_]] extends UnorderedFoldableTests[F] { def laws: FoldableLaws[F] def foldable[A: Arbitrary, B: Arbitrary](implicit - ArbFA: Arbitrary[F[A]], - A: CommutativeMonoid[A], - B: CommutativeMonoid[B], - CogenA: Cogen[A], - CogenB: Cogen[B], - EqA: Eq[A], - EqFA: Eq[F[A]], - EqB: Eq[B], - EqOptionB: Eq[Option[B]], - EqOptionA: Eq[Option[A]] - ): RuleSet = { + ArbFA: Arbitrary[F[A]], + A: CommutativeMonoid[A], + B: CommutativeMonoid[B], + CogenA: Cogen[A], + CogenB: Cogen[B], + EqA: Eq[A], + EqFA: Eq[F[A]], + EqB: Eq[B], + EqOptionB: Eq[Option[B]], + EqOptionA: Eq[Option[A]]): RuleSet = new DefaultRuleSet( name = "foldable", parent = Some(unorderedFoldable[A, B]), @@ -46,10 +45,8 @@ trait FoldableTests[F[_]] extends UnorderedFoldableTests[F] { "collectFirstSome reference" -> forAll(laws.collectFirstSome_Ref[A, B] _), "collectFirst reference" -> forAll(laws.collectFirst_Ref[A, B] _) ) - } } - object FoldableTests { def apply[F[_]: Foldable]: FoldableTests[F] = new FoldableTests[F] { def laws: FoldableLaws[F] = FoldableLaws[F] } diff --git a/laws/src/main/scala/cats/laws/discipline/FunctorFilterTests.scala b/laws/src/main/scala/cats/laws/discipline/FunctorFilterTests.scala index 01fead48a2d..5e746c60e9e 100644 --- a/laws/src/main/scala/cats/laws/discipline/FunctorFilterTests.scala +++ b/laws/src/main/scala/cats/laws/discipline/FunctorFilterTests.scala @@ -10,17 +10,16 @@ trait FunctorFilterTests[F[_]] extends Laws { def laws: FunctorFilterLaws[F] def functorFilter[A, B, C](implicit - ArbFA: Arbitrary[F[A]], - ArbFABoo: Arbitrary[PartialFunction[A, B]], - ArbFOA: Arbitrary[F[Option[A]]], - ArbAOB: Arbitrary[A => Option[B]], - ArbBOC: Arbitrary[B => Option[C]], - ArbAB: Arbitrary[A => B], - ArbABoo: Arbitrary[A => Boolean], - EqFA: Eq[F[A]], - EqFB: Eq[F[B]], - EqFC: Eq[F[C]] - ): RuleSet = { + ArbFA: Arbitrary[F[A]], + ArbFABoo: Arbitrary[PartialFunction[A, B]], + ArbFOA: Arbitrary[F[Option[A]]], + ArbAOB: Arbitrary[A => Option[B]], + ArbBOC: Arbitrary[B => Option[C]], + ArbAB: Arbitrary[A => B], + ArbABoo: Arbitrary[A => Boolean], + EqFA: Eq[F[A]], + EqFB: Eq[F[B]], + EqFC: Eq[F[C]]): RuleSet = new DefaultRuleSet( name = "functorFilter", parent = None, @@ -30,7 +29,6 @@ trait FunctorFilterTests[F[_]] extends Laws { "flattenOption mapFilter consistency" -> forAll(laws.flattenOptionConsistentWithMapFilter[A] _), "filter mapFilter consistency" -> forAll(laws.filterConsistentWithMapFilter[A] _) ) - } } object FunctorFilterTests { diff --git a/laws/src/main/scala/cats/laws/discipline/FunctorTests.scala b/laws/src/main/scala/cats/laws/discipline/FunctorTests.scala index c2a9542a082..7cf0d085a82 100644 --- a/laws/src/main/scala/cats/laws/discipline/FunctorTests.scala +++ b/laws/src/main/scala/cats/laws/discipline/FunctorTests.scala @@ -9,19 +9,18 @@ trait FunctorTests[F[_]] extends InvariantTests[F] { def laws: FunctorLaws[F] def functor[A: Arbitrary, B: Arbitrary, C: Arbitrary](implicit - ArbFA: Arbitrary[F[A]], - CogenA: Cogen[A], - CogenB: Cogen[B], - CogenC: Cogen[C], - EqFA: Eq[F[A]], - EqFC: Eq[F[C]] - ): RuleSet = { + ArbFA: Arbitrary[F[A]], + CogenA: Cogen[A], + CogenB: Cogen[B], + CogenC: Cogen[C], + EqFA: Eq[F[A]], + EqFC: Eq[F[C]]): RuleSet = new DefaultRuleSet( name = "functor", parent = Some(invariant[A, B, C]), "covariant identity" -> forAll(laws.covariantIdentity[A] _), - "covariant composition" -> forAll(laws.covariantComposition[A, B, C] _)) - } + "covariant composition" -> forAll(laws.covariantComposition[A, B, C] _) + ) } object FunctorTests { diff --git a/laws/src/main/scala/cats/laws/discipline/InjectKTests.scala b/laws/src/main/scala/cats/laws/discipline/InjectKTests.scala index a6eed7fe61f..a2f0b500412 100644 --- a/laws/src/main/scala/cats/laws/discipline/InjectKTests.scala +++ b/laws/src/main/scala/cats/laws/discipline/InjectKTests.scala @@ -11,11 +11,10 @@ trait InjectKTests[F[_], G[_]] extends Laws { def laws: InjectKLaws[F, G] def injectK[A](implicit - ArbFA: Arbitrary[F[A]], - EqOptionFA: Eq[Option[F[A]]], - ArbGA: Arbitrary[G[A]], - EqOptionGA: Eq[Option[G[A]]] - ): RuleSet = + ArbFA: Arbitrary[F[A]], + EqOptionFA: Eq[Option[F[A]]], + ArbGA: Arbitrary[G[A]], + EqOptionGA: Eq[Option[G[A]]]): RuleSet = new DefaultRuleSet( "injectK", None, diff --git a/laws/src/main/scala/cats/laws/discipline/InjectTests.scala b/laws/src/main/scala/cats/laws/discipline/InjectTests.scala index 8619d84cb9c..3f3f0016018 100644 --- a/laws/src/main/scala/cats/laws/discipline/InjectTests.scala +++ b/laws/src/main/scala/cats/laws/discipline/InjectTests.scala @@ -11,11 +11,10 @@ trait InjectTests[A, B] extends Laws { def laws: InjectLaws[A, B] def inject(implicit - ArbA: Arbitrary[A], - EqOptionA: Eq[Option[A]], - ArbB: Arbitrary[B], - EqOptionB: Eq[Option[B]] - ): RuleSet = + ArbA: Arbitrary[A], + EqOptionA: Eq[Option[A]], + ArbB: Arbitrary[B], + EqOptionB: Eq[Option[B]]): RuleSet = new DefaultRuleSet( "inject", None, diff --git a/laws/src/main/scala/cats/laws/discipline/InvariantMonoidalTests.scala b/laws/src/main/scala/cats/laws/discipline/InvariantMonoidalTests.scala index 0f868c1ebdc..2b956abf4a7 100644 --- a/laws/src/main/scala/cats/laws/discipline/InvariantMonoidalTests.scala +++ b/laws/src/main/scala/cats/laws/discipline/InvariantMonoidalTests.scala @@ -10,18 +10,17 @@ trait InvariantMonoidalTests[F[_]] extends InvariantSemigroupalTests[F] { def laws: InvariantMonoidalLaws[F] def invariantMonoidal[A: Arbitrary, B: Arbitrary, C: Arbitrary](implicit - ArbFA: Arbitrary[F[A]], - ArbFB: Arbitrary[F[B]], - ArbFC: Arbitrary[F[C]], - CogenA: Cogen[A], - CogenB: Cogen[B], - CogenC: Cogen[C], - EqFABC: Eq[F[(A, (B, C))]], - EqFABC2: Eq[F[(A, B, C)]], - iso: Isomorphisms[F], - EqFA: Eq[F[A]], - EqFC: Eq[F[C]] - ): RuleSet = + ArbFA: Arbitrary[F[A]], + ArbFB: Arbitrary[F[B]], + ArbFC: Arbitrary[F[C]], + CogenA: Cogen[A], + CogenB: Cogen[B], + CogenC: Cogen[C], + EqFABC: Eq[F[(A, (B, C))]], + EqFABC2: Eq[F[(A, B, C)]], + iso: Isomorphisms[F], + EqFA: Eq[F[A]], + EqFC: Eq[F[C]]): RuleSet = new RuleSet { val name = "invariantMonoidal" val parents = Seq(invariant[A, B, C], semigroupal[A, B, C]) @@ -29,7 +28,9 @@ trait InvariantMonoidalTests[F[_]] extends InvariantSemigroupalTests[F] { val props = Seq( "invariant monoidal left identity" -> forAll((fa: F[A]) => laws.invariantMonoidalLeftIdentity(fa)), "invariant monoidal right identity" -> forAll((fa: F[A]) => laws.invariantMonoidalRightIdentity(fa)), - "invariant monoidal associativity" -> forAll((fa: F[A], fb: F[B], fc: F[C]) => laws.invariantMonoidalAssociativity(fa, fb, fc)) + "invariant monoidal associativity" -> forAll( + (fa: F[A], fb: F[B], fc: F[C]) => laws.invariantMonoidalAssociativity(fa, fb, fc) + ) ) } } diff --git a/laws/src/main/scala/cats/laws/discipline/InvariantSemigroupalTests.scala b/laws/src/main/scala/cats/laws/discipline/InvariantSemigroupalTests.scala index 3eae12a930a..d6a5318f8ed 100644 --- a/laws/src/main/scala/cats/laws/discipline/InvariantSemigroupalTests.scala +++ b/laws/src/main/scala/cats/laws/discipline/InvariantSemigroupalTests.scala @@ -10,17 +10,17 @@ trait InvariantSemigroupalTests[F[_]] extends InvariantTests[F] with Semigroupal def laws: InvariantSemigroupalLaws[F] def invariantSemigroupal[A: Arbitrary, B: Arbitrary, C: Arbitrary](implicit - arbFA: Arbitrary[F[A]], - arbFB: Arbitrary[F[B]], - arbFC: Arbitrary[F[C]], - CogenA: Cogen[A], - CogenB: Cogen[B], - CogenC: Cogen[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 { + arbFA: Arbitrary[F[A]], + arbFB: Arbitrary[F[B]], + arbFC: Arbitrary[F[C]], + CogenA: Cogen[A], + CogenB: Cogen[B], + CogenC: Cogen[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 { val name = "invariantSemigroupal" val parents = Seq(invariant[A, B, C], semigroupal[A, B, C]) val bases = Nil diff --git a/laws/src/main/scala/cats/laws/discipline/InvariantTests.scala b/laws/src/main/scala/cats/laws/discipline/InvariantTests.scala index a801ba99e0d..4594eed29ce 100644 --- a/laws/src/main/scala/cats/laws/discipline/InvariantTests.scala +++ b/laws/src/main/scala/cats/laws/discipline/InvariantTests.scala @@ -11,19 +11,18 @@ trait InvariantTests[F[_]] extends Laws { def laws: InvariantLaws[F] def invariant[A: Arbitrary, B: Arbitrary, C: Arbitrary](implicit - ArbFA: Arbitrary[F[A]], - CogenA: Cogen[A], - CogenB: Cogen[B], - CogenC: Cogen[C], - EqFA: Eq[F[A]], - EqFC: Eq[F[C]] - ): RuleSet = { + ArbFA: Arbitrary[F[A]], + CogenA: Cogen[A], + CogenB: Cogen[B], + CogenC: Cogen[C], + EqFA: Eq[F[A]], + EqFC: Eq[F[C]]): RuleSet = new DefaultRuleSet( name = "invariant", parent = None, "invariant identity" -> forAll(laws.invariantIdentity[A] _), - "invariant composition" -> forAll(laws.invariantComposition[A, B, C] _)) - } + "invariant composition" -> forAll(laws.invariantComposition[A, B, C] _) + ) } object InvariantTests { diff --git a/laws/src/main/scala/cats/laws/discipline/MonadErrorTests.scala b/laws/src/main/scala/cats/laws/discipline/MonadErrorTests.scala index 53e23ca65d7..5d74eeef456 100644 --- a/laws/src/main/scala/cats/laws/discipline/MonadErrorTests.scala +++ b/laws/src/main/scala/cats/laws/discipline/MonadErrorTests.scala @@ -11,28 +11,27 @@ trait MonadErrorTests[F[_], E] extends ApplicativeErrorTests[F, E] with MonadTes def laws: MonadErrorLaws[F, E] def monadError[A: Arbitrary: Eq, B: Arbitrary: Eq, C: Arbitrary: Eq](implicit - ArbFA: Arbitrary[F[A]], - ArbFB: Arbitrary[F[B]], - ArbFC: Arbitrary[F[C]], - ArbFU: Arbitrary[F[Unit]], - ArbFAtoB: Arbitrary[F[A => B]], - ArbFBtoC: Arbitrary[F[B => C]], - ArbE: Arbitrary[E], - CogenA: Cogen[A], - CogenB: Cogen[B], - CogenC: Cogen[C], - CogenE: Cogen[E], - EqFA: Eq[F[A]], - EqFB: Eq[F[B]], - EqFC: Eq[F[C]], - EqE: Eq[E], - EqFEitherEU: Eq[F[Either[E, Unit]]], - EqFEitherEA: Eq[F[Either[E, A]]], - EqEitherTFEA: Eq[EitherT[F, E, A]], - EqFABC: Eq[F[(A, B, C)]], - EqFInt: Eq[F[Int]], - iso: Isomorphisms[F] - ): RuleSet = { + ArbFA: Arbitrary[F[A]], + ArbFB: Arbitrary[F[B]], + ArbFC: Arbitrary[F[C]], + ArbFU: Arbitrary[F[Unit]], + ArbFAtoB: Arbitrary[F[A => B]], + ArbFBtoC: Arbitrary[F[B => C]], + ArbE: Arbitrary[E], + CogenA: Cogen[A], + CogenB: Cogen[B], + CogenC: Cogen[C], + CogenE: Cogen[E], + EqFA: Eq[F[A]], + EqFB: Eq[F[B]], + EqFC: Eq[F[C]], + EqE: Eq[E], + EqFEitherEU: Eq[F[Either[E, Unit]]], + EqFEitherEA: Eq[F[Either[E, A]]], + EqEitherTFEA: Eq[EitherT[F, E, A]], + EqFABC: Eq[F[(A, B, C)]], + EqFInt: Eq[F[Int]], + iso: Isomorphisms[F]): RuleSet = new RuleSet { def name: String = "monadError" def bases: Seq[(String, RuleSet)] = Nil @@ -46,7 +45,6 @@ trait MonadErrorTests[F[_], E] extends ApplicativeErrorTests[F, E] with MonadTes "monadError rethrow attempt" -> forAll(laws.rethrowAttempt[A] _) ) } - } } object MonadErrorTests { diff --git a/laws/src/main/scala/cats/laws/discipline/MonadTests.scala b/laws/src/main/scala/cats/laws/discipline/MonadTests.scala index 2ac2aa16e21..506591edcf3 100644 --- a/laws/src/main/scala/cats/laws/discipline/MonadTests.scala +++ b/laws/src/main/scala/cats/laws/discipline/MonadTests.scala @@ -11,49 +11,48 @@ trait MonadTests[F[_]] extends ApplicativeTests[F] with FlatMapTests[F] { def laws: MonadLaws[F] def monad[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]], - CogenA: Cogen[A], - CogenB: Cogen[B], - CogenC: Cogen[C], - EqFA: Eq[F[A]], - EqFB: Eq[F[B]], - EqFC: Eq[F[C]], - EqFABC: Eq[F[(A, B, C)]], - EqFInt: Eq[F[Int]], - iso: Isomorphisms[F] - ): RuleSet = { + ArbFA: Arbitrary[F[A]], + ArbFB: Arbitrary[F[B]], + ArbFC: Arbitrary[F[C]], + ArbFAtoB: Arbitrary[F[A => B]], + ArbFBtoC: Arbitrary[F[B => C]], + CogenA: Cogen[A], + CogenB: Cogen[B], + CogenC: Cogen[C], + EqFA: Eq[F[A]], + EqFB: Eq[F[B]], + EqFC: Eq[F[C]], + EqFABC: Eq[F[(A, B, C)]], + EqFInt: Eq[F[Int]], + iso: Isomorphisms[F]): RuleSet = new RuleSet { def name: String = "monad" def bases: Seq[(String, RuleSet)] = Nil def parents: Seq[RuleSet] = Seq(applicative[A, B, C], flatMap[A, B, C]) - def props: Seq[(String, Prop)] = Seq( - "monad left identity" -> forAll(laws.monadLeftIdentity[A, B] _), - "monad right identity" -> forAll(laws.monadRightIdentity[A] _), - "map flatMap coherence" -> forAll(laws.mapFlatMapCoherence[A, B] _) - ) ++ (if (Platform.isJvm) Seq[(String, Prop)]("tailRecM stack safety" -> Prop.lzy(laws.tailRecMStackSafety)) else Seq.empty) + def props: Seq[(String, Prop)] = + Seq( + "monad left identity" -> forAll(laws.monadLeftIdentity[A, B] _), + "monad right identity" -> forAll(laws.monadRightIdentity[A] _), + "map flatMap coherence" -> forAll(laws.mapFlatMapCoherence[A, B] _) + ) ++ (if (Platform.isJvm) Seq[(String, Prop)]("tailRecM stack safety" -> Prop.lzy(laws.tailRecMStackSafety)) + else Seq.empty) } - } def stackUnsafeMonad[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]], - CogenA: Cogen[A], - CogenB: Cogen[B], - CogenC: Cogen[C], - EqFA: Eq[F[A]], - EqFB: Eq[F[B]], - EqFC: Eq[F[C]], - EqFABC: Eq[F[(A, B, C)]], - EqFInt: Eq[F[Int]], - iso: Isomorphisms[F] - ): RuleSet = { + ArbFA: Arbitrary[F[A]], + ArbFB: Arbitrary[F[B]], + ArbFC: Arbitrary[F[C]], + ArbFAtoB: Arbitrary[F[A => B]], + ArbFBtoC: Arbitrary[F[B => C]], + CogenA: Cogen[A], + CogenB: Cogen[B], + CogenC: Cogen[C], + EqFA: Eq[F[A]], + EqFB: Eq[F[B]], + EqFC: Eq[F[C]], + EqFABC: Eq[F[(A, B, C)]], + EqFInt: Eq[F[Int]], + iso: Isomorphisms[F]): RuleSet = new RuleSet { def name: String = "monad (stack-unsafe)" def bases: Seq[(String, RuleSet)] = Nil @@ -64,7 +63,6 @@ trait MonadTests[F[_]] extends ApplicativeTests[F] with FlatMapTests[F] { "map flatMap coherence" -> forAll(laws.mapFlatMapCoherence[A, B] _) ) } - } } object MonadTests { diff --git a/laws/src/main/scala/cats/laws/discipline/MonoidKTests.scala b/laws/src/main/scala/cats/laws/discipline/MonoidKTests.scala index 3ea259d0d03..5cabd7f0484 100644 --- a/laws/src/main/scala/cats/laws/discipline/MonoidKTests.scala +++ b/laws/src/main/scala/cats/laws/discipline/MonoidKTests.scala @@ -9,17 +9,17 @@ trait MonoidKTests[F[_]] extends SemigroupKTests[F] { def laws: MonoidKLaws[F] def monoidK[A: Arbitrary](implicit - ArbFA: Arbitrary[F[A]], - EqFA: Eq[F[A]] - ): RuleSet = + ArbFA: Arbitrary[F[A]], + EqFA: Eq[F[A]]): RuleSet = new DefaultRuleSet( "monoidK", Some(semigroupK[A]), "monoidK left identity" -> forAll(laws.monoidKLeftIdentity[A] _), - "monoidK right identity" -> forAll(laws.monoidKRightIdentity[A] _)) + "monoidK right identity" -> forAll(laws.monoidKRightIdentity[A] _) + ) } object MonoidKTests { - def apply[F[_] : MonoidK]: MonoidKTests[F] = + def apply[F[_]: MonoidK]: MonoidKTests[F] = new MonoidKTests[F] { def laws: MonoidKLaws[F] = MonoidKLaws[F] } } diff --git a/laws/src/main/scala/cats/laws/discipline/NonEmptyParallelTests.scala b/laws/src/main/scala/cats/laws/discipline/NonEmptyParallelTests.scala index 0112b8d8947..0dc268cb7b7 100644 --- a/laws/src/main/scala/cats/laws/discipline/NonEmptyParallelTests.scala +++ b/laws/src/main/scala/cats/laws/discipline/NonEmptyParallelTests.scala @@ -9,8 +9,14 @@ import org.typelevel.discipline.Laws trait NonEmptyParallelTests[M[_], F[_]] extends Laws { def laws: NonEmptyParallelLaws[M, F] - def nonEmptyParallel[A, B] - (implicit ArbA: Arbitrary[A], ArbM: Arbitrary[M[A]], ArbMb: Arbitrary[M[B]], Arbf: Arbitrary[A => B], EqMa: Eq[M[A]], EqMb: Eq[M[B]], ArbF: Arbitrary[F[A]], EqFa: Eq[F[A]]): RuleSet = + def nonEmptyParallel[A, B](implicit ArbA: Arbitrary[A], + ArbM: Arbitrary[M[A]], + ArbMb: Arbitrary[M[B]], + Arbf: Arbitrary[A => B], + EqMa: Eq[M[A]], + EqMb: Eq[M[B]], + ArbF: Arbitrary[F[A]], + EqFa: Eq[F[A]]): RuleSet = new DefaultRuleSet( "parallel", None, diff --git a/laws/src/main/scala/cats/laws/discipline/NonEmptyTraverseTests.scala b/laws/src/main/scala/cats/laws/discipline/NonEmptyTraverseTests.scala index 86e2438b6ce..7603236a83b 100644 --- a/laws/src/main/scala/cats/laws/discipline/NonEmptyTraverseTests.scala +++ b/laws/src/main/scala/cats/laws/discipline/NonEmptyTraverseTests.scala @@ -1,17 +1,16 @@ package cats.laws.discipline - import org.scalacheck.{Arbitrary, Cogen, Prop} import Prop.forAll import cats.kernel.CommutativeMonoid import cats.{Applicative, CommutativeApplicative, Eq, NonEmptyTraverse} import cats.laws.NonEmptyTraverseLaws - trait NonEmptyTraverseTests[F[_]] extends TraverseTests[F] with ReducibleTests[F] { def laws: NonEmptyTraverseLaws[F] - def nonEmptyTraverse[G[_]: Applicative, A: Arbitrary, B: Arbitrary, C: Arbitrary, M: Arbitrary, X[_], Y[_]](implicit + def nonEmptyTraverse[G[_]: Applicative, A: Arbitrary, B: Arbitrary, C: Arbitrary, M: Arbitrary, X[_], Y[_]]( + implicit ArbFA: Arbitrary[F[A]], ArbXB: Arbitrary[X[B]], ArbYB: Arbitrary[Y[B]], @@ -46,7 +45,7 @@ trait NonEmptyTraverseTests[F[_]] extends TraverseTests[F] with ReducibleTests[F EqYFM: Eq[Y[F[M]]], EqOptionA: Eq[Option[A]] ): RuleSet = { - implicit def EqXFBYFB : Eq[(X[F[B]], Y[F[B]])] = new Eq[(X[F[B]], Y[F[B]])] { + implicit def EqXFBYFB: Eq[(X[F[B]], Y[F[B]])] = new Eq[(X[F[B]], Y[F[B]])] { override def eqv(x: (X[F[B]], Y[F[B]]), y: (X[F[B]], Y[F[B]])): Boolean = EqXFB.eqv(x._1, y._1) && EqYFB.eqv(x._2, y._2) } @@ -56,7 +55,9 @@ trait NonEmptyTraverseTests[F[_]] extends TraverseTests[F] with ReducibleTests[F def parents: Seq[RuleSet] = Seq(traverse[A, B, C, M, X, Y], reducible[G, A, B]) def props: Seq[(String, Prop)] = Seq( "nonEmptyTraverse identity" -> forAll(laws.nonEmptyTraverseIdentity[A, C] _), - "nonEmptyTraverse sequential composition" -> forAll(laws.nonEmptyTraverseSequentialComposition[A, B, C, X, Y] _), + "nonEmptyTraverse sequential composition" -> forAll( + laws.nonEmptyTraverseSequentialComposition[A, B, C, X, Y] _ + ), "nonEmptyTraverse parallel composition" -> forAll(laws.nonEmptyTraverseParallelComposition[A, B, X, Y] _), "nonEmptyTraverse derive reduceMap" -> forAll(laws.reduceMapDerived[A, M] _) ) diff --git a/laws/src/main/scala/cats/laws/discipline/ParallelTests.scala b/laws/src/main/scala/cats/laws/discipline/ParallelTests.scala index 7c66bdfeb8b..4b1cba0b9d6 100644 --- a/laws/src/main/scala/cats/laws/discipline/ParallelTests.scala +++ b/laws/src/main/scala/cats/laws/discipline/ParallelTests.scala @@ -8,8 +8,14 @@ import org.scalacheck.Prop.forAll trait ParallelTests[M[_], F[_]] extends NonEmptyParallelTests[M, F] { def laws: ParallelLaws[M, F] - def parallel[A, B] - (implicit ArbA: Arbitrary[A], ArbM: Arbitrary[M[A]], ArbMb: Arbitrary[M[B]], Arbf: Arbitrary[A => B], EqMa: Eq[M[A]], EqMb: Eq[M[B]], ArbF: Arbitrary[F[A]], EqFa: Eq[F[A]]): RuleSet = + def parallel[A, B](implicit ArbA: Arbitrary[A], + ArbM: Arbitrary[M[A]], + ArbMb: Arbitrary[M[B]], + Arbf: Arbitrary[A => B], + EqMa: Eq[M[A]], + EqMb: Eq[M[B]], + ArbF: Arbitrary[F[A]], + EqFa: Eq[F[A]]): RuleSet = new DefaultRuleSet( "parallel", Some(nonEmptyParallel[A, B]), diff --git a/laws/src/main/scala/cats/laws/discipline/ProfunctorTests.scala b/laws/src/main/scala/cats/laws/discipline/ProfunctorTests.scala index 5d94255c702..30d08656bad 100644 --- a/laws/src/main/scala/cats/laws/discipline/ProfunctorTests.scala +++ b/laws/src/main/scala/cats/laws/discipline/ProfunctorTests.scala @@ -10,7 +10,8 @@ import org.typelevel.discipline.Laws trait ProfunctorTests[F[_, _]] extends Laws { def laws: ProfunctorLaws[F] - def profunctor[A: Arbitrary, B: Arbitrary, C: Arbitrary, D: Arbitrary, E: Arbitrary, G: Arbitrary](implicit + def profunctor[A: Arbitrary, B: Arbitrary, C: Arbitrary, D: Arbitrary, E: Arbitrary, G: Arbitrary]( + implicit ArbFAB: Arbitrary[F[A, B]], ArbFCD: Arbitrary[F[C, D]], CogenA: Cogen[A], @@ -30,7 +31,8 @@ trait ProfunctorTests[F[_, _]] extends Laws { "profunctor lmap identity" -> forAll(laws.profunctorLmapIdentity[A, B] _), "profunctor rmap identity" -> forAll(laws.profunctorRmapIdentity[A, B] _), "profunctor lmap composition" -> forAll(laws.profunctorLmapComposition[A, B, C, D] _), - "profunctor rmap composition" -> forAll(laws.profunctorRmapComposition[A, D, C, B] _)) + "profunctor rmap composition" -> forAll(laws.profunctorRmapComposition[A, D, C, B] _) + ) } object ProfunctorTests { diff --git a/laws/src/main/scala/cats/laws/discipline/ReducibleTests.scala b/laws/src/main/scala/cats/laws/discipline/ReducibleTests.scala index 5a61a886015..0b260bef232 100644 --- a/laws/src/main/scala/cats/laws/discipline/ReducibleTests.scala +++ b/laws/src/main/scala/cats/laws/discipline/ReducibleTests.scala @@ -12,20 +12,19 @@ trait ReducibleTests[F[_]] extends FoldableTests[F] { def laws: ReducibleLaws[F] def reducible[G[_]: Applicative, A: Arbitrary, B: Arbitrary](implicit - ArbFA: Arbitrary[F[A]], - ArbFB: Arbitrary[F[B]], - ArbFGA: Arbitrary[F[G[A]]], - ArbGB: Arbitrary[G[B]], - CogenA: Cogen[A], - CogenB: Cogen[B], - EqG: Eq[G[Unit]], - EqA: Eq[A], - EqB: Eq[B], - EqFA: Eq[F[A]], - EqOptionA: Eq[Option[A]], - MonoidA: CommutativeMonoid[A], - MonoidB: CommutativeMonoid[B] - ): RuleSet = + ArbFA: Arbitrary[F[A]], + ArbFB: Arbitrary[F[B]], + ArbFGA: Arbitrary[F[G[A]]], + ArbGB: Arbitrary[G[B]], + CogenA: Cogen[A], + CogenB: Cogen[B], + EqG: Eq[G[Unit]], + EqA: Eq[A], + EqB: Eq[B], + EqFA: Eq[F[A]], + EqOptionA: Eq[Option[A]], + MonoidA: CommutativeMonoid[A], + MonoidB: CommutativeMonoid[B]): RuleSet = new DefaultRuleSet( name = "reducible", parent = Some(foldable[A, B]), @@ -44,6 +43,6 @@ trait ReducibleTests[F[_]] extends FoldableTests[F] { } object ReducibleTests { - def apply[F[_] : Reducible]: ReducibleTests[F] = + def apply[F[_]: Reducible]: ReducibleTests[F] = new ReducibleTests[F] { def laws: ReducibleLaws[F] = ReducibleLaws[F] } } diff --git a/laws/src/main/scala/cats/laws/discipline/RepresentableTests.scala b/laws/src/main/scala/cats/laws/discipline/RepresentableTests.scala index f62bd9e53fa..2630f379fa7 100644 --- a/laws/src/main/scala/cats/laws/discipline/RepresentableTests.scala +++ b/laws/src/main/scala/cats/laws/discipline/RepresentableTests.scala @@ -8,25 +8,24 @@ import org.scalacheck.Prop._ trait RepresentableTests[F[_], R] extends Laws { - val laws: RepresentableLaws[F, R] + val laws: RepresentableLaws[F, R] - def representable[A](implicit - ArbA: Arbitrary[A], - ArbFA: Arbitrary[F[A]], - ArbRep: Arbitrary[R], - ArbRepFn: Arbitrary[R => A], - EqFA: Eq[F[A]], - EqA: Eq[A] - ): RuleSet = new DefaultRuleSet( - name = "representable", - parent = None, - "index andThen tabulate = id" -> forAll(laws.indexTabulateIsId[A] _), - "tabulate andThen index = id" -> forAll(laws.tabulateIndexIsId[A] _) - ) + def representable[A](implicit + ArbA: Arbitrary[A], + ArbFA: Arbitrary[F[A]], + ArbRep: Arbitrary[R], + ArbRepFn: Arbitrary[R => A], + EqFA: Eq[F[A]], + EqA: Eq[A]): RuleSet = new DefaultRuleSet( + name = "representable", + parent = None, + "index andThen tabulate = id" -> forAll(laws.indexTabulateIsId[A] _), + "tabulate andThen index = id" -> forAll(laws.tabulateIndexIsId[A] _) + ) } object RepresentableTests { def apply[F[_], R](implicit RF: Representable.Aux[F, R]): RepresentableTests[F, R] = new RepresentableTests[F, R] { - override implicit val laws: RepresentableLaws[F, R] = RepresentableLaws[F, R] + implicit override val laws: RepresentableLaws[F, R] = RepresentableLaws[F, R] } } diff --git a/laws/src/main/scala/cats/laws/discipline/SemigroupKTests.scala b/laws/src/main/scala/cats/laws/discipline/SemigroupKTests.scala index ca4525eea84..54c9e569f73 100644 --- a/laws/src/main/scala/cats/laws/discipline/SemigroupKTests.scala +++ b/laws/src/main/scala/cats/laws/discipline/SemigroupKTests.scala @@ -10,13 +10,9 @@ trait SemigroupKTests[F[_]] extends Laws { def laws: SemigroupKLaws[F] def semigroupK[A: Arbitrary](implicit - ArbFA: Arbitrary[F[A]], - EqFA: Eq[F[A]] - ): RuleSet = - new DefaultRuleSet( - "semigroupK", - None, - "semigroupK associative" -> forAll(laws.semigroupKAssociative[A] _)) + ArbFA: Arbitrary[F[A]], + EqFA: Eq[F[A]]): RuleSet = + new DefaultRuleSet("semigroupK", None, "semigroupK associative" -> forAll(laws.semigroupKAssociative[A] _)) } object SemigroupKTests { diff --git a/laws/src/main/scala/cats/laws/discipline/SemigroupalTests.scala b/laws/src/main/scala/cats/laws/discipline/SemigroupalTests.scala index 228d8e9cadb..7ec8c88ec45 100644 --- a/laws/src/main/scala/cats/laws/discipline/SemigroupalTests.scala +++ b/laws/src/main/scala/cats/laws/discipline/SemigroupalTests.scala @@ -11,24 +11,24 @@ import org.typelevel.discipline.Laws trait SemigroupalTests[F[_]] extends Laws { def laws: SemigroupalLaws[F] - def semigroupal[A : Arbitrary, B : Arbitrary, C : Arbitrary](implicit - iso: Isomorphisms[F], - ArbFA: Arbitrary[F[A]], - ArbFB: Arbitrary[F[B]], - ArbFC: Arbitrary[F[C]], - EqFA: Eq[F[A]], - EqFABC: Eq[F[(A, B, C)]] - ): RuleSet = { + def semigroupal[A: Arbitrary, B: Arbitrary, C: Arbitrary](implicit + iso: Isomorphisms[F], + ArbFA: Arbitrary[F[A]], + ArbFB: Arbitrary[F[B]], + ArbFC: Arbitrary[F[C]], + EqFA: Eq[F[A]], + EqFABC: Eq[F[(A, B, C)]]): RuleSet = new DefaultRuleSet( name = "semigroupal", parent = None, - "semigroupal associativity" -> forAll((fa: F[A], fb: F[B], fc: F[C]) => iso.associativity(laws.semigroupalAssociativity(fa, fb, fc))) + "semigroupal associativity" -> forAll( + (fa: F[A], fb: F[B], fc: F[C]) => iso.associativity(laws.semigroupalAssociativity(fa, fb, fc)) + ) ) - } } object SemigroupalTests { - def apply[F[_] : Semigroupal](implicit ev: Isomorphisms[F]): SemigroupalTests[F] = + def apply[F[_]: Semigroupal](implicit ev: Isomorphisms[F]): SemigroupalTests[F] = new SemigroupalTests[F] { val laws: SemigroupalLaws[F] = SemigroupalLaws[F] } trait Isomorphisms[F[_]] { @@ -43,14 +43,18 @@ object SemigroupalTests { implicit def invariant[F[_]](implicit F: Invariant[F]): Isomorphisms[F] = new Isomorphisms[F] { def associativity[A, B, C](fs: (F[(A, (B, C))], F[((A, B), C)])): IsEq[F[(A, B, C)]] = - F.imap(fs._1) { case (a, (b, c)) => (a, b, c) } { case (a, b, c) => (a, (b, c)) } <-> - F.imap(fs._2) { case ((a, b), c) => (a, b, c) } { case (a, b, c) => ((a, b), c) } + F.imap(fs._1) { case (a, (b, c)) => (a, b, c) } { case (a, b, c) => (a, (b, c)) } <-> + F.imap(fs._2) { case ((a, b), c) => (a, b, c) } { case (a, b, c) => ((a, b), c) } def leftIdentity[A](fs: (F[(Unit, A)], F[A])): IsEq[F[A]] = - F.imap(fs._1) { case (_, a) => a } { a => ((), a) } <-> fs._2 + F.imap(fs._1) { case (_, a) => a } { a => + ((), a) + } <-> fs._2 def rightIdentity[A](fs: (F[(A, Unit)], F[A])): IsEq[F[A]] = - F.imap(fs._1) { case (a, _) => a } { a => (a, ()) } <-> fs._2 + F.imap(fs._1) { case (a, _) => a } { a => + (a, ()) + } <-> fs._2 } } diff --git a/laws/src/main/scala/cats/laws/discipline/StrongTests.scala b/laws/src/main/scala/cats/laws/discipline/StrongTests.scala index 83fb8279bc7..d6d4c7fa029 100644 --- a/laws/src/main/scala/cats/laws/discipline/StrongTests.scala +++ b/laws/src/main/scala/cats/laws/discipline/StrongTests.scala @@ -9,7 +9,8 @@ import cats.arrow.Strong trait StrongTests[F[_, _]] extends ProfunctorTests[F] { def laws: StrongLaws[F] - def strong[A: Arbitrary, B: Arbitrary, C: Arbitrary, D: Arbitrary, E: Arbitrary, G: Arbitrary](implicit + def strong[A: Arbitrary, B: Arbitrary, C: Arbitrary, D: Arbitrary, E: Arbitrary, G: Arbitrary]( + implicit ArbFAB: Arbitrary[F[A, B]], ArbFBC: Arbitrary[F[B, C]], ArbFCD: Arbitrary[F[C, D]], @@ -28,7 +29,8 @@ trait StrongTests[F[_, _]] extends ProfunctorTests[F] { name = "strong", parent = Some(profunctor[A, B, C, D, E, G]), "strong first distributivity" -> forAll(laws.strongFirstDistributivity[A, B, C, D, E] _), - "strong second distributivity" -> forAll(laws.strongSecondDistributivity[A, B, C, D, E] _)) + "strong second distributivity" -> forAll(laws.strongSecondDistributivity[A, B, C, D, E] _) + ) } object StrongTests { diff --git a/laws/src/main/scala/cats/laws/discipline/TraverseFilterTests.scala b/laws/src/main/scala/cats/laws/discipline/TraverseFilterTests.scala index 77dc281eec3..342bf10b790 100644 --- a/laws/src/main/scala/cats/laws/discipline/TraverseFilterTests.scala +++ b/laws/src/main/scala/cats/laws/discipline/TraverseFilterTests.scala @@ -11,23 +11,22 @@ trait TraverseFilterTests[F[_]] extends FunctorFilterTests[F] { def laws: TraverseFilterLaws[F] def traverseFilter[A, B, C](implicit - ArbFA: Arbitrary[F[A]], - ArbFOA: Arbitrary[F[Option[A]]], - ArbFABoo: Arbitrary[PartialFunction[A, B]], - ArbAOB: Arbitrary[A => Option[B]], - ArbAOA: Arbitrary[A => Option[A]], - ArbAOOB: Arbitrary[A => Option[Option[B]]], - ArbBOC: Arbitrary[B => Option[C]], - ArbBOOC: Arbitrary[B => Option[Option[C]]], - ArbAB: Arbitrary[A => B], - ArbABoo: Arbitrary[A => Boolean], - ArbAOBoo: Arbitrary[A => Option[Boolean]], - EqFA: Eq[F[A]], - EqFB: Eq[F[B]], - EqFC: Eq[F[C]], - EqGFA: Eq[Option[F[A]]], - EqMNFC: Eq[Nested[Option, Option, F[C]]] - ): RuleSet = { + ArbFA: Arbitrary[F[A]], + ArbFOA: Arbitrary[F[Option[A]]], + ArbFABoo: Arbitrary[PartialFunction[A, B]], + ArbAOB: Arbitrary[A => Option[B]], + ArbAOA: Arbitrary[A => Option[A]], + ArbAOOB: Arbitrary[A => Option[Option[B]]], + ArbBOC: Arbitrary[B => Option[C]], + ArbBOOC: Arbitrary[B => Option[Option[C]]], + ArbAB: Arbitrary[A => B], + ArbABoo: Arbitrary[A => Boolean], + ArbAOBoo: Arbitrary[A => Option[Boolean]], + EqFA: Eq[F[A]], + EqFB: Eq[F[B]], + EqFC: Eq[F[C]], + EqGFA: Eq[Option[F[A]]], + EqMNFC: Eq[Nested[Option, Option, F[C]]]): RuleSet = new DefaultRuleSet( name = "traverseFilter", parent = Some(functorFilter[A, B, C]), @@ -36,7 +35,6 @@ trait TraverseFilterTests[F[_]] extends FunctorFilterTests[F] { "traverseFilter consistent with traverse" -> forAll(laws.traverseFilterConsistentWithTraverse[Option, A] _), "filterA consistent with traverseFilter" -> forAll(laws.filterAConsistentWithTraverseFilter[Option, A] _) ) - } } object TraverseFilterTests { diff --git a/laws/src/main/scala/cats/laws/discipline/TraverseTests.scala b/laws/src/main/scala/cats/laws/discipline/TraverseTests.scala index 6171e64a03c..41455de7015 100644 --- a/laws/src/main/scala/cats/laws/discipline/TraverseTests.scala +++ b/laws/src/main/scala/cats/laws/discipline/TraverseTests.scala @@ -10,8 +10,8 @@ import Prop._ trait TraverseTests[F[_]] extends FunctorTests[F] with FoldableTests[F] with UnorderedTraverseTests[F] { def laws: TraverseLaws[F] - - def traverse[A: Arbitrary, B: Arbitrary, C: Arbitrary, M: Arbitrary, X[_]: CommutativeApplicative, Y[_]: CommutativeApplicative](implicit + def traverse[A: Arbitrary, B: Arbitrary, C: Arbitrary, M: Arbitrary, X[_]: CommutativeApplicative, Y[_]: CommutativeApplicative]( + implicit ArbFA: Arbitrary[F[A]], ArbFB: Arbitrary[F[B]], ArbXB: Arbitrary[X[B]], @@ -37,7 +37,7 @@ trait TraverseTests[F[_]] extends FunctorTests[F] with FoldableTests[F] with Uno EqYFM: Eq[Y[F[M]]], EqOptionA: Eq[Option[A]] ): RuleSet = { - implicit def EqXFBYFB : Eq[(X[F[B]], Y[F[B]])] = new Eq[(X[F[B]], Y[F[B]])] { + implicit def EqXFBYFB: Eq[(X[F[B]], Y[F[B]])] = new Eq[(X[F[B]], Y[F[B]])] { override def eqv(x: (X[F[B]], Y[F[B]]), y: (X[F[B]], Y[F[B]])): Boolean = EqXFB.eqv(x._1, y._1) && EqYFB.eqv(x._2, y._2) } diff --git a/laws/src/main/scala/cats/laws/discipline/UnorderedFoldableTests.scala b/laws/src/main/scala/cats/laws/discipline/UnorderedFoldableTests.scala index bdbd5c8a881..321e84a5f0e 100644 --- a/laws/src/main/scala/cats/laws/discipline/UnorderedFoldableTests.scala +++ b/laws/src/main/scala/cats/laws/discipline/UnorderedFoldableTests.scala @@ -11,16 +11,14 @@ import cats.instances.boolean._ trait UnorderedFoldableTests[F[_]] extends Laws { def laws: UnorderedFoldableLaws[F] - def unorderedFoldable[A: Arbitrary, B: Arbitrary](implicit - ArbFA: Arbitrary[F[A]], - ArbF: Arbitrary[A => B], - CogenA: Cogen[A], - A: CommutativeMonoid[A], - B: CommutativeMonoid[B], - EqFA: Eq[A], - EqFB: Eq[B] - ): RuleSet = + ArbFA: Arbitrary[F[A]], + ArbF: Arbitrary[A => B], + CogenA: Cogen[A], + A: CommutativeMonoid[A], + B: CommutativeMonoid[B], + EqFA: Eq[A], + EqFB: Eq[B]): RuleSet = new DefaultRuleSet( name = "unorderedFoldable", parent = None, diff --git a/laws/src/main/scala/cats/laws/discipline/UnorderedTraverseTests.scala b/laws/src/main/scala/cats/laws/discipline/UnorderedTraverseTests.scala index 161354fabf6..9edc6bdb339 100644 --- a/laws/src/main/scala/cats/laws/discipline/UnorderedTraverseTests.scala +++ b/laws/src/main/scala/cats/laws/discipline/UnorderedTraverseTests.scala @@ -9,34 +9,35 @@ import cats.kernel.CommutativeMonoid trait UnorderedTraverseTests[F[_]] extends UnorderedFoldableTests[F] { def laws: UnorderedTraverseLaws[F] - - def unorderedTraverse[A: Arbitrary, B: Arbitrary, C: Arbitrary, X[_]: CommutativeApplicative, Y[_]: CommutativeApplicative] - (implicit ArbFA: Arbitrary[F[A]], - ArbFXB: Arbitrary[F[X[B]]], - ArbXB: Arbitrary[X[B]], - ArbYB: Arbitrary[Y[B]], - ArbYC: Arbitrary[Y[C]], - CogenA: Cogen[A], - CogenB: Cogen[B], - Ca: CommutativeMonoid[A], - Cb: CommutativeMonoid[B], - EqA: Eq[A], - EqB: Eq[B], - EqXYFC: Eq[X[Y[F[C]]]], - EqXFB: Eq[X[F[B]]], - EqYFB: Eq[Y[F[B]]] + def unorderedTraverse[A: Arbitrary, B: Arbitrary, C: Arbitrary, X[_]: CommutativeApplicative, Y[_]: CommutativeApplicative]( + implicit ArbFA: Arbitrary[F[A]], + ArbFXB: Arbitrary[F[X[B]]], + ArbXB: Arbitrary[X[B]], + ArbYB: Arbitrary[Y[B]], + ArbYC: Arbitrary[Y[C]], + CogenA: Cogen[A], + CogenB: Cogen[B], + Ca: CommutativeMonoid[A], + Cb: CommutativeMonoid[B], + EqA: Eq[A], + EqB: Eq[B], + EqXYFC: Eq[X[Y[F[C]]]], + EqXFB: Eq[X[F[B]]], + EqYFB: Eq[Y[F[B]]] ): RuleSet = { - implicit def EqXFBYFB : Eq[(X[F[B]], Y[F[B]])] = new Eq[(X[F[B]], Y[F[B]])] { + implicit def EqXFBYFB: Eq[(X[F[B]], Y[F[B]])] = new Eq[(X[F[B]], Y[F[B]])] { override def eqv(x: (X[F[B]], Y[F[B]]), y: (X[F[B]], Y[F[B]])): Boolean = EqXFB.eqv(x._1, y._1) && EqYFB.eqv(x._2, y._2) } new DefaultRuleSet( name = "unorderedTraverse", parent = Some(unorderedFoldable[A, B]), - "unordered traverse sequential composition" -> forAll(laws.unorderedTraverseSequentialComposition[A, B, C, X, Y] _), - "unordered traverse parallel composition" -> forAll(laws.unorderedTraverseParallelComposition[A, B, X, Y] _), - "unordered traverse consistent with sequence" -> forAll(laws.unorderedSequenceConsistent[B, X] _) - ) + "unordered traverse sequential composition" -> forAll( + laws.unorderedTraverseSequentialComposition[A, B, C, X, Y] _ + ), + "unordered traverse parallel composition" -> forAll(laws.unorderedTraverseParallelComposition[A, B, X, Y] _), + "unordered traverse consistent with sequence" -> forAll(laws.unorderedSequenceConsistent[B, X] _) + ) } } diff --git a/macros/src/main/scala/cats/macros/Ops.scala b/macros/src/main/scala/cats/macros/Ops.scala index 7dfadc892b9..0a832019bb2 100644 --- a/macros/src/main/scala/cats/macros/Ops.scala +++ b/macros/src/main/scala/cats/macros/Ops.scala @@ -15,7 +15,8 @@ object Ops extends machinist.Ops { ("<=", "lteqv"), ("|+|", "combine"), ("|-|", "remove") - ).map{ case (k, v) => - (NameTransformer.encode(k), v) + ).map { + case (k, v) => + (NameTransformer.encode(k), v) }.toMap } diff --git a/project/Boilerplate.scala b/project/Boilerplate.scala index e84f06a2257..bb4829cbe68 100644 --- a/project/Boilerplate.scala +++ b/project/Boilerplate.scala @@ -1,29 +1,26 @@ import sbt._ /** - * Copied, with some modifications, from https://github.com/milessabin/shapeless/blob/master/project/Boilerplate.scala - * - * Generate a range of boilerplate classes, those offering alternatives with 0-22 params - * and would be tedious to craft by hand - * - * @author Miles Sabin - * @author Kevin Wright - */ - - + * Copied, with some modifications, from https://github.com/milessabin/shapeless/blob/master/project/Boilerplate.scala + * + * Generate a range of boilerplate classes, those offering alternatives with 0-22 params + * and would be tedious to craft by hand + * + * @author Miles Sabin + * @author Kevin Wright + */ object Boilerplate { import scala.StringContext._ implicit final class BlockHelper(val sc: StringContext) extends AnyVal { def block(args: Any*): String = { val interpolated = sc.standardInterpolator(treatEscapes, args) - val rawLines = interpolated split '\n' - val trimmedLines = rawLines map { _ dropWhile (_.isWhitespace) } - trimmedLines mkString "\n" + val rawLines = interpolated.split('\n') + val trimmedLines = rawLines.map { _.dropWhile(_.isWhitespace) } + trimmedLines.mkString("\n") } } - val templates: Seq[Template] = Seq( GenSemigroupalBuilders, GenSemigroupalArityFunctions, @@ -36,9 +33,8 @@ object Boilerplate { val header = "// auto-generated boilerplate by /project/Boilerplate.scala" // TODO: put something meaningful here? - /** Returns a seq of the generated files. As a side-effect, it actually generates them... */ - def gen(dir : File) = for(t <- templates) yield { + def gen(dir: File) = for (t <- templates) yield { val tgtFile = t.filename(dir) IO.write(tgtFile, t.body) tgtFile @@ -47,42 +43,43 @@ object Boilerplate { val maxArity = 22 final class TemplateVals(val arity: Int) { - val synTypes = (0 until arity) map (n => s"A$n") - val synVals = (0 until arity) map (n => s"a$n") - val synTypedVals = (synVals zip synTypes) map { case (v,t) => v + ":" + t} - val `A..N` = synTypes.mkString(", ") - val `a..n` = synVals.mkString(", ") - val `_.._` = Seq.fill(arity)("_").mkString(", ") - val `(A..N)` = if (arity == 1) "Tuple1[A]" else synTypes.mkString("(", ", ", ")") - val `(_.._)` = if (arity == 1) "Tuple1[_]" else Seq.fill(arity)("_").mkString("(", ", ", ")") - val `(a..n)` = if (arity == 1) "Tuple1(a)" else synVals.mkString("(", ", ", ")") - val `a:A..n:N` = synTypedVals mkString ", " + val synTypes = (0 until arity).map(n => s"A$n") + val synVals = (0 until arity).map(n => s"a$n") + val synTypedVals = (synVals.zip(synTypes)).map { case (v, t) => v + ":" + t } + val `A..N` = synTypes.mkString(", ") + val `a..n` = synVals.mkString(", ") + val `_.._` = Seq.fill(arity)("_").mkString(", ") + val `(A..N)` = if (arity == 1) "Tuple1[A]" else synTypes.mkString("(", ", ", ")") + val `(_.._)` = if (arity == 1) "Tuple1[_]" else Seq.fill(arity)("_").mkString("(", ", ", ")") + val `(a..n)` = if (arity == 1) "Tuple1(a)" else synVals.mkString("(", ", ", ")") + val `a:A..n:N` = synTypedVals.mkString(", ") } trait Template { - def filename(root: File):File + def filename(root: File): File def content(tv: TemplateVals): String def range = 1 to maxArity def body: String = { def expandInstances(contents: IndexedSeq[Array[String]], acc: Array[String] = Array.empty): Array[String] = - if (!contents.exists(_ exists(_ startsWith "-"))) - acc map (_.tail) + if (!contents.exists(_.exists(_.startsWith("-")))) + acc.map(_.tail) else { - val pre = contents.head takeWhile (_ startsWith "|") - val instances = contents flatMap {_ dropWhile (_ startsWith "|") takeWhile (_ startsWith "-") } - val next = contents map {_ dropWhile (_ startsWith "|") dropWhile (_ startsWith "-") } + val pre = contents.head.takeWhile(_.startsWith("|")) + val instances = contents.flatMap { _.dropWhile(_.startsWith("|")).takeWhile(_.startsWith("-")) } + val next = contents.map { _.dropWhile(_.startsWith("|")).dropWhile(_.startsWith("-")) } expandInstances(next, acc ++ pre ++ instances) } - val rawContents = range map { n => content(new TemplateVals(n)) split '\n' filterNot (_.isEmpty) } - val headerLines = header split '\n' + val rawContents = range.map { n => + content(new TemplateVals(n)).split('\n').filterNot(_.isEmpty) + } + val headerLines = header.split('\n') val instances = expandInstances(rawContents) - val footerLines = rawContents.head.reverse.takeWhile(_ startsWith "|").map(_.tail).reverse - (headerLines ++ instances ++ footerLines) mkString "\n" + val footerLines = rawContents.head.reverse.takeWhile(_.startsWith("|")).map(_.tail).reverse + (headerLines ++ instances ++ footerLines).mkString("\n") } } - /* Blocks in the templates below use a custom interpolator, combined with post-processing to produce the body @@ -96,17 +93,19 @@ object Boilerplate { - Then the last block of lines prefixed with '|' The block otherwise behaves as a standard interpolated string with regards to variable substitution. - */ + */ object GenSemigroupalBuilders extends Template { - def filename(root: File) = root / "cats" / "syntax" / "SemigroupalBuilder.scala" + def filename(root: File) = root / "cats" / "syntax" / "SemigroupalBuilder.scala" def content(tv: TemplateVals) = { import tv._ - val tpes = synTypes map { tpe => s"F[$tpe]" } - val tpesString = synTypes mkString ", " - val params = (synVals zip tpes) map { case (v,t) => s"$v:$t"} mkString ", " + val tpes = synTypes.map { tpe => + s"F[$tpe]" + } + val tpesString = synTypes.mkString(", ") + val params = (synVals.zip(tpes)).map { case (v, t) => s"$v:$t" }.mkString(", ") val next = if (arity + 1 <= maxArity) { s"def |@|[Z](z: F[Z]) = new SemigroupalBuilder${arity + 1}(${`a..n`}, z)" } else { @@ -116,16 +115,22 @@ object Boilerplate { val n = if (arity == 1) { "" } else { arity.toString } val map = - if (arity == 1) s"def map[Z](f: (${`A..N`}) => Z)(implicit functor: Functor[F]): F[Z] = functor.map(${`a..n`})(f)" - else s"def map[Z](f: (${`A..N`}) => Z)(implicit functor: Functor[F], semigroupal: Semigroupal[F]): F[Z] = Semigroupal.map$n(${`a..n`})(f)" + if (arity == 1) + s"def map[Z](f: (${`A..N`}) => Z)(implicit functor: Functor[F]): F[Z] = functor.map(${`a..n`})(f)" + else + s"def map[Z](f: (${`A..N`}) => Z)(implicit functor: Functor[F], semigroupal: Semigroupal[F]): F[Z] = Semigroupal.map$n(${`a..n`})(f)" val contramap = - if (arity == 1) s"def contramap[Z](f: Z => (${`A..N`}))(implicit contravariant: Contravariant[F]): F[Z] = contravariant.contramap(${`a..n`})(f)" - else s"def contramap[Z](f: Z => (${`A..N`}))(implicit contravariant: Contravariant[F], semigroupal: Semigroupal[F]): F[Z] = Semigroupal.contramap$n(${`a..n`})(f)" + if (arity == 1) + s"def contramap[Z](f: Z => (${`A..N`}))(implicit contravariant: Contravariant[F]): F[Z] = contravariant.contramap(${`a..n`})(f)" + else + s"def contramap[Z](f: Z => (${`A..N`}))(implicit contravariant: Contravariant[F], semigroupal: Semigroupal[F]): F[Z] = Semigroupal.contramap$n(${`a..n`})(f)" val imap = - if (arity == 1) s"def imap[Z](f: (${`A..N`}) => Z)(g: Z => (${`A..N`}))(implicit invariant: Invariant[F]): F[Z] = invariant.imap(${`a..n`})(f)(g)" - else s"def imap[Z](f: (${`A..N`}) => Z)(g: Z => (${`A..N`}))(implicit invariant: Invariant[F], semigroupal: Semigroupal[F]): F[Z] = Semigroupal.imap$n(${`a..n`})(f)(g)" + if (arity == 1) + s"def imap[Z](f: (${`A..N`}) => Z)(g: Z => (${`A..N`}))(implicit invariant: Invariant[F]): F[Z] = invariant.imap(${`a..n`})(f)(g)" + else + s"def imap[Z](f: (${`A..N`}) => Z)(g: Z => (${`A..N`}))(implicit invariant: Invariant[F], semigroupal: Semigroupal[F]): F[Z] = Semigroupal.imap$n(${`a..n`})(f)(g)" val tupled = if (arity != 1) { s"def tupled(implicit invariant: Invariant[F], semigroupal: Semigroupal[F]): F[(${`A..N`})] = Semigroupal.tuple$n(${`a..n`})" @@ -134,15 +139,15 @@ object Boilerplate { } block""" - |package cats - |package syntax - | - | - | - |@deprecated("replaced by apply syntax", "1.0.0-MF") - |private[syntax] final class SemigroupalBuilder[F[_]] { - | def |@|[A](a: F[A]) = new SemigroupalBuilder1(a) - | + |package cats + |package syntax + | + | + | + |@deprecated("replaced by apply syntax", "1.0.0-MF") + |private[syntax] final class SemigroupalBuilder[F[_]] { + | def |@|[A](a: F[A]) = new SemigroupalBuilder1(a) + | - private[syntax] final class SemigroupalBuilder$arity[${`A..N`}]($params) { - $next - def apWith[Z](f: F[(${`A..N`}) => Z])(implicit apply: Apply[F]): F[Z] = apply.ap$n(f)(${`a..n`}) @@ -151,7 +156,7 @@ object Boilerplate { - $imap - $tupled - } - |} + |} """ } } @@ -162,19 +167,29 @@ object Boilerplate { def content(tv: TemplateVals) = { import tv._ - val tpes = synTypes map { tpe => s"F[$tpe]" } - val fargs = (0 until arity) map { "f" + _ } - val fparams = (fargs zip tpes) map { case (v,t) => s"$v:$t"} mkString ", " + val tpes = synTypes.map { tpe => + s"F[$tpe]" + } + val fargs = (0 until arity).map { "f" + _ } + val fparams = (fargs.zip(tpes)).map { case (v, t) => s"$v:$t" }.mkString(", ") val a = arity / 2 val b = arity - a - val fArgsA = (0 until a) map { "f" + _ } mkString "," - val fArgsB = (a until arity) map { "f" + _ } mkString "," - val argsA = (0 until a) map { n => "a" + n + ":A" + n } mkString "," - val argsB = (a until arity) map { n => "a" + n + ":A" + n } mkString "," + val fArgsA = (0 until a).map { "f" + _ }.mkString(",") + val fArgsB = (a until arity).map { "f" + _ }.mkString(",") + val argsA = (0 until a) + .map { n => + "a" + n + ":A" + n + } + .mkString(",") + val argsB = (a until arity) + .map { n => + "a" + n + ":A" + n + } + .mkString(",") def apN(n: Int) = if (n == 1) { "ap" } else { s"ap$n" } - def allArgs = (0 until arity) map { "a" + _ } mkString "," + def allArgs = (0 until arity).map { "a" + _ }.mkString(",") val apply = block""" @@ -184,38 +199,39 @@ object Boilerplate { """ block""" - |package cats - | - |/** - | * @groupprio Ungrouped 0 - | * - | * @groupname ApArity ap arity - | * @groupdesc ApArity Higher-arity ap methods - | * @groupprio ApArity 999 - | * - | * @groupname MapArity map arity - | * @groupdesc MapArity Higher-arity map methods - | * @groupprio MapArity 999 - | * - | * @groupname TupleArity tuple arity - | * @groupdesc TupleArity Higher-arity tuple methods - | * @groupprio TupleArity 999 - | */ - |trait ApplyArityFunctions[F[_]] { self: Apply[F] => - | def tuple2[A, B](f1: F[A], f2: F[B]): F[(A, B)] = Semigroupal.tuple2(f1, f2)(self, self) + |package cats + | + |/** + | * @groupprio Ungrouped 0 + | * + | * @groupname ApArity ap arity + | * @groupdesc ApArity Higher-arity ap methods + | * @groupprio ApArity 999 + | * + | * @groupname MapArity map arity + | * @groupdesc MapArity Higher-arity map methods + | * @groupprio MapArity 999 + | * + | * @groupname TupleArity tuple arity + | * @groupdesc TupleArity Higher-arity tuple methods + | * @groupprio TupleArity 999 + | */ + |trait ApplyArityFunctions[F[_]] { self: Apply[F] => + | def tuple2[A, B](f1: F[A], f2: F[B]): F[(A, B)] = Semigroupal.tuple2(f1, f2)(self, self) - /** @group ApArity */ - def ap$arity[${`A..N`}, Z](f: F[(${`A..N`}) => Z])($fparams):F[Z] = $apply - /** @group MapArity */ - def map$arity[${`A..N`}, Z]($fparams)(f: (${`A..N`}) => Z): F[Z] = Semigroupal.map$arity($fparams)(f)(self, self) - /** @group TupleArity */ - def tuple$arity[${`A..N`}, Z]($fparams): F[(${`A..N`})] = Semigroupal.tuple$arity($fparams)(self, self) - |} + |} """ } } final case class ParallelNestedExpansions(arity: Int) { - val products = (0 until (arity - 2)).foldRight(s"Parallel.parProduct(m${arity - 2}, m${arity - 1})")((i, acc) => s"Parallel.parProduct(m$i, $acc)") + val products = (0 until (arity - 2)) + .foldRight(s"Parallel.parProduct(m${arity - 2}, m${arity - 1})")((i, acc) => s"Parallel.parProduct(m$i, $acc)") val `(a..n)` = (0 until (arity - 2)).foldRight(s"(a${arity - 2}, a${arity - 1})")((i, acc) => s"(a$i, $acc)") } @@ -225,27 +241,29 @@ object Boilerplate { def content(tv: TemplateVals) = { import tv._ - val tpes = synTypes map { tpe => s"M[$tpe]" } - val fargs = (0 until arity) map { "m" + _ } - val fparams = (fargs zip tpes) map { case (v,t) => s"$v:$t"} mkString ", " - val fargsS = fargs mkString ", " + val tpes = synTypes.map { tpe => + s"M[$tpe]" + } + val fargs = (0 until arity).map { "m" + _ } + val fparams = (fargs.zip(tpes)).map { case (v, t) => s"$v:$t" }.mkString(", ") + val fargsS = fargs.mkString(", ") val nestedExpansion = ParallelNestedExpansions(arity) block""" - |package cats - | - |/** - | * @groupprio Ungrouped 0 - | * - | * @groupname ParMapArity parMap arity - | * @groupdesc ParMapArity Higher-arity parMap methods - | * @groupprio ParMapArity 999 - | */ - |trait ParallelArityFunctions { + |package cats + | + |/** + | * @groupprio Ungrouped 0 + | * + | * @groupname ParMapArity parMap arity + | * @groupdesc ParMapArity Higher-arity parMap methods + | * @groupprio ParMapArity 999 + | */ + |trait ParallelArityFunctions { - /** @group ParMapArity */ - def parMap$arity[M[_], F[_], ${`A..N`}, Z]($fparams)(f: (${`A..N`}) => Z)(implicit p: NonEmptyParallel[M, F]): M[Z] = - p.flatMap.map(${nestedExpansion.products}) { case ${nestedExpansion.`(a..n)`} => f(${`a..n`}) } - |} + |} """ } } @@ -256,27 +274,29 @@ object Boilerplate { def content(tv: TemplateVals) = { import tv._ - val tpes = synTypes map { tpe => s"M[$tpe]" } - val fargs = (0 until arity) map { "m" + _ } - val fparams = (fargs zip tpes) map { case (v,t) => s"$v:$t"} mkString ", " - val fargsS = fargs mkString ", " + val tpes = synTypes.map { tpe => + s"M[$tpe]" + } + val fargs = (0 until arity).map { "m" + _ } + val fparams = (fargs.zip(tpes)).map { case (v, t) => s"$v:$t" }.mkString(", ") + val fargsS = fargs.mkString(", ") val nestedExpansion = ParallelNestedExpansions(arity) block""" - |package cats - | - |/** - | * @groupprio Ungrouped 0 - | * - | * @groupname ParTupleArity parTuple arity - | * @groupdesc ParTupleArity Higher-arity parTuple methods - | * @groupprio ParTupleArity 999 - | */ - |abstract class ParallelArityFunctions2 extends ParallelArityFunctions { + |package cats + | + |/** + | * @groupprio Ungrouped 0 + | * + | * @groupname ParTupleArity parTuple arity + | * @groupdesc ParTupleArity Higher-arity parTuple methods + | * @groupprio ParTupleArity 999 + | */ + |abstract class ParallelArityFunctions2 extends ParallelArityFunctions { - /** @group ParTupleArity */ - def parTuple$arity[M[_], F[_], ${`A..N`}]($fparams)(implicit p: NonEmptyParallel[M, F]): M[(${`A..N`})] = - p.flatMap.map(${nestedExpansion.products}) { case ${nestedExpansion.`(a..n)`} => (${`a..n`}) } - |} + |} """ } } @@ -287,41 +307,45 @@ object Boilerplate { def content(tv: TemplateVals) = { import tv._ - val tpes = synTypes map { tpe => s"F[$tpe]" } - val fargs = (0 until arity) map { "f" + _ } - val fparams = (fargs zip tpes) map { case (v,t) => s"$v:$t"} mkString ", " - val fargsS = fargs mkString ", " + val tpes = synTypes.map { tpe => + s"F[$tpe]" + } + val fargs = (0 until arity).map { "f" + _ } + val fparams = (fargs.zip(tpes)).map { case (v, t) => s"$v:$t" }.mkString(", ") + val fargsS = fargs.mkString(", ") - val nestedProducts = (0 until (arity - 2)).foldRight(s"semigroupal.product(f${arity - 2}, f${arity - 1})")((i, acc) => s"semigroupal.product(f$i, $acc)") - val `nested (a..n)` = (0 until (arity - 2)).foldRight(s"(a${arity - 2}, a${arity - 1})")((i, acc) => s"(a$i, $acc)") + val nestedProducts = (0 until (arity - 2)) + .foldRight(s"semigroupal.product(f${arity - 2}, f${arity - 1})")((i, acc) => s"semigroupal.product(f$i, $acc)") + val `nested (a..n)` = + (0 until (arity - 2)).foldRight(s"(a${arity - 2}, a${arity - 1})")((i, acc) => s"(a$i, $acc)") block""" - |package cats - | - |/** - | * @groupprio Ungrouped 0 - | * - | * @groupname MapArity map arity - | * @groupdesc MapArity Higher-arity map methods - | * @groupprio MapArity 999 - | * - | * @groupname ContramapArity contramap arity - | * @groupdesc ContramapArity Higher-arity contramap methods - | * @groupprio ContramapArity 999 - | * - | * @groupname ImapArity imap arity - | * @groupdesc ImapArity Higher-arity imap methods - | * @groupprio ImapArity 999 - | * - | * @groupname TupleArity tuple arity - | * @groupdesc TupleArity Higher-arity tuple methods - | * @groupprio TupleArity 999 - | * - | * @groupname TraverseArity traverse arity - | * @groupdesc TraverseArity Higher-arity traverse methods - | * @groupprio TraverseArity 999 - | */ - |trait SemigroupalArityFunctions { + |package cats + | + |/** + | * @groupprio Ungrouped 0 + | * + | * @groupname MapArity map arity + | * @groupdesc MapArity Higher-arity map methods + | * @groupprio MapArity 999 + | * + | * @groupname ContramapArity contramap arity + | * @groupdesc ContramapArity Higher-arity contramap methods + | * @groupprio ContramapArity 999 + | * + | * @groupname ImapArity imap arity + | * @groupdesc ImapArity Higher-arity imap methods + | * @groupprio ImapArity 999 + | * + | * @groupname TupleArity tuple arity + | * @groupdesc TupleArity Higher-arity tuple methods + | * @groupprio TupleArity 999 + | * + | * @groupname TraverseArity traverse arity + | * @groupdesc TraverseArity Higher-arity traverse methods + | * @groupprio TraverseArity 999 + | */ + |trait SemigroupalArityFunctions { - /** @group MapArity */ - def map$arity[F[_], ${`A..N`}, Z]($fparams)(f: (${`A..N`}) => Z)(implicit semigroupal: Semigroupal[F], functor: Functor[F]): F[Z] = - functor.map($nestedProducts) { case ${`nested (a..n)`} => f(${`a..n`}) } @@ -337,79 +361,92 @@ object Boilerplate { - /** @group TraverseArity */ - def traverse$arity[F[_], G[_], ${`A..N`}, Z]($fparams)(f: (${`A..N`}) => G[Z])(implicit semigroupal: Semigroupal[F], traverse: Traverse[F], applicative: Applicative[G]): G[F[Z]] = - traverse.traverse($nestedProducts) { case ${`nested (a..n)`} => f(${`a..n`}) } - |} + |} """ } } object GenTupleParallelSyntax extends Template { - def filename(root: File) = root / "cats" / "syntax" / "TupleParallelSyntax.scala" + def filename(root: File) = root / "cats" / "syntax" / "TupleParallelSyntax.scala" def content(tv: TemplateVals) = { import tv._ - val tpes = synTypes map { tpe => s"M[$tpe]" } - val tpesString = tpes mkString ", " + val tpes = synTypes.map { tpe => + s"M[$tpe]" + } + val tpesString = tpes.mkString(", ") val tuple = s"Tuple$arity[$tpesString]" val tupleTpe = s"t$arity: $tuple" - val tupleArgs = (1 to arity) map { case n => s"t$arity._$n" } mkString ", " + val tupleArgs = (1 to arity).map { case n => s"t$arity._$n" }.mkString(", ") val n = if (arity == 1) { "" } else { arity.toString } val parMap = - if (arity == 1) s"def parMap[F[_], Z](f: (${`A..N`}) => Z)(implicit p: NonEmptyParallel[M, F]): M[Z] = p.flatMap.map($tupleArgs)(f)" - else s"def parMapN[F[_], Z](f: (${`A..N`}) => Z)(implicit p: NonEmptyParallel[M, F]): M[Z] = Parallel.parMap$arity($tupleArgs)(f)" + if (arity == 1) + s"def parMap[F[_], Z](f: (${`A..N`}) => Z)(implicit p: NonEmptyParallel[M, F]): M[Z] = p.flatMap.map($tupleArgs)(f)" + else + s"def parMapN[F[_], Z](f: (${`A..N`}) => Z)(implicit p: NonEmptyParallel[M, F]): M[Z] = Parallel.parMap$arity($tupleArgs)(f)" val parTupled = if (arity == 1) "" - else s"def parTupled[F[_]](implicit p: NonEmptyParallel[M, F]): M[(${`A..N`})] = Parallel.parTuple$arity($tupleArgs)" + else + s"def parTupled[F[_]](implicit p: NonEmptyParallel[M, F]): M[(${`A..N`})] = Parallel.parTuple$arity($tupleArgs)" block""" - |package cats - |package syntax - | - |import cats.Parallel - | - |trait TupleParallelSyntax { + |package cats + |package syntax + | + |import cats.Parallel + | + |trait TupleParallelSyntax { - implicit def catsSyntaxTuple${arity}Parallel[M[_], ${`A..N`}]($tupleTpe): Tuple${arity}ParallelOps[M, ${`A..N`}] = new Tuple${arity}ParallelOps(t$arity) - |} - | + |} + | -private[syntax] final class Tuple${arity}ParallelOps[M[_], ${`A..N`}]($tupleTpe) { - $parMap - $parTupled -} - | + | """ } } object GenTupleSemigroupalSyntax extends Template { - def filename(root: File) = root / "cats" / "syntax" / "TupleSemigroupalSyntax.scala" + def filename(root: File) = root / "cats" / "syntax" / "TupleSemigroupalSyntax.scala" def content(tv: TemplateVals) = { import tv._ - val tpes = synTypes map { tpe => s"F[$tpe]" } - val tpesString = tpes mkString ", " + val tpes = synTypes.map { tpe => + s"F[$tpe]" + } + val tpesString = tpes.mkString(", ") val tuple = s"Tuple$arity[$tpesString]" val tupleTpe = s"t$arity: $tuple" - val tupleArgs = (1 to arity) map { case n => s"t$arity._$n" } mkString ", " + val tupleArgs = (1 to arity).map { case n => s"t$arity._$n" }.mkString(", ") val n = if (arity == 1) { "" } else { arity.toString } val map = - if (arity == 1) s"def map[Z](f: (${`A..N`}) => Z)(implicit functor: Functor[F]): F[Z] = functor.map($tupleArgs)(f)" - else s"def mapN[Z](f: (${`A..N`}) => Z)(implicit functor: Functor[F], semigroupal: Semigroupal[F]): F[Z] = Semigroupal.map$arity($tupleArgs)(f)" + if (arity == 1) + s"def map[Z](f: (${`A..N`}) => Z)(implicit functor: Functor[F]): F[Z] = functor.map($tupleArgs)(f)" + else + s"def mapN[Z](f: (${`A..N`}) => Z)(implicit functor: Functor[F], semigroupal: Semigroupal[F]): F[Z] = Semigroupal.map$arity($tupleArgs)(f)" val contramap = - if (arity == 1) s"def contramap[Z](f: Z => (${`A..N`}))(implicit contravariant: Contravariant[F]): F[Z] = contravariant.contramap($tupleArgs)(f)" - else s"def contramapN[Z](f: Z => (${`A..N`}))(implicit contravariant: Contravariant[F], semigroupal: Semigroupal[F]): F[Z] = Semigroupal.contramap$arity($tupleArgs)(f)" + if (arity == 1) + s"def contramap[Z](f: Z => (${`A..N`}))(implicit contravariant: Contravariant[F]): F[Z] = contravariant.contramap($tupleArgs)(f)" + else + s"def contramapN[Z](f: Z => (${`A..N`}))(implicit contravariant: Contravariant[F], semigroupal: Semigroupal[F]): F[Z] = Semigroupal.contramap$arity($tupleArgs)(f)" val imap = - if (arity == 1) s"def imap[Z](f: (${`A..N`}) => Z)(g: Z => (${`A..N`}))(implicit invariant: Invariant[F]): F[Z] = invariant.imap($tupleArgs)(f)(g)" - else s"def imapN[Z](f: (${`A..N`}) => Z)(g: Z => (${`A..N`}))(implicit invariant: Invariant[F], semigroupal: Semigroupal[F]): F[Z] = Semigroupal.imap$arity($tupleArgs)(f)(g)" + if (arity == 1) + s"def imap[Z](f: (${`A..N`}) => Z)(g: Z => (${`A..N`}))(implicit invariant: Invariant[F]): F[Z] = invariant.imap($tupleArgs)(f)(g)" + else + s"def imapN[Z](f: (${`A..N`}) => Z)(g: Z => (${`A..N`}))(implicit invariant: Invariant[F], semigroupal: Semigroupal[F]): F[Z] = Semigroupal.imap$arity($tupleArgs)(f)(g)" val tupled = if (arity != 1) { s"def tupled(implicit invariant: Invariant[F], semigroupal: Semigroupal[F]): F[(${`A..N`})] = Semigroupal.tuple$n($tupleArgs)" @@ -418,20 +455,21 @@ object Boilerplate { } val traverse = - if (arity == 1) s"def traverse[G[_]: Applicative, Z](f: (${`A..N`}) => G[Z])(implicit traverse: Traverse[F]): G[F[Z]] = traverse.traverse($tupleArgs)(f)" - else s"def traverseN[G[_]: Applicative, Z](f: (${`A..N`}) => G[Z])(implicit traverse: Traverse[F], semigroupal: Semigroupal[F]): G[F[Z]] = Semigroupal.traverse$arity($tupleArgs)(f)" - + if (arity == 1) + s"def traverse[G[_]: Applicative, Z](f: (${`A..N`}) => G[Z])(implicit traverse: Traverse[F]): G[F[Z]] = traverse.traverse($tupleArgs)(f)" + else + s"def traverseN[G[_]: Applicative, Z](f: (${`A..N`}) => G[Z])(implicit traverse: Traverse[F], semigroupal: Semigroupal[F]): G[F[Z]] = Semigroupal.traverse$arity($tupleArgs)(f)" block""" - |package cats - |package syntax - | - | - | - |trait TupleSemigroupalSyntax { + |package cats + |package syntax + | + | + | + |trait TupleSemigroupalSyntax { - implicit def catsSyntaxTuple${arity}Semigroupal[F[_], ${`A..N`}]($tupleTpe): Tuple${arity}SemigroupalOps[F, ${`A..N`}] = new Tuple${arity}SemigroupalOps(t$arity) - |} - | + |} + | -private[syntax] final class Tuple${arity}SemigroupalOps[F[_], ${`A..N`}]($tupleTpe) { - $map - $contramap @@ -440,7 +478,7 @@ object Boilerplate { - $traverse - def apWith[Z](f: F[(${`A..N`}) => Z])(implicit apply: Apply[F]): F[Z] = apply.ap$n(f)($tupleArgs) -} - | + | """ } } diff --git a/project/KernelBoiler.scala b/project/KernelBoiler.scala index 16c64d3471f..8305be68dfb 100644 --- a/project/KernelBoiler.scala +++ b/project/KernelBoiler.scala @@ -2,14 +2,14 @@ import KernelBoiler.TemplateVals import sbt._ /** - * Generate a range of boilerplate classes that would be tedious to write and maintain by hand. - * - * Copied, with some modifications, from - * [[https://github.com/milessabin/shapeless/blob/master/project/Boilerplate.scala Shapeless]]. - * - * @author Miles Sabin - * @author Kevin Wright - */ + * Generate a range of boilerplate classes that would be tedious to write and maintain by hand. + * + * Copied, with some modifications, from + * [[https://github.com/milessabin/shapeless/blob/master/project/Boilerplate.scala Shapeless]]. + * + * @author Miles Sabin + * @author Kevin Wright + */ object KernelBoiler { import scala.StringContext._ @@ -28,10 +28,10 @@ object KernelBoiler { val maxArity = 22 /** - * Return a sequence of the generated files. - * - * As a side-effect, it actually generates them... - */ + * Return a sequence of the generated files. + * + * As a side-effect, it actually generates them... + */ def gen(dir: File): Seq[File] = templates.map { template => val tgtFile = template.filename(dir) IO.write(tgtFile, template.body) @@ -40,28 +40,28 @@ object KernelBoiler { class TemplateVals(val arity: Int) { val synTypes = (0 until arity).map(n => s"A$n") - val synVals = (0 until arity).map(n => s"a$n") - val `A..N` = synTypes.mkString(", ") - val `a..n` = synVals.mkString(", ") - val `_.._` = Seq.fill(arity)("_").mkString(", ") + val synVals = (0 until arity).map(n => s"a$n") + val `A..N` = synTypes.mkString(", ") + val `a..n` = synVals.mkString(", ") + val `_.._` = Seq.fill(arity)("_").mkString(", ") val `(A..N)` = if (arity == 1) "Tuple1[A0]" else synTypes.mkString("(", ", ", ")") val `(_.._)` = if (arity == 1) "Tuple1[_]" else Seq.fill(arity)("_").mkString("(", ", ", ")") val `(a..n)` = if (arity == 1) "Tuple1(a)" else synVals.mkString("(", ", ", ")") } /** - * Blocks in the templates below use a custom interpolator, combined with post-processing to - * produce the body. - * - * - The contents of the `header` val is output first - * - Then the first block of lines beginning with '|' - * - Then the block of lines beginning with '-' is replicated once for each arity, - * with the `templateVals` already pre-populated with relevant relevant vals for that arity - * - Then the last block of lines prefixed with '|' - * - * The block otherwise behaves as a standard interpolated string with regards to variable - * substitution. - */ + * Blocks in the templates below use a custom interpolator, combined with post-processing to + * produce the body. + * + * - The contents of the `header` val is output first + * - Then the first block of lines beginning with '|' + * - Then the block of lines beginning with '-' is replicated once for each arity, + * with the `templateVals` already pre-populated with relevant relevant vals for that arity + * - Then the last block of lines prefixed with '|' + * + * The block otherwise behaves as a standard interpolated string with regards to variable + * substitution. + */ trait Template { def filename(root: File): File def preBody: String @@ -74,11 +74,10 @@ object KernelBoiler { } } - case class InstanceDef(start: String, methods: TemplateVals => TemplatedBlock, end: String = "}") { + case class InstanceDef(start: String, methods: TemplateVals => TemplatedBlock, end: String = "}") { def body(tvs: Seq[TemplateVals]): Seq[String] = Seq(start) ++ tvs.map(methods(_).content) ++ Seq(end) } - abstract class TemplatedBlock(tv: TemplateVals) { import tv._ @@ -111,8 +110,9 @@ object KernelBoiler { } def unaryMethod(name: String) = - synTypes.zipWithIndex.iterator.map { case (tpe, i) => - s"$tpe.$name(x._${i + 1})" + synTypes.zipWithIndex.iterator.map { + case (tpe, i) => + s"$tpe.$name(x._${i + 1})" } def nullaryTuple(name: String) = { @@ -134,15 +134,18 @@ object KernelBoiler { package instances """ - def instances: Seq[InstanceDef] = { - + def instances: Seq[InstanceDef] = Seq( - InstanceDef("trait TupleInstances extends TupleInstances1 {", - tv => new TemplatedBlock(tv) { - import tv._ - def content = - block""" - implicit def catsKernelStdCommutativeGroupForTuple${arity}[${`A..N`}](implicit ${constraints("CommutativeGroup")}): CommutativeGroup[${`(A..N)`}] = + InstanceDef( + "trait TupleInstances extends TupleInstances1 {", + tv => + new TemplatedBlock(tv) { + import tv._ + def content = + block""" + implicit def catsKernelStdCommutativeGroupForTuple${arity}[${`A..N`}](implicit ${constraints( + "CommutativeGroup" + )}): CommutativeGroup[${`(A..N)`}] = new CommutativeGroup[${`(A..N)`}] { def combine(x: ${`(A..N)`}, y: ${`(A..N)`}): ${`(A..N)`} = ${binTuple("combine")} def empty: ${`(A..N)`} = ${nullaryTuple("empty")} @@ -155,7 +158,9 @@ object KernelBoiler { ${binMethod("compare").mkString("Array(", ", ", ")")}.find(_ != 0).getOrElse(0) } - implicit def catsKernelStdBoundedSemilatticeForTuple${arity}[${`A..N`}](implicit ${constraints("BoundedSemilattice")}): BoundedSemilattice[${`(A..N)`}] = + implicit def catsKernelStdBoundedSemilatticeForTuple${arity}[${`A..N`}](implicit ${constraints( + "BoundedSemilattice" + )}): BoundedSemilattice[${`(A..N)`}] = new BoundedSemilattice[${`(A..N)`}] { def combine(x: ${`(A..N)`}, y: ${`(A..N)`}): ${`(A..N)`} = ${binTuple("combine")} def empty: ${`(A..N)`} = ${nullaryTuple("empty")} @@ -163,18 +168,21 @@ object KernelBoiler { """ } ), - - InstanceDef("trait TupleInstances1 extends TupleInstances2 {", - tv => new TemplatedBlock(tv) { - import tv._ - def content = - block""" + InstanceDef( + "trait TupleInstances1 extends TupleInstances2 {", + tv => + new TemplatedBlock(tv) { + import tv._ + def content = + block""" 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")} } - implicit def catsKernelStdCommutativeMonoidForTuple${arity}[${`A..N`}](implicit ${constraints("CommutativeMonoid")}): CommutativeMonoid[${`(A..N)`}] = + implicit def catsKernelStdCommutativeMonoidForTuple${arity}[${`A..N`}](implicit ${constraints( + "CommutativeMonoid" + )}): CommutativeMonoid[${`(A..N)`}] = new CommutativeMonoid[${`(A..N)`}] { def combine(x: ${`(A..N)`}, y: ${`(A..N)`}): ${`(A..N)`} = ${binTuple("combine")} def empty: ${`(A..N)`} = ${nullaryTuple("empty")} @@ -189,7 +197,8 @@ object KernelBoiler { implicit def catsKernelStdHashForTuple${arity}[${`A..N`}](implicit ${constraints("Hash")}): Hash[${`(A..N)`}] = new Hash[${`(A..N)`}] { - def hash(x: ${`(A..N)`}): Int = ${unaryMethod("hash").mkString(s"$tupleNHeader(", ", ", ")")}.hashCode() + def hash(x: ${`(A..N)`}): Int = ${unaryMethod("hash") + .mkString(s"$tupleNHeader(", ", ", ")")}.hashCode() def eqv(x: ${`(A..N)`}, y: ${`(A..N)`}): Boolean = ${binMethod("eqv").mkString(" && ")} } @@ -198,19 +207,24 @@ object KernelBoiler { def partialCompare(x: ${`(A..N)`}, y: ${`(A..N)`}): Double = ${binMethod("partialCompare").mkString("Array(", ", ", ")")}.find(_ != 0.0).getOrElse(0.0) } - """}), - - InstanceDef("trait TupleInstances2 extends TupleInstances3 {", - tv => new TemplatedBlock(tv) { - import tv._ - def content = - block""" + """ + } + ), + InstanceDef( + "trait TupleInstances2 extends TupleInstances3 {", + tv => + new TemplatedBlock(tv) { + import tv._ + def content = + block""" 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 catsKernelStdCommutativeSemigroupForTuple${arity}[${`A..N`}](implicit ${constraints("CommutativeSemigroup")}): CommutativeSemigroup[${`(A..N)`}] = + implicit def catsKernelStdCommutativeSemigroupForTuple${arity}[${`A..N`}](implicit ${constraints( + "CommutativeSemigroup" + )}): CommutativeSemigroup[${`(A..N)`}] = new CommutativeSemigroup[${`(A..N)`}] { def combine(x: ${`(A..N)`}, y: ${`(A..N)`}): ${`(A..N)`} = ${binTuple("combine")} } @@ -220,13 +234,16 @@ object KernelBoiler { def combine(x: ${`(A..N)`}, y: ${`(A..N)`}): ${`(A..N)`} = ${binTuple("combine")} def empty: ${`(A..N)`} = ${nullaryTuple("empty")} } - """}), - - InstanceDef("trait TupleInstances3 {", - tv => new TemplatedBlock(tv) { - import tv._ - def content = - block""" + """ + } + ), + InstanceDef( + "trait TupleInstances3 {", + tv => + new TemplatedBlock(tv) { + import tv._ + def content = + block""" 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")} @@ -236,8 +253,10 @@ object KernelBoiler { new Eq[${`(A..N)`}] { def eqv(x: ${`(A..N)`}, y: ${`(A..N)`}): Boolean = ${binMethod("eqv").mkString(" && ")} } - """})) - } + """ + } + ) + ) } } diff --git a/project/plugins.sbt b/project/plugins.sbt index 04b66786a8a..00457610122 100644 --- a/project/plugins.sbt +++ b/project/plugins.sbt @@ -1,19 +1,20 @@ addSbtCoursier -addSbtPlugin("com.eed3si9n" % "sbt-unidoc" % "0.4.2") -addSbtPlugin("com.github.gseitz" %% "sbt-release" % "1.0.9") -addSbtPlugin("com.jsuereth" % "sbt-pgp" % "1.1.2") -addSbtPlugin("com.typesafe" % "sbt-mima-plugin" % "0.3.0") -addSbtPlugin("pl.project13.scala" % "sbt-jmh" % "0.3.4") -addSbtPlugin("org.scalastyle" % "scalastyle-sbt-plugin" % "1.0.0") -addSbtPlugin("org.scoverage" % "sbt-scoverage" % "1.6.0-M3") -addSbtPlugin("com.typesafe.sbt" % "sbt-git" % "1.0.0") -addSbtPlugin("com.github.tkawachi" % "sbt-doctest" % "0.8.0") -addSbtPlugin("org.xerial.sbt" % "sbt-sonatype" % "2.0") -addSbtPlugin("com.47deg" % "sbt-microsites" % "0.7.20") -addSbtPlugin("com.dwijnand" % "sbt-travisci" % "1.1.3") -addSbtPlugin("org.lyranthe.sbt" % "partial-unification" % "1.1.2") -addSbtPlugin("org.tpolecat" % "tut-plugin" % "0.6.7") -addSbtPlugin("org.portable-scala" % "sbt-scalajs-crossproject" % "0.6.0") -addSbtPlugin("org.portable-scala" % "sbt-scala-native-crossproject" % "0.6.0") -addSbtPlugin("org.scala-js" % "sbt-scalajs" % "0.6.24") -addSbtPlugin("org.scala-native" % "sbt-scala-native" % "0.3.8") +addSbtPlugin("com.eed3si9n" % "sbt-unidoc" % "0.4.2") +addSbtPlugin("com.github.gseitz" %% "sbt-release" % "1.0.9") +addSbtPlugin("com.jsuereth" % "sbt-pgp" % "1.1.2") +addSbtPlugin("com.typesafe" % "sbt-mima-plugin" % "0.3.0") +addSbtPlugin("pl.project13.scala" % "sbt-jmh" % "0.3.4") +addSbtPlugin("org.scalastyle" % "scalastyle-sbt-plugin" % "1.0.0") +addSbtPlugin("org.scoverage" % "sbt-scoverage" % "1.6.0-M3") +addSbtPlugin("com.typesafe.sbt" % "sbt-git" % "1.0.0") +addSbtPlugin("com.github.tkawachi" % "sbt-doctest" % "0.8.0") +addSbtPlugin("org.xerial.sbt" % "sbt-sonatype" % "2.0") +addSbtPlugin("com.47deg" % "sbt-microsites" % "0.7.20") +addSbtPlugin("com.dwijnand" % "sbt-travisci" % "1.1.3") +addSbtPlugin("org.lyranthe.sbt" % "partial-unification" % "1.1.2") +addSbtPlugin("org.tpolecat" % "tut-plugin" % "0.6.7") +addSbtPlugin("org.portable-scala" % "sbt-scalajs-crossproject" % "0.6.0") +addSbtPlugin("org.portable-scala" % "sbt-scala-native-crossproject" % "0.6.0") +addSbtPlugin("org.scala-js" % "sbt-scalajs" % "0.6.24") +addSbtPlugin("org.scala-native" % "sbt-scala-native" % "0.3.8") +addSbtPlugin("com.geirsson" % "sbt-scalafmt" % "1.5.1") diff --git a/scalastyle-config.xml b/scalastyle-config.xml index 081d0095346..9b6c1c39c58 100644 --- a/scalastyle-config.xml +++ b/scalastyle-config.xml @@ -49,7 +49,7 @@ - + @@ -65,11 +65,6 @@ ...]).]]> - - - PACKAGE, WHILE, CASE, NEW, DO, EQUALS, SUBTYPE, SEALED, TYPE, FINAL, IMPORT, RETURN, VAL, VAR, ELSE, MATCH, TRY, SUPERTYPE, OP, CATCH, THROW, CLASS, DEF, FOR, LARROW, ABSTRACT, IF, OBJECT, COMMA, YIELD, PIPE, IMPLICIT, LAZY, TRAIT, FORSOME, FINALLY, OVERRIDE, ARROW, EXTENDS - - OP, PIPE, FORSOME @@ -85,10 +80,4 @@ - - - - - - diff --git a/scripts/travis-publish.sh b/scripts/travis-publish.sh index 0a333e8d0c5..2d348ae5080 100755 --- a/scripts/travis-publish.sh +++ b/scripts/travis-publish.sh @@ -43,7 +43,7 @@ js="$core_js && $free_js && $kernel_js" if [[ $TRAVIS_SCALA_VERSION == *"2.13"* ]]; then jvm="$sbt_cmd buildJVM" else -jvm="$sbt_cmd coverage validateJVM coverageReport && codecov" +jvm="$sbt_cmd coverage validate coverageReport && codecov" fi diff --git a/testkit/src/main/scala/cats/tests/CatsEquality.scala b/testkit/src/main/scala/cats/tests/CatsEquality.scala index a45dc9a4e6f..dcd550a495e 100644 --- a/testkit/src/main/scala/cats/tests/CatsEquality.scala +++ b/testkit/src/main/scala/cats/tests/CatsEquality.scala @@ -21,7 +21,8 @@ trait LowPriorityStrictCatsConstraints extends TripleEquals { trait StrictCatsEquality extends LowPriorityStrictCatsConstraints { override def convertToEqualizer[T](left: T): Equalizer[T] = super.convertToEqualizer[T](left) implicit override def convertToCheckingEqualizer[T](left: T): CheckingEqualizer[T] = new CheckingEqualizer(left) - override def unconstrainedEquality[A, B](implicit equalityOfA: Equality[A]): CanEqual[A, B] = super.unconstrainedEquality[A, B] + override def unconstrainedEquality[A, B](implicit equalityOfA: Equality[A]): CanEqual[A, B] = + super.unconstrainedEquality[A, B] implicit def catsCanEqual[A, B](implicit A: Eq[A], ev: B <:< A): CanEqual[A, B] = new BToAEquivalenceConstraint[A, B](new CatsEquivalence(A), ev) } diff --git a/testkit/src/main/scala/cats/tests/CatsSuite.scala b/testkit/src/main/scala/cats/tests/CatsSuite.scala index baf8d0b687f..d944a08ec86 100644 --- a/testkit/src/main/scala/cats/tests/CatsSuite.scala +++ b/testkit/src/main/scala/cats/tests/CatsSuite.scala @@ -4,7 +4,14 @@ package tests import catalysts.Platform import cats.instances.{AllInstances, AllInstancesBinCompat0, AllInstancesBinCompat1, AllInstancesBinCompat2} -import cats.syntax.{AllSyntax, AllSyntaxBinCompat0, AllSyntaxBinCompat1, AllSyntaxBinCompat2, AllSyntaxBinCompat3, EqOps} +import cats.syntax.{ + AllSyntax, + AllSyntaxBinCompat0, + AllSyntaxBinCompat1, + AllSyntaxBinCompat2, + AllSyntaxBinCompat3, + EqOps +} import org.scalactic.anyvals.{PosInt, PosZDouble, PosZInt} import org.scalatest.{FunSuite, FunSuiteLike, Matchers} import org.scalatest.prop.{Configuration, GeneratorDrivenPropertyChecks} @@ -18,7 +25,8 @@ trait TestSettings extends Configuration with Matchers { maxDiscardedFactor = if (Platform.isJvm) PosZDouble(5.0) else PosZDouble(50.0), minSize = PosZInt(0), sizeRange = if (Platform.isJvm) PosZInt(10) else PosZInt(5), - workers = if (Platform.isJvm) PosInt(2) else PosInt(1)) + workers = if (Platform.isJvm) PosInt(2) else PosInt(1) + ) lazy val slowCheckConfiguration: PropertyCheckConfiguration = if (Platform.isJvm) checkConfiguration @@ -26,17 +34,24 @@ trait TestSettings extends Configuration with Matchers { } /** - * An opinionated stack of traits to improve consistency and reduce - * boilerplate in Cats tests. - */ -trait CatsSuite extends FunSuite + * An opinionated stack of traits to improve consistency and reduce + * boilerplate in Cats tests. + */ +trait CatsSuite + extends FunSuite with Matchers with GeneratorDrivenPropertyChecks with Discipline with TestSettings - with AllInstances with AllInstancesBinCompat0 with AllInstancesBinCompat1 with AllInstancesBinCompat2 - with AllSyntax with AllSyntaxBinCompat0 with AllSyntaxBinCompat1 - with AllSyntaxBinCompat2 with AllSyntaxBinCompat3 + with AllInstances + with AllInstancesBinCompat0 + with AllInstancesBinCompat1 + with AllInstancesBinCompat2 + with AllSyntax + with AllSyntaxBinCompat0 + with AllSyntaxBinCompat1 + with AllSyntaxBinCompat2 + with AllSyntaxBinCompat3 with StrictCatsEquality { self: FunSuiteLike => implicit override val generatorDrivenConfig: PropertyCheckConfiguration = diff --git a/testkit/src/main/scala/cats/tests/Helpers.scala b/testkit/src/main/scala/cats/tests/Helpers.scala index 6a222cde8f9..333afae1d03 100644 --- a/testkit/src/main/scala/cats/tests/Helpers.scala +++ b/testkit/src/main/scala/cats/tests/Helpers.scala @@ -4,23 +4,23 @@ package tests import org.scalacheck.{Arbitrary, Cogen} import Arbitrary.arbitrary -import cats.kernel.{ CommutativeSemigroup, CommutativeMonoid, CommutativeGroup } -import cats.kernel.{ Band, Semilattice, BoundedSemilattice } +import cats.kernel.{CommutativeGroup, CommutativeMonoid, CommutativeSemigroup} +import cats.kernel.{Band, BoundedSemilattice, Semilattice} /** - * Helpers provides new concrete types where we control exactly which - * type class instances are available. For example, the SL type has: - * - * - Semilattice[SL] - * - Arbitrary[SL] - * - Eq[SL] - * - * (All types in Helpers have Arbitrary and Eq instances.) - * - * These are useful when a type constructor (e.g. Function0) can - * produce many different instances depending on which instances are - * available for its type parameter. - */ + * Helpers provides new concrete types where we control exactly which + * type class instances are available. For example, the SL type has: + * + * - Semilattice[SL] + * - Arbitrary[SL] + * - Eq[SL] + * + * (All types in Helpers have Arbitrary and Eq instances.) + * + * These are useful when a type constructor (e.g. Function0) can + * produce many different instances depending on which instances are + * available for its type parameter. + */ object Helpers { abstract class N { def n: Int } @@ -45,8 +45,8 @@ object Helpers { object POrd extends Arb(new POrd(_)) { implicit object O extends PartialOrder[POrd] { def partialCompare(x: POrd, y: POrd): Double = - if (x.n >= 0 && y.n >= 0) (x.n compare y.n).toDouble - else if (x.n <= 0 && y.n <= 0) (y.n compare x.n).toDouble + if (x.n >= 0 && y.n >= 0) x.n.compare(y.n).toDouble + else if (x.n <= 0 && y.n <= 0) y.n.compare(x.n).toDouble else Double.NaN } } @@ -55,7 +55,7 @@ object Helpers { case class Ord(n: Int) extends N object Ord extends Arb(new Ord(_)) { implicit object O extends Order[Ord] { - def compare(x: Ord, y: Ord): Int = x.n compare y.n + def compare(x: Ord, y: Ord): Int = x.n.compare(y.n) } } @@ -113,7 +113,7 @@ object Helpers { object Mono extends Companion(new Mono(_)) { implicit object Alg extends Monoid[Mono] { def empty: Mono = Mono(Int.MaxValue) - def combine(x: Mono, y: Mono): Mono = Mono(x.n min y.n) + def combine(x: Mono, y: Mono): Mono = Mono(x.n.min(y.n)) } } @@ -122,7 +122,7 @@ object Helpers { object CMono extends Companion(new CMono(_)) { implicit object Alg extends CommutativeMonoid[CMono] { def empty: CMono = CMono(Int.MaxValue) - def combine(x: CMono, y: CMono): CMono = CMono(x.n min y.n) + def combine(x: CMono, y: CMono): CMono = CMono(x.n.min(y.n)) } } diff --git a/tests/src/test/scala/cats/tests/AlgebraInvariantSuite.scala b/tests/src/test/scala/cats/tests/AlgebraInvariantSuite.scala index 01a1ed62db7..329ebcc56c4 100644 --- a/tests/src/test/scala/cats/tests/AlgebraInvariantSuite.scala +++ b/tests/src/test/scala/cats/tests/AlgebraInvariantSuite.scala @@ -4,7 +4,7 @@ package tests import cats.Invariant import cats.kernel._ import cats.kernel.laws.discipline.{SemigroupTests, MonoidTests, GroupTests, _} -import cats.laws.discipline.{InvariantMonoidalTests, InvariantTests, SerializableTests, InvariantSemigroupalTests} +import cats.laws.discipline.{InvariantMonoidalTests, InvariantSemigroupalTests, InvariantTests, SerializableTests} import cats.laws.discipline.eq._ import org.scalacheck.{Arbitrary, Gen} @@ -59,14 +59,12 @@ class AlgebraInvariantSuite extends CatsSuite { implicit val arbCommutativeGroupInt: Arbitrary[CommutativeGroup[Int]] = Arbitrary(genCommutativeGroupInt) - - checkAll("InvariantMonoidal[Semigroup]", SemigroupTests[Int](InvariantMonoidal[Semigroup].point(0)).semigroup) - checkAll("InvariantMonoidal[CommutativeSemigroup]", CommutativeSemigroupTests[Int](InvariantMonoidal[CommutativeSemigroup].point(0)).commutativeSemigroup) + checkAll("InvariantMonoidal[CommutativeSemigroup]", + CommutativeSemigroupTests[Int](InvariantMonoidal[CommutativeSemigroup].point(0)).commutativeSemigroup) checkAll("InvariantSemigroupal[Monoid]", InvariantSemigroupalTests[Monoid].invariantSemigroupal[Int, Int, Int]) - { val S: Semigroup[Int] = Semigroup[Int].imap(identity)(identity) checkAll("Semigroup[Int]", SemigroupTests[Int](S).semigroup) @@ -92,13 +90,11 @@ class AlgebraInvariantSuite extends CatsSuite { checkAll("CommutativeMonoid[Int]", CommutativeMonoidTests[Int](S).commutativeMonoid) } - { val S: CommutativeGroup[Int] = CommutativeGroup[Int].imap(identity)(identity) checkAll("CommutativeGroup[Int]", CommutativeGroupTests[Int](S).commutativeGroup) } - { val S: Band[Set[Int]] = Band[Set[Int]].imap(identity)(identity) checkAll("Band[Set[Int]]", BandTests[Set[Int]](S).band) @@ -114,7 +110,6 @@ class AlgebraInvariantSuite extends CatsSuite { checkAll("BoundedSemilattice[Set[Int]]", BoundedSemilatticeTests[Set[Int]](S).boundedSemilattice) } - checkAll("Invariant[Semigroup]", InvariantTests[Semigroup].invariant[Int, Int, Int]) checkAll("Invariant[Semigroup]", SerializableTests.serializable(Invariant[Semigroup])) @@ -145,7 +140,9 @@ class AlgebraInvariantSuite extends CatsSuite { checkAll("InvariantMonoidal[Semigroup]", InvariantMonoidalTests[Semigroup].invariantMonoidal[Int, Int, Int]) checkAll("InvariantMonoidal[Semigroup]", SerializableTests.serializable(InvariantMonoidal[Semigroup])) - checkAll("InvariantMonoidal[CommutativeSemigroup]", InvariantMonoidalTests[CommutativeSemigroup].invariantMonoidal[Int, Int, Int]) - checkAll("InvariantMonoidal[CommutativeSemigroup]", SerializableTests.serializable(InvariantMonoidal[CommutativeSemigroup])) + checkAll("InvariantMonoidal[CommutativeSemigroup]", + InvariantMonoidalTests[CommutativeSemigroup].invariantMonoidal[Int, Int, Int]) + checkAll("InvariantMonoidal[CommutativeSemigroup]", + SerializableTests.serializable(InvariantMonoidal[CommutativeSemigroup])) } diff --git a/tests/src/test/scala/cats/tests/AlternativeSuite.scala b/tests/src/test/scala/cats/tests/AlternativeSuite.scala index 7298600a364..eb46f102a3d 100644 --- a/tests/src/test/scala/cats/tests/AlternativeSuite.scala +++ b/tests/src/test/scala/cats/tests/AlternativeSuite.scala @@ -6,17 +6,17 @@ class AlternativeSuite extends CatsSuite { forAll { (list: List[Option[String]]) => val expected = list.collect { case Some(s) => s } - Alternative[List].unite(list) should === (expected) + Alternative[List].unite(list) should ===(expected) } } test("separate") { forAll { (list: List[Either[Int, String]]) => - val ints = list.collect { case Left(i) => i } + val ints = list.collect { case Left(i) => i } val strings = list.collect { case Right(s) => s } val expected = (ints, strings) - Alternative[List].separate(list) should === (expected) + Alternative[List].separate(list) should ===(expected) } } diff --git a/tests/src/test/scala/cats/tests/AndThenSuite.scala b/tests/src/test/scala/cats/tests/AndThenSuite.scala index a1825f9d09b..60f9509ecaa 100644 --- a/tests/src/test/scala/cats/tests/AndThenSuite.scala +++ b/tests/src/test/scala/cats/tests/AndThenSuite.scala @@ -19,7 +19,8 @@ class AndThenSuite extends CatsSuite { { implicit val iso = SemigroupalTests.Isomorphisms.invariant[AndThen[?, Int]] checkAll("AndThen[Int, Int]", ContravariantMonoidalTests[AndThen[?, Int]].contravariantMonoidal[Int, Int, Int]) - checkAll("ContravariantMonoidal[AndThen[?, Int]]", SerializableTests.serializable(ContravariantMonoidal[AndThen[?, Int]])) + checkAll("ContravariantMonoidal[AndThen[?, Int]]", + SerializableTests.serializable(ContravariantMonoidal[AndThen[?, Int]])) } checkAll("AndThen[Int, Int]", MonadTests[AndThen[Int, ?]].monad[Int, Int, Int]) @@ -57,7 +58,9 @@ class AndThenSuite extends CatsSuite { test("andThen is stack safe") { val count = if (Platform.isJvm) 500000 else 1000 - val fs = (0 until count).map(_ => { i: Int => i + 1 }) + val fs = (0 until count).map(_ => { i: Int => + i + 1 + }) val result = fs.foldLeft(AndThen((x: Int) => x))(_.andThen(_))(42) result shouldEqual (count + 42) @@ -65,7 +68,9 @@ class AndThenSuite extends CatsSuite { test("compose is stack safe") { val count = if (Platform.isJvm) 500000 else 1000 - val fs = (0 until count).map(_ => { i: Int => i + 1 }) + val fs = (0 until count).map(_ => { i: Int => + i + 1 + }) val result = fs.foldLeft(AndThen((x: Int) => x))(_.compose(_))(42) result shouldEqual (count + 42) @@ -83,4 +88,4 @@ class AndThenSuite extends CatsSuite { test("toString") { AndThen((x: Int) => x).toString should startWith("AndThen$") } -} \ No newline at end of file +} diff --git a/tests/src/test/scala/cats/tests/ApplicativeErrorSuite.scala b/tests/src/test/scala/cats/tests/ApplicativeErrorSuite.scala index bcd3e73deea..658bd97e8d3 100644 --- a/tests/src/test/scala/cats/tests/ApplicativeErrorSuite.scala +++ b/tests/src/test/scala/cats/tests/ApplicativeErrorSuite.scala @@ -8,37 +8,39 @@ class ApplicativeErrorSuite extends CatsSuite { (()).raiseError[Option, Int] test("raiseError syntax creates an Option with the correct value") { - failed should === (None: Option[Int]) + failed should ===(None: Option[Int]) } test("handleError syntax transforms an error to a success") { - failed.handleError(_ => 7) should === (Some(7)) + failed.handleError(_ => 7) should ===(Some(7)) } test("handleErrorWith transforms an error to a success") { - failed.handleErrorWith(_ => Some(7)) should === (Some(7)) + failed.handleErrorWith(_ => Some(7)) should ===(Some(7)) } test("attempt syntax creates a wrapped Either") { - failed.attempt should === (Option(Left(()))) + failed.attempt should ===(Option(Left(()))) } test("attemptT syntax creates an EitherT") { - failed.attemptT should === (EitherT[Option, Unit, Int](Option(Left(())))) + failed.attemptT should ===(EitherT[Option, Unit, Int](Option(Left(())))) } test("recover syntax transforms an error to a success") { - failed.recover { case _ => 7 } should === (Some(7)) + failed.recover { case _ => 7 } should ===(Some(7)) } test("recoverWith transforms an error to a success") { - failed.recoverWith { case _ => Some(7) } should === (Some(7)) + failed.recoverWith { case _ => Some(7) } should ===(Some(7)) } { final case class OptionWrapper[A](option: Option[A]) - implicit def mayBeApplicativeError[E](implicit ev: ApplicativeError[Option, E]): ApplicativeError[OptionWrapper, E] = + implicit def mayBeApplicativeError[E]( + implicit ev: ApplicativeError[Option, E] + ): ApplicativeError[OptionWrapper, E] = new ApplicativeError[OptionWrapper, E] { def raiseError[A](e: E): OptionWrapper[A] = @@ -55,11 +57,11 @@ class ApplicativeErrorSuite extends CatsSuite { } test("orElse leaves a success unchanged") { - (OptionWrapper(17.some) orElse OptionWrapper(None)).option should === (OptionWrapper(17.some).option) + OptionWrapper(17.some).orElse(OptionWrapper(None)).option should ===(OptionWrapper(17.some).option) } test("orElse transforms an error to the alternative") { - (().raiseError[OptionWrapper, Int] orElse OptionWrapper(17.some)).option should === (OptionWrapper(17.some).option) + ().raiseError[OptionWrapper, Int].orElse(OptionWrapper(17.some)).option should ===(OptionWrapper(17.some).option) } } } diff --git a/tests/src/test/scala/cats/tests/ApplicativeSuite.scala b/tests/src/test/scala/cats/tests/ApplicativeSuite.scala index 4d2c4559b0d..e882b708ef9 100644 --- a/tests/src/test/scala/cats/tests/ApplicativeSuite.scala +++ b/tests/src/test/scala/cats/tests/ApplicativeSuite.scala @@ -3,41 +3,39 @@ package tests import cats.Applicative import cats.kernel.laws.discipline.{MonoidTests, SemigroupTests} -import cats.data.{Validated, Const} +import cats.data.{Const, Validated} import cats.laws.discipline.arbitrary._ import cats.laws.discipline.CoflatMapTests - - class ApplicativeSuite extends CatsSuite { test("replicateA creates a List of 'n' copies of given Applicative 'fa'") { val A = Applicative[Option] val fa = A.pure(1) - fa.replicateA(5) should === (Some(List(1,1,1,1,1))) + fa.replicateA(5) should ===(Some(List(1, 1, 1, 1, 1))) } test("whenA return given argument when cond is true") { forAll { (l: List[Int]) => - l.whenA(true) should === (List.fill(l.length)(())) + l.whenA(true) should ===(List.fill(l.length)(())) } } test("whenA lift Unit to F when cond is false") { forAll { (l: List[Int]) => - l.whenA(false) should === (List(())) + l.whenA(false) should ===(List(())) } } test("unlessA return given argument when cond is false") { forAll { (l: List[Int]) => - l.unlessA(false) should === (List.fill(l.length)(())) + l.unlessA(false) should ===(List.fill(l.length)(())) } } test("unlessA lift Unit to F when cond is true") { forAll { (l: List[Int]) => - l.unlessA(true) should === (List(())) + l.unlessA(true) should ===(List(())) } } diff --git a/tests/src/test/scala/cats/tests/AsSuite.scala b/tests/src/test/scala/cats/tests/AsSuite.scala index 33a9742a96b..ead924adcc5 100644 --- a/tests/src/test/scala/cats/tests/AsSuite.scala +++ b/tests/src/test/scala/cats/tests/AsSuite.scala @@ -7,18 +7,16 @@ import cats.arrow.Category class AsSuite extends CatsSuite { import evidence._ - def toMap[A, B, X](fa: List[X])(implicit ev: X <~< (A,B)): Map[A,B] = { + def toMap[A, B, X](fa: List[X])(implicit ev: X <~< (A, B)): Map[A, B] = { type RequiredFunc = (Map[A, B], X) => Map[A, B] type GivenFunc = (Map[A, B], (A, B)) => Map[A, B] val subst: GivenFunc <~< RequiredFunc = As.contra2_3(ev) //introduced because inference failed on scalajs on 2.10.6 - fa.foldLeft(Map.empty[A,B])(subst(_ + _)) + fa.foldLeft(Map.empty[A, B])(subst(_ + _)) } implicit def arbAs[A, B](implicit ev: A <~< B) = Arbitrary(Gen.const(ev)) implicit def eq[A, B]: Eq[As[A, B]] = Eq.fromUniversalEquals - - test("narrow an input of a function2") { // scala's GenTraversableOnce#toMap has a similar <:< constraint @@ -40,7 +38,7 @@ class AsSuite extends CatsSuite { implicitly[String <~< Any] implicitly[String <~< AnyRef] implicitly[String <~< AnyRef] - implicitly[(String,Int) <~< (AnyRef,Any)] + implicitly[(String, Int) <~< (AnyRef, Any)] implicitly[scala.collection.immutable.List[String] <~< scala.collection.Seq[Any]] } @@ -55,11 +53,11 @@ class AsSuite extends CatsSuite { test("subtyping relationships compose") { - val cAsB: Bottom As Middle = As.reify[Bottom,Middle] + val cAsB: Bottom As Middle = As.reify[Bottom, Middle] val bAsA: Middle As Top = As.fromPredef(implicitly) - val one: Bottom As Top = cAsB andThen bAsA - val two: Bottom As Top = bAsA compose cAsB + val one: Bottom As Top = cAsB.andThen(bAsA) + val two: Bottom As Top = bAsA.compose(cAsB) } test("we can use As to coerce a value") { @@ -79,7 +77,7 @@ class AsSuite extends CatsSuite { val co3: ((Bottom, Unit, Unit) As (Top, Unit, Unit)) = As.co3(cAsA) val co3_2: ((Unit, Bottom, Unit) As (Unit, Top, Unit)) = As.co3_2(cAsA) val co3_3: ((Unit, Unit, Bottom) As (Unit, Unit, Top)) = As.co3_3(cAsA) - val lift2: ((Bottom, String) As (Top,Any)) = As.lift2(cAsA,implicitly) + val lift2: ((Bottom, String) As (Top, Any)) = As.lift2(cAsA, implicitly) } test("we can lift subtyping to contravariant type constructors") { @@ -92,9 +90,9 @@ class AsSuite extends CatsSuite { val cAsA: (Bottom As Top) = implicitly val contra: Eat[Top] As Eat[Bottom] = As.contra(cAsA) - val contra1_2: EatF[Top, Unit] As EatF[Bottom,Unit] = As.contra1_2(cAsA) - val contra2_2: Eatꟻ[Unit, Top] As Eatꟻ[Unit,Bottom] = As.contra2_2(cAsA) - val contra1_3: EatF13[Top, Unit,Unit] As EatF13[Bottom, Unit, Unit] = As.contra1_3(cAsA) + val contra1_2: EatF[Top, Unit] As EatF[Bottom, Unit] = As.contra1_2(cAsA) + val contra2_2: Eatꟻ[Unit, Top] As Eatꟻ[Unit, Bottom] = As.contra2_2(cAsA) + val contra1_3: EatF13[Top, Unit, Unit] As EatF13[Bottom, Unit, Unit] = As.contra1_3(cAsA) val contra2_3: EatF23[Unit, Top, Unit] As EatF23[Unit, Bottom, Unit] = As.contra2_3(cAsA) val contra3_3: EatF33[Unit, Unit, Top] As EatF33[Unit, Unit, Bottom] = As.contra3_3(cAsA) } diff --git a/tests/src/test/scala/cats/tests/BifunctorSuite.scala b/tests/src/test/scala/cats/tests/BifunctorSuite.scala index e30fda97b6d..e2a9409f5a2 100644 --- a/tests/src/test/scala/cats/tests/BifunctorSuite.scala +++ b/tests/src/test/scala/cats/tests/BifunctorSuite.scala @@ -9,7 +9,8 @@ class BifunctorSuite extends CatsSuite { val tuple2ComposeEither: Bifunctor[Tuple2Either] = Bifunctor[Tuple2].compose[Either] - checkAll("Tuple2 compose Either", BifunctorTests(tuple2ComposeEither).bifunctor[Int, Int, Int, String, String, String]) + checkAll("Tuple2 compose Either", + BifunctorTests(tuple2ComposeEither).bifunctor[Int, Int, Int, String, String, String]) checkAll("Bifunctor[Tuple2 compose Either]", SerializableTests.serializable(tuple2ComposeEither)) { diff --git a/tests/src/test/scala/cats/tests/BinestedSuite.scala b/tests/src/test/scala/cats/tests/BinestedSuite.scala index 96e3d5b85b2..88e5caa8607 100644 --- a/tests/src/test/scala/cats/tests/BinestedSuite.scala +++ b/tests/src/test/scala/cats/tests/BinestedSuite.scala @@ -18,29 +18,48 @@ class BinestedSuite extends CatsSuite { { // Bifunctor + Functor + Functor = Bifunctor implicit val instance = ListWrapper.functor - checkAll("Binested[Either, ListWrapper, Option, ?, ?]", BifunctorTests[Binested[Either, ListWrapper, Option, ?, ?]].bifunctor[Int, Int, Int, String, String, String]) - checkAll("Bifunctor[Binested[Either, ListWrapper, Option, ?, ?]]", SerializableTests.serializable(Bifunctor[Binested[Either, ListWrapper, Option, ?, ?]])) + checkAll( + "Binested[Either, ListWrapper, Option, ?, ?]", + BifunctorTests[Binested[Either, ListWrapper, Option, ?, ?]].bifunctor[Int, Int, Int, String, String, String] + ) + checkAll("Bifunctor[Binested[Either, ListWrapper, Option, ?, ?]]", + SerializableTests.serializable(Bifunctor[Binested[Either, ListWrapper, Option, ?, ?]])) } { // Profunctor + Functor + Functor = Profunctor implicit val instance = ListWrapper.functor - checkAll("Binested[Function1, ListWrapper, Option, ?, ?]", ProfunctorTests[Binested[Function1, ListWrapper, Option, ?, ?]].profunctor[Int, Int, Int, String, String, String]) - checkAll("Profunctor[Binested[Function1, ListWrapper, Option, ?, ?]]", SerializableTests.serializable(Profunctor[Binested[Function1, ListWrapper, Option, ?, ?]])) + checkAll( + "Binested[Function1, ListWrapper, Option, ?, ?]", + ProfunctorTests[Binested[Function1, ListWrapper, Option, ?, ?]].profunctor[Int, Int, Int, String, String, String] + ) + checkAll("Profunctor[Binested[Function1, ListWrapper, Option, ?, ?]]", + SerializableTests.serializable(Profunctor[Binested[Function1, ListWrapper, Option, ?, ?]])) } { // Bifoldable + foldable + foldable = Bifoldable implicit val instance = ListWrapper.foldable - checkAll("Binested[Either, ListWrapper, ListWrapper, ?, ?]", BifoldableTests[Binested[Either, ListWrapper, ListWrapper, ?, ?]].bifoldable[Int, Int, Int]) - checkAll("Bifoldable[Binested[Either, ListWrapper, ListWrapper, ?, ?]]", SerializableTests.serializable(Bifoldable[Binested[Either, ListWrapper, ListWrapper, ?, ?]])) + checkAll("Binested[Either, ListWrapper, ListWrapper, ?, ?]", + BifoldableTests[Binested[Either, ListWrapper, ListWrapper, ?, ?]].bifoldable[Int, Int, Int]) + checkAll( + "Bifoldable[Binested[Either, ListWrapper, ListWrapper, ?, ?]]", + SerializableTests.serializable(Bifoldable[Binested[Either, ListWrapper, ListWrapper, ?, ?]]) + ) } { // Bitraverse + traverse + traverse = Bitraverse implicit val instance = ListWrapper.traverse - checkAll("Binested[Either, ListWrapper, ListWrapper, ?, ?]", BitraverseTests[Binested[Either, ListWrapper, ListWrapper, ?, ?]].bitraverse[Option, Int, Int, Int, String, String, String]) - checkAll("Bitraverse[Binested[Either, ListWrapper, ListWrapper, ?, ?]]", SerializableTests.serializable(Bitraverse[Binested[Either, ListWrapper, ListWrapper, ?, ?]])) + checkAll( + "Binested[Either, ListWrapper, ListWrapper, ?, ?]", + BitraverseTests[Binested[Either, ListWrapper, ListWrapper, ?, ?]] + .bitraverse[Option, Int, Int, Int, String, String, String] + ) + checkAll( + "Bitraverse[Binested[Either, ListWrapper, ListWrapper, ?, ?]]", + SerializableTests.serializable(Bitraverse[Binested[Either, ListWrapper, ListWrapper, ?, ?]]) + ) } test("simple syntax-based usage") { diff --git a/tests/src/test/scala/cats/tests/BitSetSuite.scala b/tests/src/test/scala/cats/tests/BitSetSuite.scala index de61ad9d359..305149be359 100644 --- a/tests/src/test/scala/cats/tests/BitSetSuite.scala +++ b/tests/src/test/scala/cats/tests/BitSetSuite.scala @@ -9,12 +9,12 @@ class BitSetSuite extends CatsSuite { implicit val arbitraryBitSet: Arbitrary[BitSet] = Arbitrary(arbitrary[List[Short]].map(ns => BitSet(ns.map(_ & 0xffff): _*))) - test("show BitSet"){ - BitSet(1, 1, 2, 3).show should === ("BitSet(1, 2, 3)") - BitSet.empty.show should === ("BitSet()") + test("show BitSet") { + BitSet(1, 1, 2, 3).show should ===("BitSet(1, 2, 3)") + BitSet.empty.show should ===("BitSet()") forAll { fs: BitSet => - fs.show should === (fs.toString) + fs.show should ===(fs.toString) } } diff --git a/tests/src/test/scala/cats/tests/BitraverseSuite.scala b/tests/src/test/scala/cats/tests/BitraverseSuite.scala index 0664bbda0b9..8c8c47e4019 100644 --- a/tests/src/test/scala/cats/tests/BitraverseSuite.scala +++ b/tests/src/test/scala/cats/tests/BitraverseSuite.scala @@ -8,6 +8,7 @@ class BitraverseSuite extends CatsSuite { val eitherComposeTuple2: Bitraverse[EitherTuple2] = Bitraverse[Either].compose[Tuple2] - checkAll("Either compose Tuple2", BitraverseTests(eitherComposeTuple2).bitraverse[Option, Int, Int, Int, String, String, String]) + checkAll("Either compose Tuple2", + BitraverseTests(eitherComposeTuple2).bitraverse[Option, Int, Int, Int, String, String, String]) checkAll("Bitraverse[Either compose Tuple2]", SerializableTests.serializable(eitherComposeTuple2)) } diff --git a/tests/src/test/scala/cats/tests/ChainSuite.scala b/tests/src/test/scala/cats/tests/ChainSuite.scala index b776354939c..2f2df8f89fa 100644 --- a/tests/src/test/scala/cats/tests/ChainSuite.scala +++ b/tests/src/test/scala/cats/tests/ChainSuite.scala @@ -2,7 +2,14 @@ package cats package tests import cats.data.Chain -import cats.laws.discipline.{AlternativeTests, CoflatMapTests, MonadTests, SerializableTests, TraverseFilterTests, TraverseTests} +import cats.laws.discipline.{ + AlternativeTests, + CoflatMapTests, + MonadTests, + SerializableTests, + TraverseFilterTests, + TraverseTests +} import cats.kernel.laws.discipline.{EqTests, MonoidTests, OrderTests, PartialOrderTests} import cats.laws.discipline.arbitrary._ @@ -25,110 +32,105 @@ class ChainSuite extends CatsSuite { checkAll("Chain[Int]", OrderTests[Chain[Int]].order) checkAll("Order[Chain]", SerializableTests.serializable(Order[Chain[Int]])) - checkAll("Chain[Int]", TraverseFilterTests[Chain].traverseFilter[Int, Int, Int]) checkAll("TraverseFilter[Chain]", SerializableTests.serializable(TraverseFilter[Chain])) { implicit val partialOrder = ListWrapper.partialOrder[Int] - checkAll("Chain[ListWrapper[Int]]", - PartialOrderTests[Chain[ListWrapper[Int]]].partialOrder) + checkAll("Chain[ListWrapper[Int]]", PartialOrderTests[Chain[ListWrapper[Int]]].partialOrder) checkAll("PartialOrder[Chain[ListWrapper[Int]]", - SerializableTests.serializable(PartialOrder[Chain[ListWrapper[Int]]])) + SerializableTests.serializable(PartialOrder[Chain[ListWrapper[Int]]])) } { implicit val eqv = ListWrapper.eqv[Int] - checkAll("Chain[ListWrapper[Int]]", - EqTests[Chain[ListWrapper[Int]]].eqv) - checkAll("Eq[Chain[ListWrapper[Int]]", - SerializableTests.serializable(Eq[Chain[ListWrapper[Int]]])) + checkAll("Chain[ListWrapper[Int]]", EqTests[Chain[ListWrapper[Int]]].eqv) + checkAll("Eq[Chain[ListWrapper[Int]]", SerializableTests.serializable(Eq[Chain[ListWrapper[Int]]])) } - - test("show"){ - Show[Chain[Int]].show(Chain(1, 2, 3)) should === ("Chain(1, 2, 3)") - Chain.empty[Int].show should === ("Chain()") + test("show") { + Show[Chain[Int]].show(Chain(1, 2, 3)) should ===("Chain(1, 2, 3)") + Chain.empty[Int].show should ===("Chain()") forAll { l: Chain[String] => - l.show should === (l.toString) + l.show should ===(l.toString) } } test("size is consistent with toList.size") { forAll { (ci: Chain[Int]) => - ci.size.toInt should === (ci.toList.size) + ci.size.toInt should ===(ci.toList.size) } } test("filterNot and then exists should always be false") { forAll { (ci: Chain[Int], f: Int => Boolean) => - ci.filterNot(f).exists(f) should === (false) + ci.filterNot(f).exists(f) should ===(false) } } test("filter and then forall should always be true") { forAll { (ci: Chain[Int], f: Int => Boolean) => - ci.filter(f).forall(f) should === (true) + ci.filter(f).forall(f) should ===(true) } } test("exists should be consistent with find + isDefined") { forAll { (ci: Chain[Int], f: Int => Boolean) => - ci.exists(f) should === (ci.find(f).isDefined) + ci.exists(f) should ===(ci.find(f).isDefined) } } test("deleteFirst consistent with find") { forAll { (ci: Chain[Int], f: Int => Boolean) => - ci.find(f) should === (ci.deleteFirst(f).map(_._1)) + ci.find(f) should ===(ci.deleteFirst(f).map(_._1)) } } test("filterNot element and then contains should be false") { forAll { (ci: Chain[Int], i: Int) => - ci.filterNot(_ === i).contains(i) should === (false) + ci.filterNot(_ === i).contains(i) should ===(false) } } test("Always nonempty after cons") { forAll { (ci: Chain[Int], i: Int) => - (i +: ci).nonEmpty should === (true) + (i +: ci).nonEmpty should ===(true) } } test("fromSeq . toVector is id") { forAll { (ci: Chain[Int]) => - Chain.fromSeq(ci.toVector) should === (ci) + Chain.fromSeq(ci.toVector) should ===(ci) } } test("fromSeq . toList . iterator is id") { forAll { (ci: Chain[Int]) => - Chain.fromSeq(ci.iterator.toList) should === (ci) + Chain.fromSeq(ci.iterator.toList) should ===(ci) } } test("zipWith consistent with List#zip and then List#map") { forAll { (a: Chain[String], b: Chain[Int], f: (String, Int) => Int) => - a.zipWith(b)(f).toList should === (a.toList.zip(b.toList).map { case (x, y) => f(x, y) }) + a.zipWith(b)(f).toList should ===(a.toList.zip(b.toList).map { case (x, y) => f(x, y) }) } } test("groupBy consistent with List#groupBy") { forAll { (cs: Chain[String], f: String => Int) => - cs.groupBy(f).map { case (k, v) => (k, v.toList) }.toMap should === (cs.toList.groupBy(f).toMap) + cs.groupBy(f).map { case (k, v) => (k, v.toList) }.toMap should ===(cs.toList.groupBy(f).toMap) } } test("reverse . reverse is id") { forAll { (ci: Chain[Int]) => - ci.reverse.reverse should === (ci) + ci.reverse.reverse should ===(ci) } } test("reverse consistent with List#reverse") { forAll { (ci: Chain[Int]) => - ci.reverse.toList should === (ci.toList.reverse) + ci.reverse.toList should ===(ci.toList.reverse) } } @@ -157,7 +159,7 @@ class ChainSuite extends CatsSuite { forAll { (a: Chain[Int]) => val it = a.iterator - while(it.hasNext) it.next + while (it.hasNext) it.next intercept[java.util.NoSuchElementException] { it.next @@ -165,7 +167,7 @@ class ChainSuite extends CatsSuite { val rit = a.reverseIterator - while(rit.hasNext) rit.next + while (rit.hasNext) rit.next intercept[java.util.NoSuchElementException] { rit.next diff --git a/tests/src/test/scala/cats/tests/CokleisliSuite.scala b/tests/src/test/scala/cats/tests/CokleisliSuite.scala index 7ffa5f5bad6..57e3520c0bc 100644 --- a/tests/src/test/scala/cats/tests/CokleisliSuite.scala +++ b/tests/src/test/scala/cats/tests/CokleisliSuite.scala @@ -12,9 +12,8 @@ import org.scalacheck.Arbitrary class CokleisliSuite extends SlowCatsSuite { implicit override val generatorDrivenConfig: PropertyCheckConfiguration = - slowCheckConfiguration.copy( - sizeRange = slowCheckConfiguration.sizeRange.min(5), - minSuccessful = slowCheckConfiguration.minSuccessful.min(20)) + slowCheckConfiguration.copy(sizeRange = slowCheckConfiguration.sizeRange.min(5), + minSuccessful = slowCheckConfiguration.minSuccessful.min(20)) implicit def cokleisliEq[F[_], A, B](implicit A: Arbitrary[F[A]], FB: Eq[B]): Eq[Cokleisli[F, A, B]] = Eq.by[Cokleisli[F, A, B], F[A] => B](_.run) @@ -25,38 +24,45 @@ class CokleisliSuite extends SlowCatsSuite { implicit val iso = SemigroupalTests.Isomorphisms.invariant[Cokleisli[Option, Int, ?]] checkAll("Cokleisli[Option, Int, Int]", SemigroupalTests[Cokleisli[Option, Int, ?]].semigroupal[Int, Int, Int]) - checkAll("Semigroupal[Cokleisli[Option, Int, ?]]", SerializableTests.serializable(Semigroupal[Cokleisli[Option, Int, ?]])) + checkAll("Semigroupal[Cokleisli[Option, Int, ?]]", + SerializableTests.serializable(Semigroupal[Cokleisli[Option, Int, ?]])) checkAll("Cokleisli[Option, Int, Int]", MonadTests[Cokleisli[Option, Int, ?]].monad[Int, Int, Int]) checkAll("Monad[Cokleisli[Option, Int, ?]]", SerializableTests.serializable(Monad[Cokleisli[Option, Int, ?]])) - checkAll("Cokleisli[Option, Int, Int]", ProfunctorTests[Cokleisli[Option, ?, ?]].profunctor[Int, Int, Int, Int, Int, Int]) + checkAll("Cokleisli[Option, Int, Int]", + ProfunctorTests[Cokleisli[Option, ?, ?]].profunctor[Int, Int, Int, Int, Int, Int]) checkAll("Profunctor[Cokleisli[Option, ?, ?]]", SerializableTests.serializable(Profunctor[Cokleisli[Option, ?, ?]])) checkAll("Cokleisli[Option, Int, Int]", ContravariantTests[Cokleisli[Option, ?, Int]].contravariant[Int, Int, Int]) - checkAll("Contravariant[Cokleisli[Option, ?, Int]]", SerializableTests.serializable(Contravariant[Cokleisli[Option, ?, Int]])) - + checkAll("Contravariant[Cokleisli[Option, ?, Int]]", + SerializableTests.serializable(Contravariant[Cokleisli[Option, ?, Int]])) checkAll("Cokleisli[NonEmptyList, Int, Int]", MonoidKTests[λ[α => Cokleisli[NonEmptyList, α, α]]].monoidK[Int]) - checkAll("MonoidK[λ[α => Cokleisli[NonEmptyList, α, α]]]", SerializableTests.serializable(MonoidK[λ[α => Cokleisli[NonEmptyList, α, α]]])) + checkAll("MonoidK[λ[α => Cokleisli[NonEmptyList, α, α]]]", + SerializableTests.serializable(MonoidK[λ[α => Cokleisli[NonEmptyList, α, α]]])) checkAll("Cokleisli[List, Int, Int]", SemigroupKTests[λ[α => Cokleisli[List, α, α]]].semigroupK[Int]) - checkAll("SemigroupK[λ[α => Cokleisli[List, α, α]]]", SerializableTests.serializable(SemigroupK[λ[α => Cokleisli[List, α, α]]])) + checkAll("SemigroupK[λ[α => Cokleisli[List, α, α]]]", + SerializableTests.serializable(SemigroupK[λ[α => Cokleisli[List, α, α]]])) - checkAll("Cokleisli[NonEmptyList, Int, Int]", ArrowTests[Cokleisli[NonEmptyList, ?, ?]].arrow[Int, Int, Int, Int, Int, Int]) + checkAll("Cokleisli[NonEmptyList, Int, Int]", + ArrowTests[Cokleisli[NonEmptyList, ?, ?]].arrow[Int, Int, Int, Int, Int, Int]) checkAll("Arrow[Cokleisli[NonEmptyList, ?, ?]]", SerializableTests.serializable(Arrow[Cokleisli[NonEmptyList, ?, ?]])) { implicit def cokleisliIdEq[A, B](implicit A: Arbitrary[A], FB: Eq[B]): Eq[Cokleisli[Id, A, B]] = Eq.by[Cokleisli[Id, A, B], A => B](_.run) - checkAll("Cokleisli[Id, Int, Int]", CommutativeArrowTests[Cokleisli[Id, ?, ?]].commutativeArrow[Int, Int, Int, Int, Int, Int]) - checkAll("CommutativeArrow[Cokleisli[Id, ?, ?]]", SerializableTests.serializable(CommutativeArrow[Cokleisli[Id, ?, ?]])) + checkAll("Cokleisli[Id, Int, Int]", + CommutativeArrowTests[Cokleisli[Id, ?, ?]].commutativeArrow[Int, Int, Int, Int, Int, Int]) + checkAll("CommutativeArrow[Cokleisli[Id, ?, ?]]", + SerializableTests.serializable(CommutativeArrow[Cokleisli[Id, ?, ?]])) } - test("contramapValue with Id consistent with lmap"){ + test("contramapValue with Id consistent with lmap") { forAll { (c: Cokleisli[Id, Int, Long], f: Char => Int) => - c.contramapValue[Char](f) should === (c.lmap(f)) + c.contramapValue[Char](f) should ===(c.lmap(f)) } } } diff --git a/tests/src/test/scala/cats/tests/ConstSuite.scala b/tests/src/test/scala/cats/tests/ConstSuite.scala index 80a658b26e3..3b1a10d9b7e 100644 --- a/tests/src/test/scala/cats/tests/ConstSuite.scala +++ b/tests/src/test/scala/cats/tests/ConstSuite.scala @@ -18,7 +18,8 @@ class ConstSuite extends CatsSuite { checkAll("Const[String, Int]", ApplicativeTests[Const[String, ?]].applicative[Int, Int, Int]) checkAll("Applicative[Const[String, ?]]", SerializableTests.serializable(Applicative[Const[String, ?]])) - checkAll("Const[String, Int] with Option", TraverseTests[Const[String, ?]].traverse[Int, Int, Int, Int, Option, Option]) + checkAll("Const[String, Int] with Option", + TraverseTests[Const[String, ?]].traverse[Int, Int, Int, Int, Option, Option]) checkAll("Traverse[Const[String, ?]]", SerializableTests.serializable(Traverse[Const[String, ?]])) checkAll("Const[String, Int]", TraverseFilterTests[Const[String, ?]].traverseFilter[Int, Int, Int]) @@ -27,9 +28,11 @@ class ConstSuite 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 = SemigroupalTests.Isomorphisms.invariant[Const[NonEmptyList[String], ?]](Const.catsDataContravariantForConst) + implicit val iso = + SemigroupalTests.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], ?]])) + checkAll("Apply[Const[NonEmptyList[String], ?]]", + SerializableTests.serializable(Apply[Const[NonEmptyList[String], ?]])) } // Algebra checks for Serializability of instances as part of the laws @@ -57,23 +60,25 @@ class ConstSuite extends CatsSuite { checkAll("Contravariant[Const[String, ?]]", SerializableTests.serializable(Contravariant[Const[String, ?]])) checkAll("Const[String, Int]", ContravariantMonoidalTests[Const[String, ?]].contravariantMonoidal[Int, Int, Int]) - checkAll("ContravariantMonoidal[Const[String, ?]]", SerializableTests.serializable(ContravariantMonoidal[Const[String, ?]])) + checkAll("ContravariantMonoidal[Const[String, ?]]", + SerializableTests.serializable(ContravariantMonoidal[Const[String, ?]])) checkAll("Const[?, ?]", BifoldableTests[Const].bifoldable[Int, Int, Int]) checkAll("Bifoldable[Const]", SerializableTests.serializable(Bifoldable[Const])) - checkAll("InvariantMonoidal[Const[String, ?]]", InvariantMonoidalTests[Const[String, ?]].invariantMonoidal[Int, Int, Int]) + checkAll("InvariantMonoidal[Const[String, ?]]", + InvariantMonoidalTests[Const[String, ?]].invariantMonoidal[Int, Int, Int]) checkAll("InvariantMonoidal[Const[String, ?]]", SerializableTests.serializable(InvariantMonoidal[Const[String, ?]])) test("show") { - Const(1).show should === ("Const(1)") + Const(1).show should ===("Const(1)") forAll { const: Const[Int, String] => - const.show.startsWith("Const(") should === (true) + const.show.startsWith("Const(") should ===(true) const.show.contains(const.getConst.show) - const.show should === (implicitly[Show[Const[Int, String]]].show(const)) - const.show should === (const.retag[Boolean].show) + const.show should ===(implicitly[Show[Const[Int, String]]].show(const)) + const.show should ===(const.retag[Boolean].show) } } @@ -83,7 +88,8 @@ class ConstSuite extends CatsSuite { { implicit val iso = SemigroupalTests.Isomorphisms.invariant[Const[CMono, ?]](Const.catsDataFunctorForConst) checkAll("Const[CMono, Int]", CommutativeApplicativeTests[Const[CMono, ?]].commutativeApplicative[Int, Int, Int]) - checkAll("CommutativeApplicative[Const[CMono, ?]]", SerializableTests.serializable(CommutativeApplicative[Const[CMono, ?]])) + checkAll("CommutativeApplicative[Const[CMono, ?]]", + SerializableTests.serializable(CommutativeApplicative[Const[CMono, ?]])) } checkAll("Const[CSemi, Int]", CommutativeApplyTests[Const[CSemi, ?]].commutativeApply[Int, Int, Int]) diff --git a/tests/src/test/scala/cats/tests/ContravariantSuite.scala b/tests/src/test/scala/cats/tests/ContravariantSuite.scala index 3524633c459..189005977f8 100644 --- a/tests/src/test/scala/cats/tests/ContravariantSuite.scala +++ b/tests/src/test/scala/cats/tests/ContravariantSuite.scala @@ -12,12 +12,12 @@ class ContravariantSuite extends CatsSuite { test("narrow equals contramap(identity)") { implicit val constInst = Const.catsDataContravariantForConst[Int] - implicit val canEqual: CanEqual[cats.data.Const[Int,Some[Int]],cats.data.Const[Int,Some[Int]]] = + implicit val canEqual: CanEqual[cats.data.Const[Int, Some[Int]], cats.data.Const[Int, Some[Int]]] = StrictCatsEquality.lowPriorityConversionCheckedConstraint forAll { (i: Int) => val const: Const[Int, Option[Int]] = Const[Int, Option[Int]](i) val narrowed: Const[Int, Some[Int]] = constInst.narrow[Option[Int], Some[Int]](const) - narrowed should === (constInst.contramap(const)(identity[Option[Int]](_: Some[Int]))) + narrowed should ===(constInst.contramap(const)(identity[Option[Int]](_: Some[Int]))) assert(narrowed eq const) } } @@ -30,17 +30,17 @@ class ContravariantSuite extends CatsSuite { def product[A, B](fa: Predicate[A], fb: Predicate[B]): Predicate[(A, B)] = Predicate(x => fa.run(x._1) && fb.run(x._2)) def contramap[A, B](fa: Predicate[A])(f: B => A): Predicate[B] = - Predicate(x => fa.run(f(x))) + Predicate(x => fa.run(f(x))) } implicit def eqPredicate[A: Arbitrary]: Eq[Predicate[A]] = Eq.by[Predicate[A], A => Boolean](_.run) - implicit def arbPredicate[A: Cogen]: Arbitrary[Predicate[A]] = Arbitrary(implicitly[Arbitrary[A => Boolean]].arbitrary.map(f => Predicate(f))) - checkAll("ContravariantMonoidal[Predicate]", ContravariantMonoidalTests[Predicate].contravariantMonoidal[Int, Int, Int]) + checkAll("ContravariantMonoidal[Predicate]", + ContravariantMonoidalTests[Predicate].contravariantMonoidal[Int, Int, Int]) { implicit val predicateMonoid = ContravariantMonoidal.monoid[Predicate, Int] diff --git a/tests/src/test/scala/cats/tests/CsvCodecInvariantMonoidalSuite.scala b/tests/src/test/scala/cats/tests/CsvCodecInvariantMonoidalSuite.scala index 96cbf7d18df..3ab768ddcc5 100644 --- a/tests/src/test/scala/cats/tests/CsvCodecInvariantMonoidalSuite.scala +++ b/tests/src/test/scala/cats/tests/CsvCodecInvariantMonoidalSuite.scala @@ -13,13 +13,14 @@ object CsvCodecInvariantMonoidalSuite { type CSV = List[String] /** - * Type class to read and write objects of type A to CSV. - * - * Obeys `forAll { (c: CsvCodec[A], a: A) => c.read(c.writes(a)) == (Some(a), List())`, - * under the assumtion that `imap(f, g)` is always called with `f` and `g` such that - * `forAll { (a: A) => g(f(a)) == a }`. - */ + * Type class to read and write objects of type A to CSV. + * + * Obeys `forAll { (c: CsvCodec[A], a: A) => c.read(c.writes(a)) == (Some(a), List())`, + * under the assumtion that `imap(f, g)` is always called with `f` and `g` such that + * `forAll { (a: A) => g(f(a)) == a }`. + */ trait CsvCodec[A] extends Serializable { self => + /** Reads the first value of a CSV, returning an optional value of type `A` and the remaining CSV. */ def read(s: CSV): (Option[A], CSV) @@ -43,7 +44,7 @@ object CsvCodecInvariantMonoidalSuite { def read(s: CSV): (Option[(A, B)], CSV) = { val (a1, s1) = fa.read(s) val (a2, s2) = fb.read(s1) - ((a1, a2).mapN(_ -> _), s2) + ((a1, a2).mapN(_ -> _), s2) } def write(a: (A, B)): CSV = @@ -82,7 +83,8 @@ object CsvCodecInvariantMonoidalSuite { implicit def csvCodecsEq[A](implicit a: Arbitrary[A], e: Eq[A]): Eq[CsvCodec[A]] = { val writeEq: Eq[CsvCodec[A]] = Eq.by[CsvCodec[A], A => CSV](_.write)(catsLawsEqForFn1[A, CSV]) - val readEq: Eq[CsvCodec[A]] = Eq.by[CsvCodec[A], CSV => (Option[A], CSV)](_.read)(catsLawsEqForFn1[CSV, (Option[A], CSV)]) + val readEq: Eq[CsvCodec[A]] = + Eq.by[CsvCodec[A], CSV => (Option[A], CSV)](_.read)(catsLawsEqForFn1[CSV, (Option[A], CSV)]) Eq.and(writeEq, readEq) } } diff --git a/tests/src/test/scala/cats/tests/DurationSuite.scala b/tests/src/test/scala/cats/tests/DurationSuite.scala index 693093d26d0..dcd6d2a2027 100644 --- a/tests/src/test/scala/cats/tests/DurationSuite.scala +++ b/tests/src/test/scala/cats/tests/DurationSuite.scala @@ -8,11 +8,11 @@ import scala.concurrent.duration.{Duration, DurationInt} class DurationSuite extends CatsSuite { checkAll("Show[Duration]", SerializableTests.serializable(Show[Duration])) - test("show works for FiniteDuration"){ + test("show works for FiniteDuration") { Show[Duration].show(23.minutes) should ===("23 minutes") } - test("show works for non-finite durations"){ + test("show works for non-finite durations") { Show[Duration].show(Duration.Inf) should ===("Duration.Inf") Show[Duration].show(Duration.MinusInf) should ===("Duration.MinusInf") Show[Duration].show(Duration.Undefined) should ===("Duration.Undefined") diff --git a/tests/src/test/scala/cats/tests/EitherKSuite.scala b/tests/src/test/scala/cats/tests/EitherKSuite.scala index 9871f8faf0c..04b63260ca7 100644 --- a/tests/src/test/scala/cats/tests/EitherKSuite.scala +++ b/tests/src/test/scala/cats/tests/EitherKSuite.scala @@ -9,13 +9,15 @@ import cats.laws.discipline.eq._ class EitherKSuite extends CatsSuite { - checkAll("EitherK[Option, Option, ?]", TraverseTests[EitherK[Option, Option, ?]].traverse[Int, Int, Int, Int, Option, Option]) + checkAll("EitherK[Option, Option, ?]", + TraverseTests[EitherK[Option, Option, ?]].traverse[Int, Int, Int, Int, Option, Option]) checkAll("Traverse[EitherK[Option, Option, ?]]", SerializableTests.serializable(Traverse[EitherK[Option, Option, ?]])) { implicit val foldable = EitherK.catsDataFoldableForEitherK[Option, Option] checkAll("EitherK[Option, Option, ?]", FoldableTests[EitherK[Option, Option, ?]].foldable[Int, Int]) - checkAll("Foldable[EitherK[Option, Option, ?]]", SerializableTests.serializable(Foldable[EitherK[Option, Option, ?]])) + checkAll("Foldable[EitherK[Option, Option, ?]]", + SerializableTests.serializable(Foldable[EitherK[Option, Option, ?]])) } checkAll("EitherK[Eval, Eval, ?]", ComonadTests[EitherK[Eval, Eval, ?]].comonad[Int, Int, Int]) @@ -31,7 +33,8 @@ class EitherKSuite extends CatsSuite { checkAll("Eq[EitherK[Option, Option, Int]]", SerializableTests.serializable(Eq[EitherK[Option, Option, Int]])) checkAll("EitherK[Show, Show, ?]", ContravariantTests[EitherK[Show, Show, ?]].contravariant[Int, Int, Int]) - checkAll("Contravariant[EitherK[Show, Show, ?]]", SerializableTests.serializable(Contravariant[EitherK[Show, Show, ?]])) + checkAll("Contravariant[EitherK[Show, Show, ?]]", + SerializableTests.serializable(Contravariant[EitherK[Show, Show, ?]])) test("double swap is identity") { forAll { (x: EitherK[Option, Option, Int]) => @@ -41,20 +44,20 @@ class EitherKSuite extends CatsSuite { test("swap negates isLeft/isRight") { forAll { (x: EitherK[Option, Option, Int]) => - x.isLeft should !== (x.swap.isLeft) - x.isRight should !== (x.swap.isRight) + x.isLeft should !==(x.swap.isLeft) + x.isRight should !==(x.swap.isRight) } } test("isLeft consistent with isRight") { forAll { (x: EitherK[Option, Option, Int]) => - x.isLeft should !== (x.isRight) + x.isLeft should !==(x.isRight) } } test("toValidated + toEither is identity") { forAll { (x: EitherK[Option, List, Int]) => - x.toValidated.toEither should === (x.run) + x.toValidated.toEither should ===(x.run) } } } diff --git a/tests/src/test/scala/cats/tests/EitherSuite.scala b/tests/src/test/scala/cats/tests/EitherSuite.scala index 05e81e073be..ed7c8927299 100644 --- a/tests/src/test/scala/cats/tests/EitherSuite.scala +++ b/tests/src/test/scala/cats/tests/EitherSuite.scala @@ -1,9 +1,9 @@ package cats package tests -import cats.data.{ EitherT, Validated, NonEmptySet, NonEmptyChain, NonEmptyList } +import cats.data.{EitherT, NonEmptyChain, NonEmptyList, NonEmptySet, Validated} import cats.laws.discipline._ -import cats.kernel.laws.discipline.{MonoidTests, SemigroupTests, OrderTests, PartialOrderTests, EqTests} +import cats.kernel.laws.discipline.{EqTests, MonoidTests, OrderTests, PartialOrderTests, SemigroupTests} import scala.util.Try class EitherSuite extends CatsSuite { @@ -27,10 +27,12 @@ class EitherSuite extends CatsSuite { checkAll("Bitraverse[Either]", SerializableTests.serializable(Bitraverse[Either])) checkAll("Either[ListWrapper[String], ?]", SemigroupKTests[Either[ListWrapper[String], ?]].semigroupK[Int]) - checkAll("SemigroupK[Either[ListWrapper[String], ?]]", SerializableTests.serializable(SemigroupK[Either[ListWrapper[String], ?]])) + checkAll("SemigroupK[Either[ListWrapper[String], ?]]", + SerializableTests.serializable(SemigroupK[Either[ListWrapper[String], ?]])) checkAll("Either[ListWrapper[String], Int]", SemigroupTests[Either[ListWrapper[String], Int]].semigroup) - checkAll("Semigroup[Either[ListWrapper[String], Int]]", SerializableTests.serializable(Semigroup[Either[ListWrapper[String], Int]])) + checkAll("Semigroup[Either[ListWrapper[String], Int]]", + SerializableTests.serializable(Semigroup[Either[ListWrapper[String], Int]])) val partialOrder = catsStdPartialOrderForEither[Int, String] val order = implicitly[Order[Either[Int, String]]] @@ -40,8 +42,10 @@ class EitherSuite extends CatsSuite { { implicit val S = ListWrapper.eqv[String] implicit val I = ListWrapper.eqv[Int] - checkAll("Either[ListWrapper[String], ListWrapper[Int]]", EqTests[Either[ListWrapper[String], ListWrapper[Int]]].eqv) - checkAll("Eq[Either[ListWrapper[String], ListWrapper[Int]]]", SerializableTests.serializable(Eq[Either[ListWrapper[String], ListWrapper[Int]]])) + checkAll("Either[ListWrapper[String], ListWrapper[Int]]", + EqTests[Either[ListWrapper[String], ListWrapper[Int]]].eqv) + checkAll("Eq[Either[ListWrapper[String], ListWrapper[Int]]]", + SerializableTests.serializable(Eq[Either[ListWrapper[String], ListWrapper[Int]]])) } checkAll("Either[Int, String]", PartialOrderTests[Either[Int, String]](partialOrder).partialOrder) @@ -50,7 +54,7 @@ class EitherSuite extends CatsSuite { test("Left/Right cast syntax") { forAll { (e: Either[Int, String]) => e match { - case l @ Left(_) => + case l @ Left(_) => l.rightCast[Double]: Either[Int, Double] assert(true) case r @ Right(_) => @@ -76,104 +80,106 @@ class EitherSuite extends CatsSuite { test("show isn't empty") { forAll { (e: Either[Int, String]) => - show.show(e).nonEmpty should === (true) + show.show(e).nonEmpty should ===(true) } } test("map2Eval is lazy") { val bomb: Eval[Either[String, Int]] = Later(sys.error("boom")) val x: Either[String, Int] = Left("l") - x.map2Eval(bomb)(_ + _).value should === (x) + x.map2Eval(bomb)(_ + _).value should ===(x) } test("catchOnly lets non-matching exceptions escape") { val _ = intercept[NumberFormatException] { - Either.catchOnly[IndexOutOfBoundsException]{ "foo".toInt } + Either.catchOnly[IndexOutOfBoundsException] { "foo".toInt } } } test("catchNonFatal catches non-fatal exceptions") { - assert(Either.catchNonFatal{ "foo".toInt }.isLeft) - assert(Either.catchNonFatal{ throw new Throwable("blargh") }.isLeft) + assert(Either.catchNonFatal { "foo".toInt }.isLeft) + assert(Either.catchNonFatal { throw new Throwable("blargh") }.isLeft) } test("fromTry is left for failed Try") { forAll { t: Try[Int] => - t.isFailure should === (Either.fromTry(t).isLeft) + t.isFailure should ===(Either.fromTry(t).isLeft) } } test("fromOption isLeft consistent with Option.isEmpty") { forAll { (o: Option[Int], s: String) => - Either.fromOption(o, s).isLeft should === (o.isEmpty) + Either.fromOption(o, s).isLeft should ===(o.isEmpty) } } test("leftNel is consistent with left(NEL)") { forAll { s: String => - Either.leftNel[String, Int](s) should === (Either.left[NonEmptyList[String], Int](NonEmptyList.one(s))) + Either.leftNel[String, Int](s) should ===(Either.left[NonEmptyList[String], Int](NonEmptyList.one(s))) } } test("rightNel is consistent with right") { forAll { i: Int => - Either.rightNel[String, Int](i) should === (Either.right[NonEmptyList[String], Int](i)) + Either.rightNel[String, Int](i) should ===(Either.right[NonEmptyList[String], Int](i)) } } test("double swap is identity") { forAll { (x: Either[Int, String]) => - x.swap.swap should === (x) + x.swap.swap should ===(x) } } test("leftNec is consistent with left(NEC)") { forAll { s: String => - Either.leftNec[String, Int](s) should === (Either.left[NonEmptyChain[String], Int](NonEmptyChain.one(s))) + Either.leftNec[String, Int](s) should ===(Either.left[NonEmptyChain[String], Int](NonEmptyChain.one(s))) } } test("rightNec is consistent with right") { forAll { i: Int => - Either.rightNec[String, Int](i) should === (Either.right[NonEmptyChain[String], Int](i)) + Either.rightNec[String, Int](i) should ===(Either.right[NonEmptyChain[String], Int](i)) } } test("leftNes is consistent with left(NES)") { forAll { s: String => - Either.leftNes[String, Int](s) should === (Either.left[NonEmptySet[String], Int](NonEmptySet.one(s))) + Either.leftNes[String, Int](s) should ===(Either.left[NonEmptySet[String], Int](NonEmptySet.one(s))) } } test("rightNes is consistent with right") { forAll { i: Int => - Either.rightNes[String, Int](i) should === (Either.right[NonEmptySet[String], Int](i)) + Either.rightNes[String, Int](i) should ===(Either.right[NonEmptySet[String], Int](i)) } } test("swap negates isLeft/isRight") { forAll { (x: Either[Int, String]) => - x.isLeft should !== (x.swap.isLeft) - x.isRight should !== (x.swap.isRight) + x.isLeft should !==(x.swap.isLeft) + x.isRight should !==(x.swap.isRight) } } test("isLeft consistent with isRight") { forAll { (x: Either[Int, String]) => - x.isLeft should !== (x.isRight) + x.isLeft should !==(x.isRight) } } test("foreach is noop for left") { forAll { (x: Either[Int, String]) => var count = 0 - x.foreach{ _ => count += 1} - (count == 0) should === (x.isLeft) + x.foreach { _ => + count += 1 + } + (count == 0) should ===(x.isLeft) } } test("getOrElse ignores default for right") { forAll { (x: Either[Int, String], s: String, t: String) => if (x.isRight) { - x.getOrElse(s) should === (x.getOrElse(t)) + x.getOrElse(s) should ===(x.getOrElse(t)) } } } @@ -181,50 +187,50 @@ class EitherSuite extends CatsSuite { test("orElse") { forAll { (x: Either[Int, String], y: Either[Int, String]) => val z = x.orElse(y) - (z === (x)) || (z === (y)) should === (true) + (z === (x)) || (z === (y)) should ===(true) } } test("recover recovers handled values") { val either = Either.left[String, Int]("either") - either.recover { case "either" => 5 }.isRight should === (true) + either.recover { case "either" => 5 }.isRight should ===(true) } test("recover ignores unhandled values") { val either = Either.left[String, Int]("either") - either.recover { case "noteither" => 5 } should === (either) + either.recover { case "noteither" => 5 } should ===(either) } test("recover ignores the right side") { val either = Either.right[String, Int](10) - either.recover { case "either" => 5 } should === (either) + either.recover { case "either" => 5 } should ===(either) } test("recoverWith recovers handled values") { val either = Either.left[String, Int]("either") - either.recoverWith { case "either" => Either.right[String, Int](5) }.isRight should === (true) + either.recoverWith { case "either" => Either.right[String, Int](5) }.isRight should ===(true) } test("recoverWith ignores unhandled values") { val either = Either.left[String, Int]("either") - either.recoverWith { case "noteither" => Either.right[String, Int](5) } should === (either) + either.recoverWith { case "noteither" => Either.right[String, Int](5) } should ===(either) } test("recoverWith ignores the right side") { val either = Either.right[String, Int](10) - either.recoverWith { case "either" => Either.right[String, Int](5) } should === (either) + either.recoverWith { case "either" => Either.right[String, Int](5) } should ===(either) } test("valueOr consistent with swap then map then merge") { forAll { (x: Either[Int, String], f: Int => String) => - x.valueOr(f) should === (x.swap.map(f).merge) + x.valueOr(f) should ===(x.swap.map(f).merge) } } test("isLeft implies forall") { forAll { (x: Either[Int, String], p: String => Boolean) => if (x.isLeft) { - x.forall(p) should === (true) + x.forall(p) should ===(true) } } } @@ -232,14 +238,14 @@ class EitherSuite extends CatsSuite { test("isLeft implies exists is false") { forAll { (x: Either[Int, String], p: String => Boolean) => if (x.isLeft) { - x.exists(p) should === (false) + x.exists(p) should ===(false) } } } test("toIor then toEither is identity") { forAll { (x: Either[Int, String]) => - x.toIor.toEither should === (x) + x.toIor.toEither should ===(x) } } @@ -247,113 +253,112 @@ class EitherSuite extends CatsSuite { implicit def eqTh: Eq[Throwable] = Eq.allEqual forAll { (x: Throwable Either String) => - Either.fromTry(x.toTry) should === (x) + Either.fromTry(x.toTry) should ===(x) } } test("isLeft consistency") { forAll { (x: Either[Int, String]) => - x.isLeft should === (x.toOption.isEmpty) - x.isLeft should === (x.toList.isEmpty) - x.isLeft should === (x.toValidated.isInvalid) - x.isLeft should === (x.toValidatedNel.isInvalid) - x.isLeft should === (x.toValidatedNec.isInvalid) - Option(x.isLeft) should === (x.toEitherT[Option].isLeft) + x.isLeft should ===(x.toOption.isEmpty) + x.isLeft should ===(x.toList.isEmpty) + x.isLeft should ===(x.toValidated.isInvalid) + x.isLeft should ===(x.toValidatedNel.isInvalid) + x.isLeft should ===(x.toValidatedNec.isInvalid) + Option(x.isLeft) should ===(x.toEitherT[Option].isLeft) } } test("withValidated") { forAll { (x: Either[Int, String], f: Int => Double) => - x.withValidated(_.bimap(f, identity)) should === (x.leftMap(f)) + x.withValidated(_.bimap(f, identity)) should ===(x.leftMap(f)) } } test("combine is right iff both operands are right") { forAll { (x: Either[Int, String], y: Either[Int, String]) => - x.combine(y).isRight should === (x.isRight && y.isRight) + x.combine(y).isRight should ===(x.isRight && y.isRight) } } test("to consistent with toList") { forAll { (x: Either[Int, String]) => - x.to[List] should === (x.toList) + x.to[List] should ===(x.toList) } } test("to consistent with toOption") { forAll { (x: Either[Int, String]) => - x.to[Option] should === (x.toOption) + x.to[Option] should ===(x.toOption) } } test("partialCompare consistent with PartialOrder") { - forAll { (x: Either[Int, String], y: Either[Int, String]) => - x.partialCompare(y) should === (partialOrder.partialCompare(x, y)) + forAll { (x: Either[Int, String], y: Either[Int, String]) => + x.partialCompare(y) should ===(partialOrder.partialCompare(x, y)) } } test("toEitherNec Left") { val either = Either.left[String, Int]("oops") - either.toEitherNec should === (Either.left[NonEmptyChain[String], Int](NonEmptyChain.one("oops"))) + either.toEitherNec should ===(Either.left[NonEmptyChain[String], Int](NonEmptyChain.one("oops"))) } test("toEitherNec Right") { val either = Either.right[String, Int](42) - either.toEitherNec should === (Either.right[NonEmptyChain[String], Int](42)) + either.toEitherNec should ===(Either.right[NonEmptyChain[String], Int](42)) } test("toEitherNes Left") { val either = Either.left[String, Int]("oops") - either.toEitherNes should === (Either.left[NonEmptySet[String], Int](NonEmptySet.one("oops"))) + either.toEitherNes should ===(Either.left[NonEmptySet[String], Int](NonEmptySet.one("oops"))) } test("toEitherNes Right") { val either = Either.right[String, Int](42) - either.toEitherNes should === (Either.right[NonEmptySet[String], Int](42)) + either.toEitherNes should ===(Either.right[NonEmptySet[String], Int](42)) } test("show Right") { val either = Either.right[String, Int](10) - either.show should === ("Right(10)") + either.show should ===("Right(10)") } test("show Left") { val either = Either.left[String, Int]("string") - either.show should === ("Left(string)") + either.show should ===("Left(string)") } test("toEitherNel Left") { val either = Either.left[String, Int]("oops") - either.toEitherNel should === (Either.left[NonEmptyList[String], Int](NonEmptyList.one("oops"))) + either.toEitherNel should ===(Either.left[NonEmptyList[String], Int](NonEmptyList.one("oops"))) } test("toEitherNel Right") { val either = Either.right[String, Int](42) - either.toEitherNel should === (Either.right[NonEmptyList[String], Int](42)) + either.toEitherNel should ===(Either.right[NonEmptyList[String], Int](42)) } test("ap consistent with Applicative") { val fab = implicitly[Applicative[Either[String, ?]]] - forAll { (fa: Either[String, Int], - f: Int => String) => - fa.ap(Either.right(f)) should === (fab.map(fa)(f)) + forAll { (fa: Either[String, Int], f: Int => String) => + fa.ap(Either.right(f)) should ===(fab.map(fa)(f)) } } test("raiseOrPure syntax consistent with fromEither") { val ev = ApplicativeError[Validated[String, ?], String] forAll { (fa: Either[String, Int]) => - fa.raiseOrPure[Validated[String, ?]] should === (ev.fromEither(fa)) + fa.raiseOrPure[Validated[String, ?]] should ===(ev.fromEither(fa)) } } test("leftFlatMap consistent with leftMap") { forAll { (either: Either[String, Int], f: String => String) => - either.leftFlatMap(v => Left(f(v))) should === (either.leftMap(f)) + either.leftFlatMap(v => Left(f(v))) should ===(either.leftMap(f)) } } test("leftFlatMap consistent with swap and then flatMap") { forAll { (either: Either[String, Int], f: String => Either[String, Int]) => - either.leftFlatMap(f) should === (either.swap.flatMap(a => f(a).swap).swap) + either.leftFlatMap(f) should ===(either.swap.flatMap(a => f(a).swap).swap) } } diff --git a/tests/src/test/scala/cats/tests/EitherTSuite.scala b/tests/src/test/scala/cats/tests/EitherTSuite.scala index e87400d1c97..1c8fdc11af3 100644 --- a/tests/src/test/scala/cats/tests/EitherTSuite.scala +++ b/tests/src/test/scala/cats/tests/EitherTSuite.scala @@ -6,44 +6,54 @@ import cats.data.EitherT import cats.laws.discipline._ import cats.laws.discipline.arbitrary._ -import cats.kernel.laws.discipline.{MonoidTests, SemigroupTests, OrderTests, PartialOrderTests, EqTests} - +import cats.kernel.laws.discipline.{EqTests, MonoidTests, OrderTests, PartialOrderTests, SemigroupTests} class EitherTSuite extends CatsSuite { - implicit val iso = SemigroupalTests.Isomorphisms.invariant[EitherT[ListWrapper, String, ?]](EitherT.catsDataFunctorForEitherT(ListWrapper.functor)) + implicit val iso = SemigroupalTests.Isomorphisms + .invariant[EitherT[ListWrapper, String, ?]](EitherT.catsDataFunctorForEitherT(ListWrapper.functor)) checkAll("EitherT[Eval, String, ?]", DeferTests[EitherT[Eval, String, ?]].defer[Int]) { - checkAll("EitherT[Option, ListWrapper[String], ?]", SemigroupKTests[EitherT[Option, ListWrapper[String], ?]].semigroupK[Int]) - checkAll("SemigroupK[EitherT[Option, ListWrapper[String], ?]]", SerializableTests.serializable(SemigroupK[EitherT[Option, ListWrapper[String], ?]])) + checkAll("EitherT[Option, ListWrapper[String], ?]", + SemigroupKTests[EitherT[Option, ListWrapper[String], ?]].semigroupK[Int]) + checkAll("SemigroupK[EitherT[Option, ListWrapper[String], ?]]", + SerializableTests.serializable(SemigroupK[EitherT[Option, ListWrapper[String], ?]])) } { implicit val F = ListWrapper.order[Either[String, Int]] checkAll("EitherT[List, String, Int]", OrderTests[EitherT[ListWrapper, String, Int]].order) - checkAll("Order[EitherT[List, String, Int]]", SerializableTests.serializable(Order[EitherT[ListWrapper, String, Int]])) + checkAll("Order[EitherT[List, String, Int]]", + SerializableTests.serializable(Order[EitherT[ListWrapper, String, Int]])) } { //If a Functor for F is defined implicit val F = ListWrapper.functor - checkAll("EitherT[ListWrapper, ?, ?]", BifunctorTests[EitherT[ListWrapper, ?, ?]].bifunctor[Int, Int, Int, String, String, String]) - checkAll("Bifunctor[EitherT[ListWrapper, ?, ?]]", SerializableTests.serializable(Bifunctor[EitherT[ListWrapper, ?, ?]])) + checkAll("EitherT[ListWrapper, ?, ?]", + BifunctorTests[EitherT[ListWrapper, ?, ?]].bifunctor[Int, Int, Int, String, String, String]) + checkAll("Bifunctor[EitherT[ListWrapper, ?, ?]]", + SerializableTests.serializable(Bifunctor[EitherT[ListWrapper, ?, ?]])) checkAll("EitherT[ListWrapper, Int, ?]", FunctorTests[EitherT[ListWrapper, Int, ?]].functor[Int, Int, Int]) - checkAll("Functor[EitherT[ListWrapper, Int, ?]]", SerializableTests.serializable(Functor[EitherT[ListWrapper, Int, ?]])) + checkAll("Functor[EitherT[ListWrapper, Int, ?]]", + SerializableTests.serializable(Functor[EitherT[ListWrapper, Int, ?]])) } { //If a Traverse for F is defined implicit val F = ListWrapper.traverse - checkAll("EitherT[ListWrapper, Int, ?]", TraverseTests[EitherT[ListWrapper, Int, ?]].traverse[Int, Int, Int, Int, Option, Option]) - checkAll("Traverse[EitherT[ListWrapper, Int, ?]]", SerializableTests.serializable(Traverse[EitherT[ListWrapper, Int, ?]])) - checkAll("EitherT[ListWrapper, ?, ?]", BitraverseTests[EitherT[ListWrapper, ?, ?]].bitraverse[Option, Int, Int, Int, String, String, String]) - checkAll("Bitraverse[EitherT[ListWrapper, ?, ?]]", SerializableTests.serializable(Bitraverse[EitherT[ListWrapper, ?, ?]])) + checkAll("EitherT[ListWrapper, Int, ?]", + TraverseTests[EitherT[ListWrapper, Int, ?]].traverse[Int, Int, Int, Int, Option, Option]) + checkAll("Traverse[EitherT[ListWrapper, Int, ?]]", + SerializableTests.serializable(Traverse[EitherT[ListWrapper, Int, ?]])) + checkAll("EitherT[ListWrapper, ?, ?]", + BitraverseTests[EitherT[ListWrapper, ?, ?]].bitraverse[Option, Int, Int, Int, String, String, String]) + checkAll("Bitraverse[EitherT[ListWrapper, ?, ?]]", + SerializableTests.serializable(Bitraverse[EitherT[ListWrapper, ?, ?]])) } @@ -58,8 +68,10 @@ class EitherTSuite extends CatsSuite { Applicative[EitherT[ListWrapper, String, ?]] Monad[EitherT[ListWrapper, String, ?]] - checkAll("EitherT[ListWrapper, String, Int]", MonadErrorTests[EitherT[ListWrapper, String, ?], String].monadError[Int, Int, Int]) - checkAll("MonadError[EitherT[List, ?, ?]]", SerializableTests.serializable(MonadError[EitherT[ListWrapper, String, ?], String])) + checkAll("EitherT[ListWrapper, String, Int]", + MonadErrorTests[EitherT[ListWrapper, String, ?], String].monadError[Int, Int, Int]) + checkAll("MonadError[EitherT[List, ?, ?]]", + SerializableTests.serializable(MonadError[EitherT[ListWrapper, String, ?], String])) } @@ -75,8 +87,10 @@ class EitherTSuite extends CatsSuite { Applicative[EitherT[Option, String, ?]] Monad[EitherT[Option, String, ?]] - checkAll("EitherT[Option, String, String]", MonadErrorTests[EitherT[Option, String, ?], Unit].monadError[String, String, String]) - checkAll("MonadError[EitherT[Option, ?, ?]]", SerializableTests.serializable(MonadError[EitherT[Option, String, ?], Unit])) + checkAll("EitherT[Option, String, String]", + MonadErrorTests[EitherT[Option, String, ?], Unit].monadError[String, String, String]) + checkAll("MonadError[EitherT[Option, ?, ?]]", + SerializableTests.serializable(MonadError[EitherT[Option, String, ?], Unit])) } { @@ -88,7 +102,8 @@ class EitherTSuite extends CatsSuite { Monad[EitherT[ListWrapper, String, ?]] checkAll("EitherT[ListWrapper, String, Int]", MonadTests[EitherT[ListWrapper, String, ?]].monad[Int, Int, Int]) - checkAll("Monad[EitherT[ListWrapper, String, ?]]", SerializableTests.serializable(Monad[EitherT[ListWrapper, String, ?]])) + checkAll("Monad[EitherT[ListWrapper, String, ?]]", + SerializableTests.serializable(Monad[EitherT[ListWrapper, String, ?]])) } { @@ -96,21 +111,24 @@ class EitherTSuite extends CatsSuite { implicit val F = ListWrapper.foldable checkAll("EitherT[ListWrapper, Int, ?]", FoldableTests[EitherT[ListWrapper, Int, ?]].foldable[Int, Int]) - checkAll("Foldable[EitherT[ListWrapper, Int, ?]]", SerializableTests.serializable(Foldable[EitherT[ListWrapper, Int, ?]])) + checkAll("Foldable[EitherT[ListWrapper, Int, ?]]", + SerializableTests.serializable(Foldable[EitherT[ListWrapper, Int, ?]])) } { implicit val F = ListWrapper.partialOrder[Either[String, Int]] checkAll("EitherT[ListWrapper, String, Int]", PartialOrderTests[EitherT[ListWrapper, String, Int]].partialOrder) - checkAll("PartialOrder[EitherT[ListWrapper, String, Int]]", SerializableTests.serializable(PartialOrder[EitherT[ListWrapper, String, Int]])) + checkAll("PartialOrder[EitherT[ListWrapper, String, Int]]", + SerializableTests.serializable(PartialOrder[EitherT[ListWrapper, String, Int]])) } { implicit val F = ListWrapper.semigroup[Either[String, Int]] checkAll("EitherT[ListWrapper, String, Int]", SemigroupTests[EitherT[ListWrapper, String, Int]].semigroup) - checkAll("Semigroup[EitherT[ListWrapper, String, Int]]", SerializableTests.serializable(Semigroup[EitherT[ListWrapper, String, Int]])) + checkAll("Semigroup[EitherT[ListWrapper, String, Int]]", + SerializableTests.serializable(Semigroup[EitherT[ListWrapper, String, Int]])) } { @@ -119,315 +137,317 @@ class EitherTSuite extends CatsSuite { Semigroup[EitherT[ListWrapper, String, Int]] checkAll("EitherT[ListWrapper, String, Int]", MonoidTests[EitherT[ListWrapper, String, Int]].monoid) - checkAll("Monoid[EitherT[ListWrapper, String, Int]]", SerializableTests.serializable(Monoid[EitherT[ListWrapper, String, Int]])) + checkAll("Monoid[EitherT[ListWrapper, String, Int]]", + SerializableTests.serializable(Monoid[EitherT[ListWrapper, String, Int]])) } { implicit val F = ListWrapper.eqv[Either[String, Int]] checkAll("EitherT[ListWrapper, String, Int]", EqTests[EitherT[ListWrapper, String, Int]].eqv) - checkAll("Eq[EitherT[ListWrapper, String, Int]]", SerializableTests.serializable(Eq[EitherT[ListWrapper, String, Int]])) + checkAll("Eq[EitherT[ListWrapper, String, Int]]", + SerializableTests.serializable(Eq[EitherT[ListWrapper, String, Int]])) } test("toValidated") { forAll { (eithert: EitherT[List, String, Int]) => - eithert.toValidated.map(_.toEither) should === (eithert.value) + eithert.toValidated.map(_.toEither) should ===(eithert.value) } } test("toValidatedNel") { forAll { (eithert: EitherT[List, String, Int]) => - eithert.toValidatedNel.map(_.toEither.leftMap(_.head)) should === (eithert.value) + eithert.toValidatedNel.map(_.toEither.leftMap(_.head)) should ===(eithert.value) } } test("toValidatedNec") { forAll { (eithert: EitherT[List, String, Int]) => - eithert.toValidatedNec.map(_.toEither.leftMap(_.head)) should === (eithert.value) + eithert.toValidatedNec.map(_.toEither.leftMap(_.head)) should ===(eithert.value) } } test("toNested") { forAll { (eithert: EitherT[List, String, Int]) => - eithert.toNested.value should === (eithert.value) + eithert.toNested.value should ===(eithert.value) } } test("toNestedValidated") { forAll { (eithert: EitherT[List, String, Int]) => - eithert.toNestedValidated.value should === (eithert.value.map(_.toValidated)) + eithert.toNestedValidated.value should ===(eithert.value.map(_.toValidated)) } } test("toNestedValidatedNel") { forAll { (eithert: EitherT[List, String, Int]) => - eithert.toNestedValidatedNel.value should === (eithert.value.map(_.toValidatedNel)) + eithert.toNestedValidatedNel.value should ===(eithert.value.map(_.toValidatedNel)) } } test("toNestedValidatedNec") { forAll { (eithert: EitherT[List, String, Int]) => - eithert.toNestedValidatedNec.value should === (eithert.value.map(_.toValidatedNec)) + eithert.toNestedValidatedNec.value should ===(eithert.value.map(_.toValidatedNec)) } } test("withValidated") { forAll { (eithert: EitherT[List, String, Int], f: String => Char, g: Int => Double) => - eithert.withValidated(_.bimap(f, g)) should === (eithert.bimap(f, g)) + eithert.withValidated(_.bimap(f, g)) should ===(eithert.bimap(f, g)) } } test("fromEither") { forAll { (either: Either[String, Int]) => - Some(either.isLeft) should === (EitherT.fromEither[Option](either).isLeft) + Some(either.isLeft) should ===(EitherT.fromEither[Option](either).isLeft) } } test("fromOption isLeft consistent with Option.isEmpty") { forAll { (o: Option[Int], s: String) => - EitherT.fromOption[Id](o, s).isLeft should === (o.isEmpty) + EitherT.fromOption[Id](o, s).isLeft should ===(o.isEmpty) } } test("cond consistent with Either.cond") { forAll { (cond: Boolean, s: String, i: Int) => - EitherT.cond[Id](cond, s, i).value should === (Either.cond(cond, s, i)) + EitherT.cond[Id](cond, s, i).value should ===(Either.cond(cond, s, i)) } } test("isLeft negation of isRight") { forAll { (eithert: EitherT[List, String, Int]) => - eithert.isLeft should === (eithert.isRight.map(! _)) + eithert.isLeft should ===(eithert.isRight.map(!_)) } } test("double swap is noop") { forAll { (eithert: EitherT[List, String, Int]) => - eithert.swap.swap should === (eithert) + eithert.swap.swap should ===(eithert) } } test("swap negates isRight") { forAll { (eithert: EitherT[List, String, Int]) => - eithert.swap.isRight should === (eithert.isRight.map(! _)) + eithert.swap.isRight should ===(eithert.isRight.map(!_)) } } test("toOption on Right returns Some") { forAll { (eithert: EitherT[List, String, Int]) => - eithert.toOption.isDefined should === (eithert.isRight) + eithert.toOption.isDefined should ===(eithert.isRight) } } test("toEither preserves isRight") { forAll { (eithert: EitherT[List, String, Int]) => - eithert.value.map(_.isRight) should === (eithert.isRight) + eithert.value.map(_.isRight) should ===(eithert.isRight) } } test("recover recovers handled values") { val eithert = EitherT.leftT[Id, Int]("eithert") - eithert.recover { case "eithert" => 5 }.isRight should === (true) + eithert.recover { case "eithert" => 5 }.isRight should ===(true) } test("recover ignores unhandled values") { val eithert = EitherT.leftT[Id, Int]("eithert") - eithert.recover { case "noteithert" => 5 } should === (eithert) + eithert.recover { case "noteithert" => 5 } should ===(eithert) } test("recover ignores the right side") { val eithert = EitherT.pure[Id, String](10) - eithert.recover { case "eithert" => 5 } should === (eithert) + eithert.recover { case "eithert" => 5 } should ===(eithert) } test("recoverWith recovers handled values") { val eithert = EitherT.leftT[Id, Int]("eithert") - eithert.recoverWith { case "eithert" => EitherT.pure[Id, String](5) }.isRight should === (true) + eithert.recoverWith { case "eithert" => EitherT.pure[Id, String](5) }.isRight should ===(true) } test("recoverWith ignores unhandled values") { val eithert = EitherT.leftT[Id, Int]("eithert") - eithert.recoverWith { case "noteithert" => EitherT.pure[Id, String](5) } should === (eithert) + eithert.recoverWith { case "noteithert" => EitherT.pure[Id, String](5) } should ===(eithert) } test("transform consistent with value.map") { forAll { (eithert: EitherT[List, String, Int], f: Either[String, Int] => Either[Long, Double]) => - eithert.transform(f) should === (EitherT(eithert.value.map(f))) + eithert.transform(f) should ===(EitherT(eithert.value.map(f))) } } test("mapK consistent with f(value)+pure") { val f: List ~> Option = λ[List ~> Option](_.headOption) forAll { (eithert: EitherT[List, String, Int]) => - eithert.mapK(f) should === (EitherT(f(eithert.value))) + eithert.mapK(f) should ===(EitherT(f(eithert.value))) } } test("semiflatMap consistent with value.flatMap+f+pure") { forAll { (eithert: EitherT[List, String, Int], f: Int => List[String]) => - eithert.semiflatMap(f) should === (EitherT(eithert.value.flatMap { + eithert.semiflatMap(f) should ===(EitherT(eithert.value.flatMap { case l @ Left(_) => List(l.asInstanceOf[Either[String, String]]) - case Right(b) => f(b).map(Right(_)) + case Right(b) => f(b).map(Right(_)) })) } } test("subflatMap consistent with value.map+flatMap") { forAll { (eithert: EitherT[List, String, Int], f: Int => Either[String, Double]) => - eithert.subflatMap(f) should === (EitherT(eithert.value.map(_.flatMap(f)))) + eithert.subflatMap(f) should ===(EitherT(eithert.value.map(_.flatMap(f)))) } } test("flatMap and flatMapF consistent") { - forAll { (eithert: EitherT[List, String, Int], f: Int => EitherT[List, String, Int]) => - eithert.flatMap(f) should === (eithert.flatMapF(f(_).value)) + forAll { (eithert: EitherT[List, String, Int], f: Int => EitherT[List, String, Int]) => + eithert.flatMap(f) should ===(eithert.flatMapF(f(_).value)) } } test("fold with Id consistent with Either fold") { forAll { (eithert: EitherT[Id, String, Int], f: String => Long, g: Int => Long) => - eithert.fold(f, g) should === (eithert.value.fold(f, g)) + eithert.fold(f, g) should ===(eithert.value.fold(f, g)) } } test("valueOr with Id consistent with Either valueOr") { forAll { (eithert: EitherT[Id, String, Int], f: String => Int) => - eithert.valueOr(f) should === (eithert.value.valueOr(f)) + eithert.valueOr(f) should ===(eithert.value.valueOr(f)) } } test("valueOrF with Id consistent with Either valueOr") { - forAll{ (eithert: EitherT[Id, String, Int], f: String => Int) => - eithert.valueOrF(f) should === (eithert.value.valueOr(f)) + forAll { (eithert: EitherT[Id, String, Int], f: String => Int) => + eithert.valueOrF(f) should ===(eithert.value.valueOr(f)) } } test("getOrElse with Id consistent with Either getOrElse") { forAll { (eithert: EitherT[Id, String, Int], i: Int) => - eithert.getOrElse(i) should === (eithert.value.getOrElse(i)) + eithert.getOrElse(i) should ===(eithert.value.getOrElse(i)) } } test("getOrElseF with Id consistent with Either getOrElse") { forAll { (eithert: EitherT[Id, String, Int], i: Int) => - eithert.getOrElseF(i) should === (eithert.value.getOrElse(i)) + eithert.getOrElseF(i) should ===(eithert.value.getOrElse(i)) } } test("orElse with Id consistent with Either orElse") { forAll { (eithert: EitherT[Id, String, Int], fallback: EitherT[Id, String, Int]) => - eithert.orElse(fallback).value should === (eithert.value.orElse(fallback.value)) + eithert.orElse(fallback).value should ===(eithert.value.orElse(fallback.value)) } } test("orElse evaluates effect only once") { forAll { (either: Either[String, Int], fallback: EitherT[Eval, String, Int]) => var evals = 0 - val eithert = (EitherT(Eval.always { evals += 1; either }) orElse fallback) + val eithert = EitherT(Eval.always { evals += 1; either }).orElse(fallback) eithert.value.value - evals should === (1) + evals should ===(1) } } test("forall with Id consistent with Either forall") { forAll { (eithert: EitherT[Id, String, Int], f: Int => Boolean) => - eithert.forall(f) should === (eithert.value.forall(f)) + eithert.forall(f) should ===(eithert.value.forall(f)) } } test("exists with Id consistent with Either exists") { forAll { (eithert: EitherT[Id, String, Int], f: Int => Boolean) => - eithert.exists(f) should === (eithert.value.exists(f)) + eithert.exists(f) should ===(eithert.value.exists(f)) } } test("leftMap with Id consistent with Either leftMap") { forAll { (eithert: EitherT[Id, String, Int], f: String => Long) => - eithert.leftMap(f).value should === (eithert.value.leftMap(f)) + eithert.leftMap(f).value should ===(eithert.value.leftMap(f)) } } test("compare with Id consistent with Either compare") { forAll { (x: EitherT[Id, String, Int], y: EitherT[Id, String, Int]) => - x.compare(y) should === (x.value.compare(y.value)) + x.compare(y) should ===(x.value.compare(y.value)) } } test("=== with Id consistent with Either ===") { forAll { (x: EitherT[Id, String, Int], y: EitherT[Id, String, Int]) => - x === y should === (x.value === y.value) + x === y should ===(x.value === y.value) } } test("traverse with Id consistent with Either traverse") { forAll { (x: EitherT[Id, String, Int], f: Int => Option[Long]) => val e: Either[String, Int] = x.value - x.traverse(f).map(_.value) should === (e.traverse(f)) + x.traverse(f).map(_.value) should ===(e.traverse(f)) } } test("foldLeft with Id consistent with Either foldLeft") { forAll { (x: EitherT[Id, String, Int], l: Long, f: (Long, Int) => Long) => - x.foldLeft(l)(f) should === (x.value.foldLeft(l)(f)) + x.foldLeft(l)(f) should ===(x.value.foldLeft(l)(f)) } } test("foldRight with Id consistent with Either foldRight") { forAll { (x: EitherT[Id, String, Int], l: Eval[Long], f: (Int, Eval[Long]) => Eval[Long]) => - x.foldRight(l)(f) should === (x.value.foldRight(l)(f)) + x.foldRight(l)(f) should ===(x.value.foldRight(l)(f)) } } test("collectRight with Option consistent with flattening a to[Option]") { forAll { (et: EitherT[Option, String, Int]) => - et.collectRight should === (et.to[Option].flatten) + et.collectRight should ===(et.to[Option].flatten) } } test("applyAlt with Id consistent with EitherT map") { forAll { (et: EitherT[Id, String, Int], f: Int => String) => - et.applyAlt(EitherT.pure(f)) should === (et.map(f)) + et.applyAlt(EitherT.pure(f)) should ===(et.map(f)) } } test("merge with Id consistent with Either merge") { forAll { (x: EitherT[Id, Int, Int]) => - x.merge should === (x.value.merge) + x.merge should ===(x.value.merge) } } test("to consistent with toOption") { forAll { (x: EitherT[List, String, Int]) => - x.to[Option] should === (x.toOption.value) + x.to[Option] should ===(x.toOption.value) } } test("toEither consistent with toOption") { forAll { (x: EitherT[List, String, Int]) => - x.value.map(_.right.toOption) should === (x.toOption.value) + x.value.map(_.right.toOption) should ===(x.toOption.value) } } test("ensure on left is identity") { forAll { (x: EitherT[Id, String, Int], s: String, p: Int => Boolean) => if (x.isLeft) { - x.ensure(s)(p) should === (x) + x.ensure(s)(p) should ===(x) } } } test("ensure on right is identity if predicate satisfied") { forAll { (x: EitherT[Id, String, Int], s: String, p: Int => Boolean) => - if (x.isRight && p(x getOrElse 0)) { - x.ensure(s)(p) should === (x) + if (x.isRight && p(x.getOrElse(0))) { + x.ensure(s)(p) should ===(x) } } } test("ensure should fail if predicate not satisfied") { forAll { (x: EitherT[Id, String, Int], s: String, p: Int => Boolean) => - if (x.isRight && !p(x getOrElse 0)) { - x.ensure(s)(p) should === (EitherT.leftT[Id, Int](s)) + if (x.isRight && !p(x.getOrElse(0))) { + x.ensure(s)(p) should ===(EitherT.leftT[Id, Int](s)) } } } @@ -437,8 +457,8 @@ class EitherTSuite extends CatsSuite { case object Error1 extends AppError case object Error2 extends AppError - val either1: Id[Either[Error1.type , String]] = Right("hi").pure[Id] - val either2: Id[Either[Error2.type , String]] = Right("bye").pure[Id] + val either1: Id[Either[Error1.type, String]] = Right("hi").pure[Id] + val either2: Id[Either[Error2.type, String]] = Right("bye").pure[Id] for { s1 <- EitherT(either1) @@ -487,7 +507,7 @@ class EitherTSuite extends CatsSuite { test("biSemiflatMap consistent with leftSemiflatMap and semiFlatmap") { forAll { (eithert: EitherT[List, String, Int], fa: String => List[Int], fb: Int => List[String]) => - eithert.biSemiflatMap(fa, fb) should === (eithert.leftSemiflatMap(fa).semiflatMap(fb)) + eithert.biSemiflatMap(fa, fb) should ===(eithert.leftSemiflatMap(fa).semiflatMap(fb)) } } diff --git a/tests/src/test/scala/cats/tests/EqSuite.scala b/tests/src/test/scala/cats/tests/EqSuite.scala index 7b70689a014..91c16adf161 100644 --- a/tests/src/test/scala/cats/tests/EqSuite.scala +++ b/tests/src/test/scala/cats/tests/EqSuite.scala @@ -6,15 +6,13 @@ import cats.laws.discipline.ContravariantMonoidalTests import cats.laws.discipline.arbitrary._ import cats.laws.discipline.eq._ - - class EqSuite extends CatsSuite { - Invariant[Eq] - Contravariant[Eq] - Semigroupal[Eq] - ContravariantSemigroupal[Eq] + Invariant[Eq] + Contravariant[Eq] + Semigroupal[Eq] + ContravariantSemigroupal[Eq] - checkAll("Eq[Int]", ContravariantMonoidalTests[Eq].contravariantMonoidal[Int, Int, Int]) - checkAll("ContravariantMonoidal[Eq]", SerializableTests.serializable(ContravariantMonoidal[Eq])) + checkAll("Eq[Int]", ContravariantMonoidalTests[Eq].contravariantMonoidal[Int, Int, Int]) + checkAll("ContravariantMonoidal[Eq]", SerializableTests.serializable(ContravariantMonoidal[Eq])) } diff --git a/tests/src/test/scala/cats/tests/EquivSuite.scala b/tests/src/test/scala/cats/tests/EquivSuite.scala index 86c8e0ec315..62bf7d5fc74 100644 --- a/tests/src/test/scala/cats/tests/EquivSuite.scala +++ b/tests/src/test/scala/cats/tests/EquivSuite.scala @@ -1,7 +1,6 @@ package cats package tests - import cats.laws.discipline.arbitrary._ import cats.laws.discipline._ import cats.laws.discipline.eq._ @@ -16,8 +15,6 @@ class EquivSuite extends CatsSuite { checkAll("Contravariant[Equiv]", ContravariantTests[Equiv].contravariant[Int, Int, Int]) checkAll("Semigroupal[Equiv]", SemigroupalTests[Equiv].semigroupal[Int, Int, Int]) - checkAll("ContravariantMonoidal[Equiv]", - ContravariantMonoidalTests[Equiv].contravariantMonoidal[Int, Int, Int]) - checkAll("ContravariantMonoidal[Equiv]", - SerializableTests.serializable(ContravariantMonoidal[Equiv])) + checkAll("ContravariantMonoidal[Equiv]", ContravariantMonoidalTests[Equiv].contravariantMonoidal[Int, Int, Int]) + checkAll("ContravariantMonoidal[Equiv]", SerializableTests.serializable(ContravariantMonoidal[Equiv])) } diff --git a/tests/src/test/scala/cats/tests/EvalSuite.scala b/tests/src/test/scala/cats/tests/EvalSuite.scala index 979e6b70dad..6bba3c07bbc 100644 --- a/tests/src/test/scala/cats/tests/EvalSuite.scala +++ b/tests/src/test/scala/cats/tests/EvalSuite.scala @@ -2,7 +2,14 @@ package cats package tests import cats.laws.ComonadLaws -import cats.laws.discipline.{BimonadTests, CommutativeMonadTests, DeferTests, SemigroupalTests, ReducibleTests, SerializableTests} +import cats.laws.discipline.{ + BimonadTests, + CommutativeMonadTests, + DeferTests, + ReducibleTests, + SemigroupalTests, + SerializableTests +} import cats.laws.discipline.arbitrary._ import cats.kernel.laws.discipline.{EqTests, GroupTests, MonoidTests, OrderTests, PartialOrderTests, SemigroupTests} import org.scalacheck.{Arbitrary, Cogen, Gen} @@ -14,31 +21,31 @@ class EvalSuite extends CatsSuite { implicit val eqThrow: Eq[Throwable] = Eq.allEqual /** - * This method creates a Eval[A] instance (along with a - * corresponding Spooky instance) from an initial `value` using the - * given `init` function. - * - * It will then proceed to call `value` 0-or-more times, verifying - * that the result is equal to `value`, and also that the - * appropriate number of evaluations are occurring using the - * `numCalls` function. - * - * In other words, each invocation of run says: - * - * 1. What underlying `value` to use. - * 2. How to create Eval instances (memoized, eager, or by-name). - * 3. How many times we expect the value to be computed. - */ + * This method creates a Eval[A] instance (along with a + * corresponding Spooky instance) from an initial `value` using the + * given `init` function. + * + * It will then proceed to call `value` 0-or-more times, verifying + * that the result is equal to `value`, and also that the + * appropriate number of evaluations are occurring using the + * `numCalls` function. + * + * In other words, each invocation of run says: + * + * 1. What underlying `value` to use. + * 2. How to create Eval instances (memoized, eager, or by-name). + * 3. How many times we expect the value to be computed. + */ def runValue[A: Eq](value: A)(init: A => (Spooky, Eval[A]))(numCalls: Int => Int): Unit = { var spin = 0 def nTimes(n: Int, numEvals: Int): Unit = { val (spooky, lz) = init(value) (0 until n).foreach { _ => val result = lz.value - result should === (value) + result should ===(value) spin ^= result.## } - spooky.counter should === (numEvals) + spooky.counter should ===(numEvals) () } (0 to 2).foreach(n => nTimes(n, numCalls(n))) @@ -74,18 +81,18 @@ class EvalSuite extends CatsSuite { runValue(999)(always)(n => n) } - test(".value should evaluate only once on the result of .memoize"){ + test(".value should evaluate only once on the result of .memoize") { val spooky = new Spooky val i2 = Eval.always(spooky.increment()).memoize val i3 = Eval.now(()).flatMap(_ => Eval.later(spooky.increment())).memoize i2.value - spooky.counter should === (1) + spooky.counter should ===(1) i2.value - spooky.counter should === (1) + spooky.counter should ===(1) i3.value - spooky.counter should === (2) + spooky.counter should ===(2) i3.value - spooky.counter should === (2) + spooky.counter should ===(2) } { @@ -137,14 +144,14 @@ class EvalSuite extends CatsSuite { test("cokleisli left identity") { forAll { (fa: Eval[Int], f: Eval[Int] => Long) => val isEq = ComonadLaws[Eval].cokleisliLeftIdentity(fa, f) - isEq.lhs should === (isEq.rhs) + isEq.lhs should ===(isEq.rhs) } } test("cokleisli right identity") { forAll { (fa: Eval[Int], f: Eval[Int] => Long) => val isEq = ComonadLaws[Eval].cokleisliRightIdentity(fa, f) - isEq.lhs should === (isEq.rhs) + isEq.lhs should ===(isEq.rhs) } } @@ -184,11 +191,12 @@ class EvalSuite extends CatsSuite { case class ODefer[A]() extends O[A] implicit def arbitraryO[A: Arbitrary: Cogen]: Arbitrary[O[A]] = - Arbitrary(Gen.oneOf( - arbitrary[A => A].map(OMap(_)), - arbitrary[A => Eval[A]].map(OFlatMap(_)), - Gen.const(OMemoize[A]), - Gen.const(ODefer[A]))) + Arbitrary( + Gen.oneOf(arbitrary[A => A].map(OMap(_)), + arbitrary[A => Eval[A]].map(OFlatMap(_)), + Gen.const(OMemoize[A]), + Gen.const(ODefer[A])) + ) def build[A](leaf: () => Eval[A], os: Vector[O[A]]): DeepEval[A] = { @@ -197,12 +205,13 @@ class EvalSuite extends CatsSuite { @tailrec def step(i: Int, leaf: () => Eval[A], cbs: List[Eval[A] => Eval[A]]): Eval[A] = if (i >= os.length) cbs.foldLeft(leaf())((e, f) => f(e)) - else os(i) match { - case ODefer() => Eval.defer(restart(i + 1, leaf, cbs)) - case OMemoize() => step(i + 1, leaf, ((e: Eval[A]) => e.memoize) :: cbs) - case OMap(f) => step(i + 1, leaf, ((e: Eval[A]) => e.map(f)) :: cbs) - case OFlatMap(f) => step(i + 1, leaf, ((e: Eval[A]) => e.flatMap(f)) :: cbs) - } + else + os(i) match { + case ODefer() => Eval.defer(restart(i + 1, leaf, cbs)) + case OMemoize() => step(i + 1, leaf, ((e: Eval[A]) => e.memoize) :: cbs) + case OMap(f) => step(i + 1, leaf, ((e: Eval[A]) => e.map(f)) :: cbs) + case OFlatMap(f) => step(i + 1, leaf, ((e: Eval[A]) => e.flatMap(f)) :: cbs) + } DeepEval(step(0, leaf, Nil)) } @@ -227,8 +236,9 @@ class EvalSuite extends CatsSuite { try { d.eval.value succeed - } catch { case (e: StackOverflowError) => - fail(s"stack overflowed with eval-depth ${DeepEval.MaxDepth}") + } catch { + case (e: StackOverflowError) => + fail(s"stack overflowed with eval-depth ${DeepEval.MaxDepth}") } } } @@ -236,7 +246,9 @@ class EvalSuite extends CatsSuite { test("memoize handles branched evaluation correctly") { forAll { (e: Eval[Int], fn: Int => Eval[Int]) => var n0 = 0 - val a0 = e.flatMap { i => n0 += 1; fn(i); }.memoize + val a0 = e.flatMap { i => + n0 += 1; fn(i); + }.memoize assert(a0.flatMap(i1 => a0.map(i1 == _)).value == true) assert(n0 == 1) diff --git a/tests/src/test/scala/cats/tests/ExtraRegressionSuite.scala b/tests/src/test/scala/cats/tests/ExtraRegressionSuite.scala index 5de9ca8762c..b36c40c99af 100644 --- a/tests/src/test/scala/cats/tests/ExtraRegressionSuite.scala +++ b/tests/src/test/scala/cats/tests/ExtraRegressionSuite.scala @@ -1,19 +1,18 @@ package cats package tests - import ExtraRegressionSuite._ class ExtraRegressionSuite extends CatsSuite { + /** - * Placed here to work around scala/bug#6260 on scala 2.10 - */ + * Placed here to work around scala/bug#6260 on scala 2.10 + */ test("#1802 duplicated method name") { Show[First[String]] } } - object ExtraRegressionSuite { final case class First[A](getFirst: A) extends AnyVal object First { diff --git a/tests/src/test/scala/cats/tests/FiniteDurationSuite.scala b/tests/src/test/scala/cats/tests/FiniteDurationSuite.scala index 35cd201a8bc..7d417dc92c0 100644 --- a/tests/src/test/scala/cats/tests/FiniteDurationSuite.scala +++ b/tests/src/test/scala/cats/tests/FiniteDurationSuite.scala @@ -3,13 +3,13 @@ package tests import cats.laws.discipline.SerializableTests -import scala.concurrent.duration.{ DurationInt, FiniteDuration } +import scala.concurrent.duration.{DurationInt, FiniteDuration} class FiniteDurationSuite extends CatsSuite { checkAll("Show[FiniteDuration]", SerializableTests.serializable(Show[FiniteDuration])) - test("show works for FiniteDuration"){ + test("show works for FiniteDuration") { Show[FiniteDuration].show(23.minutes) should ===("23 minutes") - Show[FiniteDuration].show(10.seconds) should === ("10 seconds") + Show[FiniteDuration].show(10.seconds) should ===("10 seconds") } } diff --git a/tests/src/test/scala/cats/tests/FoldableSuite.scala b/tests/src/test/scala/cats/tests/FoldableSuite.scala index 702bdb592cb..2521f303942 100644 --- a/tests/src/test/scala/cats/tests/FoldableSuite.scala +++ b/tests/src/test/scala/cats/tests/FoldableSuite.scala @@ -9,16 +9,17 @@ import cats.instances.all._ import cats.data._ import cats.laws.discipline.arbitrary._ -abstract class FoldableSuite[F[_]: Foldable](name: String)( - implicit ArbFInt: Arbitrary[F[Int]], - ArbFString: Arbitrary[F[String]]) extends CatsSuite with PropertyChecks { +abstract class FoldableSuite[F[_]: Foldable](name: String)(implicit ArbFInt: Arbitrary[F[Int]], + ArbFString: Arbitrary[F[String]]) + extends CatsSuite + with PropertyChecks { def iterator[T](fa: F[T]): Iterator[T] test(s"Foldable[$name].size/get") { forAll { (fa: F[Int], n: Int) => val s = fa.size - s should === (iterator(fa).size.toLong) + s should ===(iterator(fa).size.toLong) if (n < s && n >= 0) { fa.get(n.toLong) === Some(iterator(fa).take(n + 1).toList.last) } else { @@ -31,7 +32,7 @@ abstract class FoldableSuite[F[_]: Foldable](name: String)( forAll { (fi: F[Int], f: Int => Either[String, String]) => val vector = Foldable[F].toList(fi).toVector val (lefts, rights) = Foldable[Vector].partitionEither(vector)(f) - (lefts <+> rights).size.toLong should === (fi.size) + (lefts <+> rights).size.toLong should ===(fi.size) } } @@ -39,27 +40,29 @@ abstract class FoldableSuite[F[_]: Foldable](name: String)( forAll { (fi: F[Int], f: Int => Either[String, String]) => val list = Foldable[F].toList(fi) val (lefts, rights) = Foldable[List].partitionEither(list)(f) - val (ls, rs) = list.map(f).partition({ - case Left(_) => true - case Right(_) => false - }) - - lefts.map(_.asLeft[String]) should === (ls) - rights.map(_.asRight[String]) should === (rs) + val (ls, rs) = list + .map(f) + .partition({ + case Left(_) => true + case Right(_) => false + }) + + lefts.map(_.asLeft[String]) should ===(ls) + rights.map(_.asRight[String]) should ===(rs) } } test("Foldable#partitionEither to one side is identity") { forAll { (fi: F[Int], f: Int => String) => val list = Foldable[F].toList(fi) - val g: Int => Either[Double, String] = f andThen Right.apply - val h: Int => Either[String, Double] = f andThen Left.apply + val g: Int => Either[Double, String] = f.andThen(Right.apply) + val h: Int => Either[String, Double] = f.andThen(Left.apply) val withG = Foldable[List].partitionEither(list)(g)._2 - withG should === (list.map(f)) + withG should ===(list.map(f)) val withH = Foldable[List].partitionEither(list)(h)._1 - withH should === (list.map(f)) + withH should ===(list.map(f)) } } @@ -70,18 +73,18 @@ abstract class FoldableSuite[F[_]: Foldable](name: String)( val sorted = list.map(f).sorted val (lefts, rights) = Foldable[List].partitionEither(sorted)(identity) - lefts.sorted should === (lefts) - rights.sorted should === (rights) + lefts.sorted should ===(lefts) + rights.sorted should ===(rights) } } test(s"Foldable[$name] summation") { forAll { (fa: F[Int]) => val total = iterator(fa).sum - fa.foldLeft(0)(_ + _) should === (total) - fa.foldRight(Now(0))((x, ly) => ly.map(x + _)).value should === (total) - fa.fold should === (total) - fa.foldMap(identity) should === (total) + fa.foldLeft(0)(_ + _) should ===(total) + fa.foldRight(Now(0))((x, ly) => ly.map(x + _)).value should ===(total) + fa.fold should ===(total) + fa.foldMap(identity) should ===(total) } } @@ -92,32 +95,32 @@ abstract class FoldableSuite[F[_]: Foldable](name: String)( val pf: PartialFunction[String, String] = { case n if f(n) ⇒ n } - fa.collectFold(pf) should === (fa.toList.collect(pf).fold(m.empty)(m.combine)) + fa.collectFold(pf) should ===(fa.toList.collect(pf).fold(m.empty)(m.combine)) def g(a: String): Option[String] = Some(a).filter(f) - fa.collectSomeFold(g) should === (fa.toList.filter(f).fold(m.empty)(m.combine)) + fa.collectSomeFold(g) should ===(fa.toList.filter(f).fold(m.empty)(m.combine)) } } test(s"Foldable[$name].find/exists/forall/findM/existsM/forallM/filter_/dropWhile_") { forAll { (fa: F[Int], n: Int) => - fa.find(_ > n) should === (iterator(fa).find(_ > n)) - fa.exists(_ > n) should === (iterator(fa).exists(_ > n)) - fa.forall(_ > n) should === (iterator(fa).forall(_ > n)) - fa.findM(k => Option(k > n)) should === (Option(iterator(fa).find(_ > n))) - fa.existsM(k => Option(k > n)) should === (Option(iterator(fa).exists(_ > n))) - fa.forallM(k => Option(k > n)) should === (Option(iterator(fa).forall(_ > n))) - fa.filter_(_ > n) should === (iterator(fa).filter(_ > n).toList) - fa.dropWhile_(_ > n) should === (iterator(fa).dropWhile(_ > n).toList) - fa.takeWhile_(_ > n) should === (iterator(fa).takeWhile(_ > n).toList) + fa.find(_ > n) should ===(iterator(fa).find(_ > n)) + fa.exists(_ > n) should ===(iterator(fa).exists(_ > n)) + fa.forall(_ > n) should ===(iterator(fa).forall(_ > n)) + fa.findM(k => Option(k > n)) should ===(Option(iterator(fa).find(_ > n))) + fa.existsM(k => Option(k > n)) should ===(Option(iterator(fa).exists(_ > n))) + fa.forallM(k => Option(k > n)) should ===(Option(iterator(fa).forall(_ > n))) + fa.filter_(_ > n) should ===(iterator(fa).filter(_ > n).toList) + fa.dropWhile_(_ > n) should ===(iterator(fa).dropWhile(_ > n).toList) + fa.takeWhile_(_ > n) should ===(iterator(fa).takeWhile(_ > n).toList) } } test(s"Foldable[$name].toList/isEmpty/nonEmpty") { forAll { (fa: F[Int]) => - fa.toList should === (iterator(fa).toList) - fa.isEmpty should === (iterator(fa).isEmpty) - fa.nonEmpty should === (iterator(fa).nonEmpty) + fa.toList should ===(iterator(fa).toList) + fa.isEmpty should ===(iterator(fa).isEmpty) + fa.nonEmpty should ===(iterator(fa).nonEmpty) } } @@ -127,46 +130,50 @@ abstract class FoldableSuite[F[_]: Foldable](name: String)( val minOpt = fa.minimumOption val list = fa.toList val nelOpt = list.toNel - maxOpt should === (nelOpt.map(_.maximum)) - maxOpt should === (nelOpt.map(_.toList.max)) - minOpt should === (nelOpt.map(_.minimum)) - minOpt should === (nelOpt.map(_.toList.min)) - maxOpt.forall(i => fa.forall(_ <= i)) should === (true) - minOpt.forall(i => fa.forall(_ >= i)) should === (true) + maxOpt should ===(nelOpt.map(_.maximum)) + maxOpt should ===(nelOpt.map(_.toList.max)) + minOpt should ===(nelOpt.map(_.minimum)) + minOpt should ===(nelOpt.map(_.toList.min)) + maxOpt.forall(i => fa.forall(_ <= i)) should ===(true) + minOpt.forall(i => fa.forall(_ >= i)) should ===(true) } } test(s"Foldable[$name].reduceLeftOption/reduceRightOption") { forAll { (fa: F[Int]) => val list = fa.toList - fa.reduceLeftOption(_ - _) should === (list.reduceLeftOption(_ - _)) - fa.reduceRightOption((x, ly) => ly.map(x - _)).value should === (list.reduceRightOption(_ - _)) + fa.reduceLeftOption(_ - _) should ===(list.reduceLeftOption(_ - _)) + fa.reduceRightOption((x, ly) => ly.map(x - _)).value should ===(list.reduceRightOption(_ - _)) } } test(s"Foldable[$name].intercalate") { forAll { (fa: F[String], a: String) => - fa.intercalate(a) should === (fa.toList.mkString(a)) + fa.intercalate(a) should ===(fa.toList.mkString(a)) } } test(s"Foldable[$name].toList") { forAll { (fa: F[Int]) => - fa.toList should === (iterator(fa).toList) + fa.toList should ===(iterator(fa).toList) } } test(s"Foldable[$name] mkString_") { forAll { (fa: F[Int]) => - fa.mkString_("L[", ";", "]") should === (fa.toList.mkString("L[", ";", "]")) + fa.mkString_("L[", ";", "]") should ===(fa.toList.mkString("L[", ";", "]")) } } test(s"Foldable[$name].collectFirstSomeM") { forAll { (fa: F[Int], n: Int) => - fa.collectFirstSomeM(x => (x > n).guard[Option].as(x).asRight[String]) should === (fa.toList.collectFirst { - case x if x > n => x - }.asRight[String]) + fa.collectFirstSomeM(x => (x > n).guard[Option].as(x).asRight[String]) should ===( + fa.toList + .collectFirst { + case x if x > n => x + } + .asRight[String] + ) } } } @@ -185,16 +192,20 @@ class FoldableSuiteAdditional extends CatsSuite { // some basic sanity checks val ns = (1 to 10).toList val total = ns.sum - F.foldLeft(ns, 0)(_ + _) should === (total) - F.foldRight(ns, Now(0))((x, ly) => ly.map(x + _)).value should === (total) - F.fold(ns) should === (total) + F.foldLeft(ns, 0)(_ + _) should ===(total) + F.foldRight(ns, Now(0))((x, ly) => ly.map(x + _)).value should ===(total) + F.fold(ns) should ===(total) // more basic checks val names = List("Aaron", "Betty", "Calvin", "Deirdra") - F.foldMap(names)(_.length) should === (names.map(_.length).sum) - val sumM = F.foldM(names, "") { (acc, x) => (Some(acc + x): Option[String]) } + F.foldMap(names)(_.length) should ===(names.map(_.length).sum) + val sumM = F.foldM(names, "") { (acc, x) => + (Some(acc + x): Option[String]) + } assert(sumM == Some("AaronBettyCalvinDeirdra")) - val sumMapM = F.foldMapM(names) { x => (Some(x): Option[String]) } + val sumMapM = F.foldMapM(names) { x => + (Some(x): Option[String]) + } assert(sumMapM == Some("AaronBettyCalvinDeirdra")) val isNotCalvin: String => Option[String] = x => if (x == "Calvin") None else Some(x) @@ -211,7 +222,7 @@ class FoldableSuiteAdditional extends CatsSuite { // safely build large lists val larger = F.foldRight(large, Now(List.empty[Int]))((x, lxs) => lxs.map((x + 1) :: _)) - larger.value should === (large.map(_ + 1)) + larger.value should ===(large.map(_ + 1)) } def checkMonadicFoldsStackSafety[F[_]](fromRange: Range => F[Int])(implicit F: Foldable[F]): Unit = { @@ -227,7 +238,7 @@ class FoldableSuiteAdditional extends CatsSuite { val n = 100000 val src = fromRange(1 to n) - val foldMExpected = n.toLong*(n.toLong+1)/2 + val foldMExpected = n.toLong * (n.toLong + 1) / 2 val foldMResult = F.foldM(src, 0L)(nonzero) assert(foldMResult.get == foldMExpected) @@ -256,10 +267,10 @@ class FoldableSuiteAdditional extends CatsSuite { Eval.always(a + eb.value) } - eval.value should === (fa.sum) + eval.value should ===(fa.sum) //Repeat here so the result is evaluated again - eval.value should === (fa.sum) + eval.value should ===(fa.sum) } } @@ -276,11 +287,13 @@ class FoldableSuiteAdditional extends CatsSuite { } test("Foldable[SortedSet].foldM/existsM/forallM/findM/collectFirstSomeM stack safety") { - checkMonadicFoldsStackSafety[SortedSet](s => SortedSet(s:_*)) + checkMonadicFoldsStackSafety[SortedSet](s => SortedSet(s: _*)) } test("Foldable[SortedMap[String, ?]].foldM/existsM/forallM/findM/collectFirstSomeM stack safety") { - checkMonadicFoldsStackSafety[SortedMap[String, ?]](xs => SortedMap.empty[String, Int] ++ xs.map(x => x.toString -> x).toMap) + checkMonadicFoldsStackSafety[SortedMap[String, ?]]( + xs => SortedMap.empty[String, Int] ++ xs.map(x => x.toString -> x).toMap + ) } test("Foldable[NonEmptyList].foldM/existsM/forallM/findM/collectFirstSomeM stack safety") { @@ -321,7 +334,7 @@ class FoldableSuiteAdditional extends CatsSuite { assert(contains(large, 10000).value) // test laziness of foldM - dangerous.foldM(0)((acc, a) => if (a < 2) Some(acc + a) else None) should === (None) + dangerous.foldM(0)((acc, a) => if (a < 2) Some(acc + a) else None) should ===(None) } @@ -373,7 +386,7 @@ class FoldableSuiteAdditional extends CatsSuite { } test("Foldable[List] doesn't break substitution") { - val result = List.range(0,10).foldM(List.empty[Int])((accum, elt) => Eval.always(elt :: accum)) + val result = List.range(0, 10).foldM(List.empty[Int])((accum, elt) => Eval.always(elt :: accum)) assert(result.value == result.value) } @@ -445,7 +458,8 @@ class FoldableOneAndSuite extends FoldableSuite[OneAnd[List, ?]]("oneAnd") { } class FoldableComposedSuite extends FoldableSuite[Nested[List, Option, ?]]("nested") { - def iterator[T](nested: Nested[List, Option, T]) = nested.value.collect { - case Some(t) => t - }.iterator + def iterator[T](nested: Nested[List, Option, T]) = + nested.value.collect { + case Some(t) => t + }.iterator } diff --git a/tests/src/test/scala/cats/tests/FuncSuite.scala b/tests/src/test/scala/cats/tests/FuncSuite.scala index 6aec186c662..47402b34493 100644 --- a/tests/src/test/scala/cats/tests/FuncSuite.scala +++ b/tests/src/test/scala/cats/tests/FuncSuite.scala @@ -48,20 +48,27 @@ class FuncSuite extends CatsSuite { implicit val appFuncApp = AppFunc.appFuncApplicative[Option, Int] implicit val iso = SemigroupalTests.Isomorphisms.invariant[AppFunc[Option, Int, ?]] checkAll("AppFunc[Option, Int, Int]", ApplicativeTests[AppFunc[Option, Int, ?]].applicative[Int, Int, Int]) - checkAll("Applicative[AppFunc[Option, Int, ?]]", SerializableTests.serializable(Applicative[AppFunc[Option, Int, ?]])) + checkAll("Applicative[AppFunc[Option, Int, ?]]", + SerializableTests.serializable(Applicative[AppFunc[Option, Int, ?]])) } test("product") { - val f = appFunc { (x: Int) => (Some(x + 10): Option[Int]) } - val g = appFunc { (x: Int) => List(x * 2) } - val h = f product g + val f = appFunc { (x: Int) => + (Some(x + 10): Option[Int]) + } + val g = appFunc { (x: Int) => + List(x * 2) + } + val h = f.product(g) val x = h.run(1) - (x.first, x.second) should === ((Some(11), List(2))) + (x.first, x.second) should ===((Some(11), List(2))) } test("traverse") { - val f = Func.appFunc { (x: Int) => (Some(x + 10): Option[Int]) } - val xs = f traverse List(1, 2, 3) - xs should === (Some(List(11, 12, 13))) + val f = Func.appFunc { (x: Int) => + (Some(x + 10): Option[Int]) + } + val xs = f.traverse(List(1, 2, 3)) + xs should ===(Some(List(11, 12, 13))) } } diff --git a/tests/src/test/scala/cats/tests/FunctionKSuite.scala b/tests/src/test/scala/cats/tests/FunctionKSuite.scala index cc73ef4e3be..e6054376908 100644 --- a/tests/src/test/scala/cats/tests/FunctionKSuite.scala +++ b/tests/src/test/scala/cats/tests/FunctionKSuite.scala @@ -13,54 +13,54 @@ class FunctionKSuite extends CatsSuite { val optionToList = λ[FunctionK[Option, List]](_.toList) sealed trait Test1Algebra[A] { - def v : A + def v: A } - case class Test1[A](v : A) extends Test1Algebra[A] + case class Test1[A](v: A) extends Test1Algebra[A] sealed trait Test2Algebra[A] { - def v : A + def v: A } - case class Test2[A](v : A) extends Test2Algebra[A] + case class Test2[A](v: A) extends Test2Algebra[A] - val Test1FK = λ[FunctionK[Test1Algebra,Id]](_.v) - val Test2FK = λ[FunctionK[Test2Algebra,Id]](_.v) + val Test1FK = λ[FunctionK[Test1Algebra, Id]](_.v) + val Test2FK = λ[FunctionK[Test2Algebra, Id]](_.v) test("compose") { forAll { (list: List[Int]) => val listToList = optionToList.compose(listToOption) - listToList(list) should === (list.take(1)) + listToList(list) should ===(list.take(1)) } } test("andThen") { forAll { (list: List[Int]) => val listToList = listToOption.andThen(optionToList) - listToList(list) should === (list.take(1)) + listToList(list) should ===(list.take(1)) } } test("id is identity") { forAll { (list: List[Int]) => - FunctionK.id[List].apply(list) should === (list) + FunctionK.id[List].apply(list) should ===(list) } } test("or") { - val combinedInterpreter = Test1FK or Test2FK - forAll { (a : Int, b : Int) => - combinedInterpreter(EitherK.left(Test1(a))) should === (a) - combinedInterpreter(EitherK.right(Test2(b))) should === (b) + val combinedInterpreter = Test1FK.or(Test2FK) + forAll { (a: Int, b: Int) => + combinedInterpreter(EitherK.left(Test1(a))) should ===(a) + combinedInterpreter(EitherK.right(Test2(b))) should ===(b) } } test("and") { - val combinedInterpreter = listToOption and listToVector - forAll { (list : List[Int]) => + val combinedInterpreter = listToOption.and(listToVector) + forAll { (list: List[Int]) => val prod = combinedInterpreter(list) - prod.first should === (list.headOption) - prod.second should === (list.toVector) + prod.first should ===(list.headOption) + prod.second should ===(list.toVector) } } @@ -68,17 +68,17 @@ class FunctionKSuite extends CatsSuite { def optionToList[A](option: Option[A]): List[A] = option.toList val fOptionToList = FunctionK.lift(optionToList _) forAll { (a: Option[Int]) => - fOptionToList(a) should === (optionToList(a)) + fOptionToList(a) should ===(optionToList(a)) } val fO2I: FunctionK[Option, Iterable] = FunctionK.lift(Option.option2Iterable _) forAll { (a: Option[String]) => - fO2I(a).toList should === (Option.option2Iterable(a).toList) + fO2I(a).toList should ===(Option.option2Iterable(a).toList) } val fNelFromListUnsafe = FunctionK.lift(NonEmptyList.fromListUnsafe _) forAll { (a: NonEmptyList[Int]) => - fNelFromListUnsafe(a.toList) should === (NonEmptyList.fromListUnsafe(a.toList)) + fNelFromListUnsafe(a.toList) should ===(NonEmptyList.fromListUnsafe(a.toList)) } } @@ -87,14 +87,14 @@ class FunctionKSuite extends CatsSuite { def optionToList[A](option: Option[A]): List[A] = option.toList val fOptionToList = cats.arrow.FunctionK.lift(optionToList _) forAll { (a: Option[Int]) => - fOptionToList(a) should === (optionToList(a)) + fOptionToList(a) should ===(optionToList(a)) } } test("lift compound unary") { val fNelFromList = FunctionK.lift[List, λ[α ⇒ Option[NonEmptyList[α]]]](NonEmptyList.fromList _) forAll { (a: List[String]) => - fNelFromList(a) should === (NonEmptyList.fromList(a)) + fNelFromList(a) should ===(NonEmptyList.fromList(a)) } } diff --git a/tests/src/test/scala/cats/tests/FunctionSuite.scala b/tests/src/test/scala/cats/tests/FunctionSuite.scala index df7d9055b8c..1b56ca44a80 100644 --- a/tests/src/test/scala/cats/tests/FunctionSuite.scala +++ b/tests/src/test/scala/cats/tests/FunctionSuite.scala @@ -24,7 +24,6 @@ import cats.laws.discipline.arbitrary._ import cats.kernel.{CommutativeGroup, CommutativeMonoid, CommutativeSemigroup} import cats.kernel.{Band, BoundedSemilattice, Semilattice} - class FunctionSuite extends CatsSuite { import Helpers._ @@ -70,8 +69,6 @@ class FunctionSuite extends CatsSuite { checkAll("Function1[Int, Int]", DistributiveTests[Int => ?].distributive[Int, Int, Int, Id, Function1[Int, ?]]) checkAll("Distributive[Int => ?]", SerializableTests.serializable(Distributive[Int => ?])) - - // law checks for the various Function0-related instances checkAll("Function0[Eqed]", EqTests[Function0[Eqed]].eqv) checkAll("Function0[POrd]", PartialOrderTests[Function0[POrd]].partialOrder) @@ -87,7 +84,6 @@ class FunctionSuite extends CatsSuite { checkAll("Function0[CGrp]", CommutativeGroupTests[Function0[CGrp]].commutativeGroup) checkAll("Function0[Distributive]", DistributiveTests[Function0].distributive[Int, Int, Int, Id, Function0]) - test("Function0[Hsh]") { forAll { (x: Function0[Hsh], y: Function0[Hsh]) => HashLaws[Function0[Hsh]].hashCompatibility(x, y) @@ -97,7 +93,8 @@ class FunctionSuite extends CatsSuite { // Test for Arrow applicative Applicative[String => ?] checkAll("Function1[String, ?]", - ApplicativeTests[Function1[String, ?]](Applicative.catsApplicativeForArrow[Function1, String]).applicative[Int, Int, Int]) + ApplicativeTests[Function1[String, ?]](Applicative.catsApplicativeForArrow[Function1, String]) + .applicative[Int, Int, Int]) // serialization tests for the various Function0-related instances checkAll("Eq[() => Eqed]", SerializableTests.serializable(Eq[() => Eqed])) @@ -130,7 +127,8 @@ class FunctionSuite extends CatsSuite { // serialization tests for the various Function1-related instances checkAll("Semigroup[String => Semi]", SerializableTests.serializable(Semigroup[String => Semi])) - checkAll("CommutativeSemigroup[String => Semi]", SerializableTests.serializable(CommutativeSemigroup[String => CSemi])) + checkAll("CommutativeSemigroup[String => Semi]", + SerializableTests.serializable(CommutativeSemigroup[String => CSemi])) checkAll("Band[String => Bnd]", SerializableTests.serializable(Band[String => Bnd])) checkAll("Semilattice[String => SL]", SerializableTests.serializable(Semilattice[String => SL])) checkAll("BoundedSemilattice[String => BSL]", SerializableTests.serializable(BoundedSemilattice[String => BSL])) @@ -138,5 +136,6 @@ class FunctionSuite extends CatsSuite { checkAll("CommutativeMonoid[String => CMono]", SerializableTests.serializable(CommutativeMonoid[String => CMono])) checkAll("Group[String => Grp]", SerializableTests.serializable(Group[String => Grp])) checkAll("CommutativeGroup[String => CGrp]", SerializableTests.serializable(CommutativeGroup[String => CGrp])) - checkAll("ContravariantMonoidal[Function1[?, Monoid]]", SerializableTests.serializable(ContravariantMonoidal[? => Long])) + checkAll("ContravariantMonoidal[Function1[?, Monoid]]", + SerializableTests.serializable(ContravariantMonoidal[? => Long])) } diff --git a/tests/src/test/scala/cats/tests/FunctorSuite.scala b/tests/src/test/scala/cats/tests/FunctorSuite.scala index 3b7c74ace0b..8e448d6457f 100644 --- a/tests/src/test/scala/cats/tests/FunctorSuite.scala +++ b/tests/src/test/scala/cats/tests/FunctorSuite.scala @@ -4,28 +4,28 @@ package tests class FunctorSuite extends CatsSuite { test("void replaces values with unit preserving structure") { forAll { (l: List[Int], o: Option[Int], m: Map[String, Int]) => - l.void should === (List.fill(l.length)(())) - o.void should === (if (o.nonEmpty) Some(()) else None) - m.void should === (m.keys.map(k => (k, ())).toMap) + l.void should ===(List.fill(l.length)(())) + o.void should ===(if (o.nonEmpty) Some(()) else None) + m.void should ===(m.keys.map(k => (k, ())).toMap) } } test("as replaces values with a constant value preserving structure") { forAll { (l: List[Int], o: Option[Int], m: Map[String, Int], i: Int) => - l.as(i) should === (List.fill(l.length)(i)) - o.as(i) should === (if (o.nonEmpty) Some(i) else None) - m.as(i) should === (m.keys.map(k => (k, i)).toMap) + l.as(i) should ===(List.fill(l.length)(i)) + o.as(i) should ===(if (o.nonEmpty) Some(i) else None) + m.as(i) should ===(m.keys.map(k => (k, i)).toMap) } } test("tupleLeft and tupleRight tuple values with a constant value preserving structure") { forAll { (l: List[Int], o: Option[Int], m: Map[String, Int], i: Int) => - l.tupleLeft(i) should === (List.tabulate(l.length)(in => (i, l(in)))) - o.tupleLeft(i) should === (if (o.nonEmpty) Some((i, o.get)) else None) - m.tupleLeft(i) should === (m.map { case (k, v) => (k, (i, v)) }.toMap) - l.tupleRight(i) should === (List.tabulate(l.length)(in => (l(in), i))) - o.tupleRight(i) should === (if (o.nonEmpty) Some((o.get, i)) else None) - m.tupleRight(i) should === (m.map { case (k, v) => (k, (v, i)) }.toMap) + l.tupleLeft(i) should ===(List.tabulate(l.length)(in => (i, l(in)))) + o.tupleLeft(i) should ===(if (o.nonEmpty) Some((i, o.get)) else None) + m.tupleLeft(i) should ===(m.map { case (k, v) => (k, (i, v)) }.toMap) + l.tupleRight(i) should ===(List.tabulate(l.length)(in => (l(in), i))) + o.tupleRight(i) should ===(if (o.nonEmpty) Some((o.get, i)) else None) + m.tupleRight(i) should ===(m.map { case (k, v) => (k, (v, i)) }.toMap) } } @@ -33,7 +33,7 @@ class FunctorSuite extends CatsSuite { forAll { (i: Int) => val list: List[Some[Int]] = List(Some(i)) val widened: List[Option[Int]] = list.widen[Option[Int]] - widened should === (list.map(identity[Option[Int]])) + widened should ===(list.map(identity[Option[Int]])) assert(widened eq list) } } diff --git a/tests/src/test/scala/cats/tests/HashSuite.scala b/tests/src/test/scala/cats/tests/HashSuite.scala index 908b9a9bcd7..b0f368867d0 100644 --- a/tests/src/test/scala/cats/tests/HashSuite.scala +++ b/tests/src/test/scala/cats/tests/HashSuite.scala @@ -1,7 +1,6 @@ package cats package tests - class HashSuite extends CatsSuite { { @@ -12,5 +11,4 @@ class HashSuite extends CatsSuite { assert(1.hash == 1.hashCode) assert("ABC".hash == "ABC".hashCode) - } diff --git a/tests/src/test/scala/cats/tests/IdTSuite.scala b/tests/src/test/scala/cats/tests/IdTSuite.scala index 878590d3633..6cb1ab9f8e4 100644 --- a/tests/src/test/scala/cats/tests/IdTSuite.scala +++ b/tests/src/test/scala/cats/tests/IdTSuite.scala @@ -2,17 +2,19 @@ package cats package tests import cats.data.{Const, IdT, NonEmptyList} -import cats.kernel.laws.discipline.{OrderTests, EqTests} +import cats.kernel.laws.discipline.{EqTests, OrderTests} import cats.laws.discipline._ import cats.laws.discipline.arbitrary._ import Helpers.CSemi class IdTSuite extends CatsSuite { - implicit val iso = SemigroupalTests.Isomorphisms.invariant[IdT[ListWrapper, ?]](IdT.catsDataFunctorForIdT(ListWrapper.functor)) + implicit val iso = + SemigroupalTests.Isomorphisms.invariant[IdT[ListWrapper, ?]](IdT.catsDataFunctorForIdT(ListWrapper.functor)) checkAll("IdT[(CSemi, ?), Int]", CommutativeFlatMapTests[IdT[(CSemi, ?), ?]].commutativeFlatMap[Int, Int, Int]) - checkAll("CommutativeFlatMap[IdT[(CSemi, ?), ?]]", SerializableTests.serializable(CommutativeFlatMap[IdT[(CSemi, ?), ?]])) + checkAll("CommutativeFlatMap[IdT[(CSemi, ?), ?]]", + SerializableTests.serializable(CommutativeFlatMap[IdT[(CSemi, ?), ?]])) checkAll("IdT[Option, Int]", CommutativeMonadTests[IdT[Option, ?]].commutativeMonad[Int, Int, Int]) checkAll("CommutativeMonad[IdT[Option, ?]]", SerializableTests.serializable(CommutativeMonad[IdT[Option, ?]])) @@ -54,9 +56,9 @@ class IdTSuite extends CatsSuite { { checkAll("IdT[Const[String, ?], ?]", - ContravariantMonoidalTests[IdT[Const[String, ?], ?]].contravariantMonoidal[Int, Int, Int]) + ContravariantMonoidalTests[IdT[Const[String, ?], ?]].contravariantMonoidal[Int, Int, Int]) checkAll("ContravariantMonoidal[IdT[Const[String, ?], ?]]", - SerializableTests.serializable(ContravariantMonoidal[IdT[Const[String, ?], ?]])) + SerializableTests.serializable(ContravariantMonoidal[IdT[Const[String, ?], ?]])) } { @@ -83,28 +85,30 @@ class IdTSuite extends CatsSuite { { implicit val F = ListWrapper.traverse - checkAll("IdT[ListWrapper, Int] with Option", TraverseTests[IdT[ListWrapper, ?]].traverse[Int, Int, Int, Int, Option, Option]) + checkAll("IdT[ListWrapper, Int] with Option", + TraverseTests[IdT[ListWrapper, ?]].traverse[Int, Int, Int, Int, Option, Option]) checkAll("Traverse[IdT[ListWrapper, ?]]", SerializableTests.serializable(Traverse[IdT[ListWrapper, ?]])) } { implicit val F = NonEmptyList.catsDataInstancesForNonEmptyList - checkAll("IdT[NonEmptyList, Int]", NonEmptyTraverseTests[IdT[NonEmptyList, ?]].nonEmptyTraverse[Option, Int, Int, Int, Int, Option, Option]) - checkAll("NonEmptyTraverse[IdT[NonEmptyList, ?]]", SerializableTests.serializable(NonEmptyTraverse[IdT[NonEmptyList, ?]])) + checkAll("IdT[NonEmptyList, Int]", + NonEmptyTraverseTests[IdT[NonEmptyList, ?]].nonEmptyTraverse[Option, Int, Int, Int, Int, Option, Option]) + checkAll("NonEmptyTraverse[IdT[NonEmptyList, ?]]", + SerializableTests.serializable(NonEmptyTraverse[IdT[NonEmptyList, ?]])) } - test("flatMap and flatMapF consistent") { - forAll { (idT: IdT[Option, Int], f: Int => IdT[Option, Int]) => - idT.flatMap(f) should === (idT.flatMapF(f(_).value)) + forAll { (idT: IdT[Option, Int], f: Int => IdT[Option, Int]) => + idT.flatMap(f) should ===(idT.flatMapF(f(_).value)) } } test("mapK consistent with f(value)+pure") { val f: List ~> Option = λ[List ~> Option](_.headOption) forAll { (idT: IdT[List, Int]) => - idT.mapK(f) should === (IdT(f(idT.value))) + idT.mapK(f) should ===(IdT(f(idT.value))) } } diff --git a/tests/src/test/scala/cats/tests/IndexedReaderWriterStateTSuite.scala b/tests/src/test/scala/cats/tests/IndexedReaderWriterStateTSuite.scala index ac6cb30a8cb..d03fa4f2787 100644 --- a/tests/src/test/scala/cats/tests/IndexedReaderWriterStateTSuite.scala +++ b/tests/src/test/scala/cats/tests/IndexedReaderWriterStateTSuite.scala @@ -1,13 +1,13 @@ package cats package tests -import cats.data.{ IRWST, IndexedReaderWriterStateT, ReaderWriterStateT, ReaderWriterState, EitherT } +import cats.data.{EitherT, IRWST, IndexedReaderWriterStateT, ReaderWriterState, ReaderWriterStateT} import cats.laws.discipline._ import cats.laws.discipline.eq._ import cats.laws.discipline.arbitrary._ import org.scalacheck.Arbitrary -import cats.arrow.{Strong, Profunctor} +import cats.arrow.{Profunctor, Strong} class ReaderWriterStateTSuite extends CatsSuite { import ReaderWriterStateTSuite._ @@ -16,9 +16,9 @@ class ReaderWriterStateTSuite extends CatsSuite { forAll { (context: String, initial: Int) => val (log, state, result) = addAndLog(5).run(context, initial).value - log should === (Vector(s"${context}: Added 5")) - state should === (initial + 5) - result should === (initial + 5) + log should ===(Vector(s"${context}: Added 5")) + state should ===(initial + 5) + result should ===(initial + 5) } } @@ -26,24 +26,28 @@ class ReaderWriterStateTSuite extends CatsSuite { val ns = (0 to 70000).toList val rws = ns.traverse(_ => addLogUnit(1)) - rws.runS("context", 0).value should === (70001) + rws.runS("context", 0).value should ===(70001) } test("map2 combines logs") { - forAll { (rwsa: ReaderWriterState[String, Vector[Int], Int, Int], rwsb: ReaderWriterState[String, Vector[Int], Int, Int], c: String, s: Int) => - val logMap2 = rwsa.map2(rwsb)((_, _) => ()).runL(c, s).value + forAll { + (rwsa: ReaderWriterState[String, Vector[Int], Int, Int], + rwsb: ReaderWriterState[String, Vector[Int], Int, Int], + c: String, + s: Int) => + val logMap2 = rwsa.map2(rwsb)((_, _) => ()).runL(c, s).value - val (logA, stateA, _) = rwsa.run(c, s).value - val logB = rwsb.runL(c, stateA).value - val combinedLog = logA |+| logB + val (logA, stateA, _) = rwsa.run(c, s).value + val logB = rwsb.runL(c, stateA).value + val combinedLog = logA |+| logB - logMap2 should === (combinedLog) + logMap2 should ===(combinedLog) } } test("ReaderWriterState.ask provides the context") { forAll { (context: String, initial: Int) => - ReaderWriterState.ask[String, String, Int].runA(context, initial).value should === (context) + ReaderWriterState.ask[String, String, Int].runA(context, initial).value should ===(context) } } @@ -53,15 +57,15 @@ class ReaderWriterStateTSuite extends CatsSuite { val rwst: ReaderWriterState[String, Vector[String], Int, Int] = ReaderWriterStateT.pure(value) val irwst: ReaderWriterState[String, Vector[String], Int, Int] = IndexedReaderWriterStateT.pure(value) - rws should === (rwst) - rwst should === (irwst) + rws should ===(rwst) + rwst should ===(irwst) } } test("ReaderWriterState.pure creates an ReaderWriterState with an empty log") { forAll { (context: String, initial: Int) => val rws: ReaderWriterState[String, String, Int, Unit] = ReaderWriterState.pure(()) - rws.run(context, initial).value should === ((Monoid[String].empty, initial, ())) + rws.run(context, initial).value should ===((Monoid[String].empty, initial, ())) } } @@ -71,8 +75,8 @@ class ReaderWriterStateTSuite extends CatsSuite { val rwst: ReaderWriterState[String, Vector[String], Int, Int] = ReaderWriterStateT.get val irwst: ReaderWriterState[String, Vector[String], Int, Int] = IndexedReaderWriterStateT.get - rws should === (rwst) - rwst should === (irwst) + rws should ===(rwst) + rwst should ===(irwst) } } @@ -81,7 +85,7 @@ class ReaderWriterStateTSuite extends CatsSuite { val singleton = ReaderWriterState.get[String, String, Int] val instance = ReaderWriterState.pure[String, String, Int, Unit](()).get - singleton should === (instance) + singleton should ===(instance) } } @@ -90,7 +94,7 @@ class ReaderWriterStateTSuite extends CatsSuite { val singleton = ReaderWriterState.inspect[String, String, Int, String](_.toString) val instance = ReaderWriterState.pure[String, String, Int, Unit](()).inspect(_.toString) - singleton should === (instance) + singleton should ===(instance) } } @@ -100,8 +104,8 @@ class ReaderWriterStateTSuite extends CatsSuite { val rwst: ReaderWriterState[String, Vector[String], Int, Int] = ReaderWriterStateT.inspect(f) val irwst: ReaderWriterState[String, Vector[String], Int, Int] = IndexedReaderWriterStateT.inspect(f) - rws should === (rwst) - rwst should === (irwst) + rws should ===(rwst) + rwst should ===(irwst) } } @@ -111,8 +115,8 @@ class ReaderWriterStateTSuite extends CatsSuite { val rwst: ReaderWriterState[String, String, Int, Int] = ReaderWriterStateT.inspectF(f.andThen(Eval.now)) val irwst: ReaderWriterState[String, String, Int, Int] = IndexedReaderWriterStateT.inspectF(f.andThen(Eval.now)) - rws should === (rwst) - rwst should === (irwst) + rws should ===(rwst) + rwst should ===(irwst) } } @@ -122,8 +126,8 @@ class ReaderWriterStateTSuite extends CatsSuite { val rwst: ReaderWriterState[String, Vector[String], Int, Unit] = ReaderWriterStateT.modify(f) val irwst: ReaderWriterState[String, Vector[String], Int, Unit] = IndexedReaderWriterStateT.modify(f) - rws should === (rwst) - rwst should === (irwst) + rws should ===(rwst) + rwst should ===(irwst) } } @@ -131,10 +135,11 @@ class ReaderWriterStateTSuite extends CatsSuite { forAll { (f: Int => Int) => val rws: ReaderWriterState[String, Vector[String], Int, Unit] = ReaderWriterState.modify(f) val rwst: ReaderWriterState[String, Vector[String], Int, Unit] = ReaderWriterStateT.modifyF(f.andThen(Eval.now)) - val irwst: ReaderWriterState[String, Vector[String], Int, Unit] = IndexedReaderWriterStateT.modifyF(f.andThen(Eval.now)) + val irwst: ReaderWriterState[String, Vector[String], Int, Unit] = + IndexedReaderWriterStateT.modifyF(f.andThen(Eval.now)) - rws should === (rwst) - rwst should === (irwst) + rws should ===(rwst) + rwst should ===(irwst) } } @@ -144,8 +149,8 @@ class ReaderWriterStateTSuite extends CatsSuite { val rwst: ReaderWriterState[String, Vector[String], Int, Int] = ReaderWriterStateT.liftF(Eval.now(value)) val irwst: ReaderWriterState[String, Vector[String], Int, Int] = IndexedReaderWriterStateT.liftF(Eval.now(value)) - rws should === (rwst) - rwst should === (irwst) + rws should ===(rwst) + rwst should ===(irwst) } } @@ -155,8 +160,8 @@ class ReaderWriterStateTSuite extends CatsSuite { val rwst: ReaderWriterState[String, Vector[String], Int, Unit] = ReaderWriterStateT.set(next) val irwst: ReaderWriterState[String, Vector[String], Int, Unit] = IndexedReaderWriterStateT.set(next) - rws should === (rwst) - rwst should === (irwst) + rws should ===(rwst) + rwst should ===(irwst) } } @@ -166,8 +171,8 @@ class ReaderWriterStateTSuite extends CatsSuite { val rwst: ReaderWriterState[String, Vector[String], Int, Unit] = ReaderWriterStateT.setF(Eval.now(next)) val irwst: ReaderWriterState[String, Vector[String], Int, Unit] = IndexedReaderWriterStateT.setF(Eval.now(next)) - rws should === (rwst) - rwst should === (irwst) + rws should ===(rwst) + rwst should ===(irwst) } } @@ -177,8 +182,8 @@ class ReaderWriterStateTSuite extends CatsSuite { val rwst: ReaderWriterState[String, String, Int, Unit] = ReaderWriterStateT.tell(log) val irwst: ReaderWriterState[String, String, Int, Unit] = IndexedReaderWriterStateT.tell(log) - rws should === (rwst) - rwst should === (irwst) + rws should ===(rwst) + rwst should ===(irwst) } } @@ -188,14 +193,14 @@ class ReaderWriterStateTSuite extends CatsSuite { val rwst: ReaderWriterState[String, String, Int, Unit] = ReaderWriterStateT.tellF(Eval.now(log)) val irwst: ReaderWriterState[String, String, Int, Unit] = IndexedReaderWriterStateT.tellF(Eval.now(log)) - rws should === (rwst) - rwst should === (irwst) + rws should ===(rwst) + rwst should ===(irwst) } } test("ReaderWriterState.tell + written is identity") { forAll { (context: String, initial: Int, log: String) => - ReaderWriterState.tell[String, String, Int](log).written.runA(context, initial).value should === (log) + ReaderWriterState.tell[String, String, Int](log).written.runA(context, initial).value should ===(log) } } @@ -203,16 +208,13 @@ class ReaderWriterStateTSuite extends CatsSuite { val rws = addAndLog(5) *> addAndLog(10) val (log, state, result) = rws.run("context", 0).value - log should === (Vector("context: Added 5", "context: Added 10")) - state should === (15) - result should === (15) + log should ===(Vector("context: Added 5", "context: Added 10")) + state should ===(15) + result should ===(15) } test("flatMap and flatMapF+tell are consistent") { - forAll { - (rwst: ReaderWriterStateT[Option, String, String, String, Int], f: Int => Option[Int], - initial: String, context: String, log: String) => - + forAll { (rwst: ReaderWriterStateT[Option, String, String, String, Int], f: Int => Option[Int], initial: String, context: String, log: String) => val flatMap = rwst.flatMap { a => ReaderWriterStateT { (e, s) => f(a).map((log, s, _)) @@ -221,40 +223,40 @@ class ReaderWriterStateTSuite extends CatsSuite { val flatMapF = rwst.flatMapF(f).tell(log) - flatMap.run(context, initial) should === (flatMapF.run(context, initial)) + flatMap.run(context, initial) should ===(flatMapF.run(context, initial)) } } test("runEmpty, runEmptyS, runEmptyA and runEmptyL are consistent") { forAll { (f: ReaderWriterStateT[Option, String, String, String, Int], c: String) => - (f.runEmptyL(c), f.runEmptyS(c), f.runEmptyA(c)).tupled should === (f.runEmpty(c)) + (f.runEmptyL(c), f.runEmptyS(c), f.runEmptyA(c)).tupled should ===(f.runEmpty(c)) } } test("reset on pure is a noop") { forAll { (c: String, s: Int, a: Int) => val pure = ReaderWriterState.pure[String, String, Int, Int](a) - pure.reset should === (pure) + pure.reset should ===(pure) } } test("modify identity is a noop") { forAll { (f: ReaderWriterStateT[Option, String, String, String, Int], c: String, initial: String) => - f.modify(identity).run(c, initial) should === (f.run(c, initial)) + f.modify(identity).run(c, initial) should ===(f.run(c, initial)) } } test("modify modifies only the state") { forAll { (rws: ReaderWriterStateT[Option, String, String, Long, Long], c: String, f: Long => Long, initial: Long) => - rws.modify(f).runS(c, initial) should === (rws.runS(c, initial).map(f)) - rws.modify(f).runA(c, initial) should === (rws.runA(c, initial)) + rws.modify(f).runS(c, initial) should ===(rws.runS(c, initial).map(f)) + rws.modify(f).runA(c, initial) should ===(rws.runA(c, initial)) } } test("reset modifies only the log") { forAll { (rws: ReaderWriterState[String, String, Int, Int], c: String, s: Int) => - rws.reset.runA(c, s) should === (rws.runA(c, s)) - rws.reset.runS(c, s) should === (rws.runS(c, s)) + rws.reset.runA(c, s) should ===(rws.runA(c, s)) + rws.reset.runS(c, s) should ===(rws.runS(c, s)) } } @@ -266,7 +268,7 @@ class ReaderWriterStateTSuite extends CatsSuite { _ <- ReaderWriterStateT.set[Option, String, String, Long](f(l)) } yield () - s1.run(c, initial) should === (s2.run(c, initial)) + s1.run(c, initial) should ===(s2.run(c, initial)) } } @@ -275,7 +277,7 @@ class ReaderWriterStateTSuite extends CatsSuite { val s1 = ReaderWriterStateT.set[Option, String, String, Long](s) val s2 = ReaderWriterStateT.modify[Option, String, String, Long](_ => s) - s1.run(c, initial) should === (s2.run(c, initial)) + s1.run(c, initial) should ===(s2.run(c, initial)) } } @@ -284,14 +286,14 @@ class ReaderWriterStateTSuite extends CatsSuite { val s1 = ReaderWriterStateT.setF[Option, String, String, Long](s) val s2 = ReaderWriterStateT.modifyF[Option, String, String, Long](_ => s) - s1.run(c, initial) should === (s2.run(c, initial)) + s1.run(c, initial) should ===(s2.run(c, initial)) } } test("ReaderWriterStateT.mapK transforms effect") { val f: Eval ~> Id = λ[Eval ~> Id](_.value) forAll { (state: ReaderWriterStateT[Eval, Long, String, String, Int], env: Long, initial: String) => - state.mapK(f).runA(env, initial) should === (state.runA(env, initial).value) + state.mapK(f).runA(env, initial) should ===(state.runA(env, initial).value) } } @@ -299,67 +301,101 @@ class ReaderWriterStateTSuite extends CatsSuite { forAll { (c: String, initial: Long, rws: ReaderWriterState[String, String, Long, Long]) => val (_, state, value) = rws.get.run(c, initial).value - state should === (value) + state should ===(value) } } test(".get and .flatMap with .get are equivalent") { forAll { (c: String, initial: Long, rws: ReaderWriterState[String, String, Long, Long]) => - rws.get.run(c, initial) should === (rws.flatMap(_ => ReaderWriterState.get).run(c, initial)) + rws.get.run(c, initial) should ===(rws.flatMap(_ => ReaderWriterState.get).run(c, initial)) } } implicit val iso = SemigroupalTests.Isomorphisms - .invariant[IndexedReaderWriterStateT[ListWrapper, String, String, Int, String, ?]](IndexedReaderWriterStateT.catsDataFunctorForIRWST(ListWrapper.functor)) + .invariant[IndexedReaderWriterStateT[ListWrapper, String, String, Int, String, ?]]( + IndexedReaderWriterStateT.catsDataFunctorForIRWST(ListWrapper.functor) + ) checkAll("IndexedReaderWriterStateT[Eval, String, String, Int, String, ?]", - DeferTests[IndexedReaderWriterStateT[Eval, String, String, Int, String, ?]].defer[Int]) + DeferTests[IndexedReaderWriterStateT[Eval, String, String, Int, String, ?]].defer[Int]) { implicit val F: Monad[ListWrapper] = ListWrapper.monad - checkAll("IndexedReaderWriterStateT[ListWrapper, String, String, Int, String, Int]", - FunctorTests[IndexedReaderWriterStateT[ListWrapper, String, String, Int, String, ?]].functor[Int, Int, Int]) - checkAll("Functor[IndexedReaderWriterStateT[ListWrapper, String, String, Int, String, ?]]", - SerializableTests.serializable(Functor[IndexedReaderWriterStateT[ListWrapper, String, String, Int, String, ?]])) - - checkAll("IndexedReaderWriterStateT[ListWrapper, String, String, String, Int, Int]", - ContravariantTests[IndexedReaderWriterStateT[ListWrapper, String, String, ?, Int, Int]].contravariant[String, String, String]) - checkAll("Contravariant[IndexedReaderWriterStateT[ListWrapper, String, String, ?, Int, Int]]", - SerializableTests.serializable(Contravariant[IndexedReaderWriterStateT[ListWrapper, String, String, ?, Int, Int]])) - - checkAll("IndexedReaderWriterStateT[ListWrapper, String, String, Int, String, Int]", - ProfunctorTests[IndexedReaderWriterStateT[ListWrapper, String, String, ?, ?, Int]].profunctor[Int, Int, Int, String, String, String]) - checkAll("Profunctor[IndexedReaderWriterStateT[ListWrapper, String, String, ?, ?, Int]]", - SerializableTests.serializable(Profunctor[IndexedReaderWriterStateT[ListWrapper, String, String, ?, ?, Int]])) - - checkAll("IndexedReaderWriterStateT[ListWrapper, String, String, Int, String, Int]", - StrongTests[IndexedReaderWriterStateT[ListWrapper, String, String, ?, ?, Int]].strong[Int, Int, Int, String, String, String]) - checkAll("Strong[IndexedReaderWriterStateT[ListWrapper, String, String, ?, ?, Int]]", - SerializableTests.serializable(Strong[IndexedReaderWriterStateT[ListWrapper, String, String, ?, ?, Int]])) - - checkAll("IndexedReaderWriterStateT[ListWrapper, String, String, Int, Int, String]", - BifunctorTests[IndexedReaderWriterStateT[ListWrapper, String, String, Int, ?, ?]].bifunctor[Int, Int, Int, String, String, String]) - checkAll("Bifunctor[IndexedReaderWriterStateT[ListWrapper, String, String, Int, ?, ?]]", - SerializableTests.serializable(Bifunctor[IndexedReaderWriterStateT[ListWrapper, String, String, Int, ?, ?]])) + checkAll( + "IndexedReaderWriterStateT[ListWrapper, String, String, Int, String, Int]", + FunctorTests[IndexedReaderWriterStateT[ListWrapper, String, String, Int, String, ?]].functor[Int, Int, Int] + ) + checkAll( + "Functor[IndexedReaderWriterStateT[ListWrapper, String, String, Int, String, ?]]", + SerializableTests.serializable(Functor[IndexedReaderWriterStateT[ListWrapper, String, String, Int, String, ?]]) + ) + + checkAll( + "IndexedReaderWriterStateT[ListWrapper, String, String, String, Int, Int]", + ContravariantTests[IndexedReaderWriterStateT[ListWrapper, String, String, ?, Int, Int]] + .contravariant[String, String, String] + ) + checkAll( + "Contravariant[IndexedReaderWriterStateT[ListWrapper, String, String, ?, Int, Int]]", + SerializableTests.serializable(Contravariant[IndexedReaderWriterStateT[ListWrapper, String, String, ?, Int, Int]]) + ) + + checkAll( + "IndexedReaderWriterStateT[ListWrapper, String, String, Int, String, Int]", + ProfunctorTests[IndexedReaderWriterStateT[ListWrapper, String, String, ?, ?, Int]] + .profunctor[Int, Int, Int, String, String, String] + ) + checkAll( + "Profunctor[IndexedReaderWriterStateT[ListWrapper, String, String, ?, ?, Int]]", + SerializableTests.serializable(Profunctor[IndexedReaderWriterStateT[ListWrapper, String, String, ?, ?, Int]]) + ) + + checkAll( + "IndexedReaderWriterStateT[ListWrapper, String, String, Int, String, Int]", + StrongTests[IndexedReaderWriterStateT[ListWrapper, String, String, ?, ?, Int]] + .strong[Int, Int, Int, String, String, String] + ) + checkAll( + "Strong[IndexedReaderWriterStateT[ListWrapper, String, String, ?, ?, Int]]", + SerializableTests.serializable(Strong[IndexedReaderWriterStateT[ListWrapper, String, String, ?, ?, Int]]) + ) + + checkAll( + "IndexedReaderWriterStateT[ListWrapper, String, String, Int, Int, String]", + BifunctorTests[IndexedReaderWriterStateT[ListWrapper, String, String, Int, ?, ?]] + .bifunctor[Int, Int, Int, String, String, String] + ) + checkAll( + "Bifunctor[IndexedReaderWriterStateT[ListWrapper, String, String, Int, ?, ?]]", + SerializableTests.serializable(Bifunctor[IndexedReaderWriterStateT[ListWrapper, String, String, Int, ?, ?]]) + ) } { implicit val G: Monad[ListWrapper] = ListWrapper.monad - val SA = IRWST.catsDataAlternativeForIRWST[ListWrapper, String, String, Int](ListWrapper.monad, ListWrapper.alternative, Monoid[String]) + val SA = IRWST.catsDataAlternativeForIRWST[ListWrapper, String, String, Int](ListWrapper.monad, + ListWrapper.alternative, + Monoid[String]) - checkAll("IndexedReaderWriterStateT[ListWrapper, String, String, Int, Int, Int]", AlternativeTests[IRWST[ListWrapper, String, String, Int, Int, ?]](SA).alternative[Int, Int, Int]) - checkAll("Alternative[IndexedReaderWriterStateT[ListWrapper, String, String, Int, Int, ?]]", SerializableTests.serializable(SA)) + checkAll( + "IndexedReaderWriterStateT[ListWrapper, String, String, Int, Int, Int]", + AlternativeTests[IRWST[ListWrapper, String, String, Int, Int, ?]](SA).alternative[Int, Int, Int] + ) + checkAll("Alternative[IndexedReaderWriterStateT[ListWrapper, String, String, Int, Int, ?]]", + SerializableTests.serializable(SA)) } { implicit val LWM: Monad[ListWrapper] = ListWrapper.monad checkAll("ReaderWriterStateT[ListWrapper, String, String, Int, Int]", - MonadTests[ReaderWriterStateT[ListWrapper, String, String, Int, ?]].monad[Int, Int, Int]) - checkAll("Monad[ReaderWriterStateT[ListWrapper, String, String, Int, ?]]", - SerializableTests.serializable(Monad[ReaderWriterStateT[ListWrapper, String, String, Int, ?]])) + MonadTests[ReaderWriterStateT[ListWrapper, String, String, Int, ?]].monad[Int, Int, Int]) + checkAll( + "Monad[ReaderWriterStateT[ListWrapper, String, String, Int, ?]]", + SerializableTests.serializable(Monad[ReaderWriterStateT[ListWrapper, String, String, Int, ?]]) + ) } { @@ -368,9 +404,11 @@ class ReaderWriterStateTSuite extends CatsSuite { EitherT.catsDataEqForEitherT[ReaderWriterStateT[Option, String, String, Int, ?], Unit, Int] checkAll("ReaderWriterStateT[Option, String, String, Int, Int]", - MonadErrorTests[ReaderWriterStateT[Option, String, String, Int, ?], Unit].monadError[Int, Int, Int]) - checkAll("MonadError[ReaderWriterStateT[Option, String, String, Int, ?], Unit]", - SerializableTests.serializable(MonadError[ReaderWriterStateT[Option, String, String, Int, ?], Unit])) + MonadErrorTests[ReaderWriterStateT[Option, String, String, Int, ?], Unit].monadError[Int, Int, Int]) + checkAll( + "MonadError[ReaderWriterStateT[Option, String, String, Int, ?], Unit]", + SerializableTests.serializable(MonadError[ReaderWriterStateT[Option, String, String, Int, ?], Unit]) + ) } { @@ -378,9 +416,11 @@ class ReaderWriterStateTSuite extends CatsSuite { implicit val S: SemigroupK[ListWrapper] = ListWrapper.semigroupK checkAll("ReaderWriterStateT[ListWrapper, String, String, Int, Int]", - SemigroupKTests[ReaderWriterStateT[ListWrapper, String, String, Int, ?]].semigroupK[Int]) - checkAll("SemigroupK[ReaderWriterStateT[ListWrapper, String, String, Int, ?]]", - SerializableTests.serializable(SemigroupK[ReaderWriterStateT[ListWrapper, String, String, Int, ?]])) + SemigroupKTests[ReaderWriterStateT[ListWrapper, String, String, Int, ?]].semigroupK[Int]) + checkAll( + "SemigroupK[ReaderWriterStateT[ListWrapper, String, String, Int, ?]]", + SerializableTests.serializable(SemigroupK[ReaderWriterStateT[ListWrapper, String, String, Int, ?]]) + ) } } @@ -397,12 +437,17 @@ object ReaderWriterStateTSuite { def addLogUnit(i: Int): ReaderWriterState[String, Unit, Int, Int] = { import cats.kernel.instances.unit._ - ReaderWriterState { (context, state) => ((), state + i, state + i) } + ReaderWriterState { (context, state) => + ((), state + i, state + i) + } } - implicit def IRWSTEq[F[_], E, L, SA, SB, A](implicit SA: Arbitrary[SA], SB: Arbitrary[SB], E: Arbitrary[E], - FLSB: Eq[F[(L, SB, A)]], F: Monad[F]): Eq[IndexedReaderWriterStateT[F, E, L, SA, SB, A]] = - Eq.by[IndexedReaderWriterStateT[F, E, L, SA, SB, A], (E, SA) => F[(L, SB, A)]] { state => - (e, s) => state.run(e, s) + implicit def IRWSTEq[F[_], E, L, SA, SB, A](implicit SA: Arbitrary[SA], + SB: Arbitrary[SB], + E: Arbitrary[E], + FLSB: Eq[F[(L, SB, A)]], + F: Monad[F]): Eq[IndexedReaderWriterStateT[F, E, L, SA, SB, A]] = + Eq.by[IndexedReaderWriterStateT[F, E, L, SA, SB, A], (E, SA) => F[(L, SB, A)]] { state => (e, s) => + state.run(e, s) } } diff --git a/tests/src/test/scala/cats/tests/IndexedStateTSuite.scala b/tests/src/test/scala/cats/tests/IndexedStateTSuite.scala index 88589251c35..4fb6f69b5fd 100644 --- a/tests/src/test/scala/cats/tests/IndexedStateTSuite.scala +++ b/tests/src/test/scala/cats/tests/IndexedStateTSuite.scala @@ -18,8 +18,8 @@ class IndexedStateTSuite extends CatsSuite { import IndexedStateTSuite._ - test("basic state usage"){ - add1.run(1).value should === (2 -> 1) + test("basic state usage") { + add1.run(1).value should ===(2 -> 1) } test("basic IndexedStateT usage") { @@ -34,46 +34,46 @@ class IndexedStateTSuite extends CatsSuite { r <- IndexedStateT.get[Id, String] } yield r - composite.run(List(1, 2, 3)) should === (("1", "1")) - composite.run(Nil) should === (("0", "0")) + composite.run(List(1, 2, 3)) should ===(("1", "1")) + composite.run(Nil) should ===(("0", "0")) } - test("traversing state is stack-safe"){ + test("traversing state is stack-safe") { val ns = (0 to 70000).toList val x = ns.traverse(_ => add1) - x.runS(0).value should === (70001) + x.runS(0).value should ===(70001) } - test("State.pure, StateT.pure and IndexedStateT.pure are consistent"){ + test("State.pure, StateT.pure and IndexedStateT.pure are consistent") { forAll { (s: String, i: Int) => val state: State[String, Int] = State.pure(i) val stateT: State[String, Int] = StateT.pure(i) val indexedStateT: State[String, Int] = IndexedStateT.pure(i) - state.run(s) should === (stateT.run(s)) - state.run(s) should === (indexedStateT.run(s)) + state.run(s) should ===(stateT.run(s)) + state.run(s) should ===(indexedStateT.run(s)) } } - test("State.empty, StateT.empty and IndexedStateT.empty are consistent"){ + test("State.empty, StateT.empty and IndexedStateT.empty are consistent") { forAll { (s: String) => val state: State[String, Int] = State.empty val stateT: State[String, Int] = StateT.empty val indexedStateT: State[String, Int] = IndexedStateT.empty - state.run(s) should === (stateT.run(s)) - state.run(s) should === (indexedStateT.run(s)) + state.run(s) should ===(stateT.run(s)) + state.run(s) should ===(indexedStateT.run(s)) } } test("State.get, StateT.get and IndexedStateT.get are consistent") { - forAll{ (s: String) => + forAll { (s: String) => val state: State[String, String] = State.get val stateT: State[String, String] = StateT.get val indexedStateT: State[String, String] = IndexedStateT.get - state.run(s) should === (stateT.run(s)) - state.run(s) should === (indexedStateT.run(s)) + state.run(s) should ===(stateT.run(s)) + state.run(s) should ===(indexedStateT.run(s)) } } @@ -83,8 +83,8 @@ class IndexedStateTSuite extends CatsSuite { val stateT: State[String, Int] = StateT.inspect(f) val indexedStateT: State[String, Int] = IndexedStateT.inspect(f) - state.run(s) should === (stateT.run(s)) - state.run(s) should === (indexedStateT.run(s)) + state.run(s) should ===(stateT.run(s)) + state.run(s) should ===(indexedStateT.run(s)) } } @@ -94,8 +94,8 @@ class IndexedStateTSuite extends CatsSuite { val stateT: State[String, Int] = StateT.inspectF(f.andThen(Eval.now)) val indexedStateT: State[String, Int] = IndexedStateT.inspectF(f.andThen(Eval.now)) - state.run(s) should === (stateT.run(s)) - state.run(s) should === (indexedStateT.run(s)) + state.run(s) should ===(stateT.run(s)) + state.run(s) should ===(indexedStateT.run(s)) } } @@ -105,8 +105,8 @@ class IndexedStateTSuite extends CatsSuite { val stateT: State[String, Unit] = StateT.modify(f) val indexedStateT: State[String, Unit] = IndexedStateT.modify(f) - state.run(s) should === (stateT.run(s)) - state.run(s) should === (indexedStateT.run(s)) + state.run(s) should ===(stateT.run(s)) + state.run(s) should ===(indexedStateT.run(s)) } } @@ -116,8 +116,8 @@ class IndexedStateTSuite extends CatsSuite { val stateT: State[String, Unit] = StateT.modifyF(f.andThen(Eval.now)) val indexedStateT: State[String, Unit] = IndexedStateT.modifyF(f.andThen(Eval.now)) - state.run(s) should === (stateT.run(s)) - state.run(s) should === (indexedStateT.run(s)) + state.run(s) should ===(stateT.run(s)) + state.run(s) should ===(indexedStateT.run(s)) } } @@ -127,8 +127,8 @@ class IndexedStateTSuite extends CatsSuite { val stateT: State[String, Int] = StateT.liftF(Eval.now(i)) val indexedStateT: State[String, Int] = IndexedStateT.liftF(Eval.now(i)) - state.run(s) should === (stateT.run(s)) - state.run(s) should === (indexedStateT.run(s)) + state.run(s) should ===(stateT.run(s)) + state.run(s) should ===(indexedStateT.run(s)) } } @@ -138,8 +138,8 @@ class IndexedStateTSuite extends CatsSuite { val stateT: StateT[Eval, String, Unit] = StateT.set(s) val indexedStateT: StateT[Eval, String, Unit] = IndexedStateT.set(s) - state.run(init) should === (stateT.run(init)) - state.run(init) should === (indexedStateT.run(init)) + state.run(init) should ===(stateT.run(init)) + state.run(init) should ===(indexedStateT.run(init)) } } @@ -149,54 +149,53 @@ class IndexedStateTSuite extends CatsSuite { val stateT: StateT[Eval, String, Unit] = StateT.setF(Eval.now(s)) val indexedStateT: StateT[Eval, String, Unit] = IndexedStateT.setF(Eval.now(s)) - state.run(init) should === (stateT.run(init)) - state.run(init) should === (indexedStateT.run(init)) + state.run(init) should ===(stateT.run(init)) + state.run(init) should ===(indexedStateT.run(init)) } } test("Semigroupal syntax is usable on State") { val x = add1 *> add1 - x.runS(0).value should === (2) + x.runS(0).value should ===(2) } - test("Singleton and instance inspect are consistent"){ + test("Singleton and instance inspect are consistent") { forAll { (s: String, i: Int) => - State.inspect[Int, String](_.toString).run(i) should === ( - State.pure[Int, Unit](()).inspect(_.toString).run(i)) + State.inspect[Int, String](_.toString).run(i) should ===(State.pure[Int, Unit](()).inspect(_.toString).run(i)) } } test("flatMap and flatMapF consistent") { forAll { (stateT: StateT[Option, Long, Int], f: Int => Option[Int]) => - stateT.flatMap(a => StateT(s => f(a).map(b => (s, b)))) should === (stateT.flatMapF(f)) + stateT.flatMap(a => StateT(s => f(a).map(b => (s, b)))) should ===(stateT.flatMapF(f)) } } - test("runEmpty, runEmptyS, and runEmptyA consistent"){ + test("runEmpty, runEmptyS, and runEmptyA consistent") { forAll { (f: StateT[List, Long, Int]) => - (f.runEmptyS zip f.runEmptyA) should === (f.runEmpty) + (f.runEmptyS.zip(f.runEmptyA)) should ===(f.runEmpty) } } - test("modify identity is a noop"){ + test("modify identity is a noop") { forAll { (f: StateT[List, Long, Int]) => - f.modify(identity) should === (f) + f.modify(identity) should ===(f) } } - test("modify modifies state"){ + test("modify modifies state") { forAll { (f: StateT[List, Long, Int], g: Long => Long, initial: Long) => - f.modify(g).runS(initial) should === (f.runS(initial).map(g)) + f.modify(g).runS(initial) should ===(f.runS(initial).map(g)) } } - test("modify doesn't affect A value"){ + test("modify doesn't affect A value") { forAll { (f: StateT[List, Long, Int], g: Long => Long, initial: Long) => - f.modify(g).runA(initial) should === (f.runA(initial)) + f.modify(g).runA(initial) should ===(f.runA(initial)) } } - test("State.modify equivalent to get then set"){ + test("State.modify equivalent to get then set") { forAll { (f: Long => Long) => val s1 = for { l <- State.get[Long] @@ -205,7 +204,7 @@ class IndexedStateTSuite extends CatsSuite { val s2 = State.modify(f) - s1 should === (s2) + s1 should ===(s2) } } @@ -213,7 +212,7 @@ class IndexedStateTSuite extends CatsSuite { forAll { (init: String, update: String) => val s1 = StateT.modify[Eval, String](_ => update) val s2 = StateT.set[Eval, String](update) - s1.run(init) should === (s2.run(init)) + s1.run(init) should ===(s2.run(init)) } } @@ -221,33 +220,33 @@ class IndexedStateTSuite extends CatsSuite { forAll { (init: String, update: String) => val s1 = StateT.modifyF[Eval, String](_ => Eval.now(update)) val s2 = StateT.setF(Eval.now(update)) - s1.run(init) should === (s2.run(init)) + s1.run(init) should ===(s2.run(init)) } } - test(".get and then .run produces same state as value"){ + test(".get and then .run produces same state as value") { forAll { (s: State[Long, Int], initial: Long) => val (finalS, finalA) = s.get.run(initial).value - finalS should === (finalA) + finalS should ===(finalA) } } - test(".get equivalent to flatMap with State.get"){ + test(".get equivalent to flatMap with State.get") { forAll { (s: State[Long, Int]) => - s.get should === (s.flatMap(_ => State.get)) + s.get should ===(s.flatMap(_ => State.get)) } } test("StateT#transformS with identity is identity") { forAll { (s: StateT[List, Long, Int]) => - s.transformS[Long](identity, (s, i) => i) should === (s) + s.transformS[Long](identity, (s, i) => i) should ===(s) } } test("StateT#mapK transforms effect") { val f: Eval ~> Id = λ[Eval ~> Id](_.value) forAll { (state: StateT[Eval, Long, Int], initial: Long) => - state.mapK(f).runA(initial) should === (state.runA(initial).value) + state.mapK(f).runA(initial) should ===(state.runA(initial).value) } } @@ -259,10 +258,9 @@ class IndexedStateTSuite extends CatsSuite { val got = x.run(input) val expected = xx.run(Env(input, "hello")).map { case (e, i) => (e.int, i) } - got should === (expected) + got should ===(expected) } - private val stackSafeTestSize = if (Platform.isJvm) 100000 else 100 @@ -272,7 +270,7 @@ class IndexedStateTSuite extends CatsSuite { val result = (0 until count).foldLeft(unit) { (acc, _) => acc.flatMap(_ => unit) } - result.run(()).value should === (((), ())) + result.run(()).value should ===(((), ())) } test("flatMap is stack safe on repeated right binds when F is") { @@ -281,7 +279,7 @@ class IndexedStateTSuite extends CatsSuite { val result = (0 until count).foldLeft(unit) { (acc, _) => unit.flatMap(_ => acc) } - result.run(()).value should === (((), ())) + result.run(()).value should ===(((), ())) } test("untilDefinedM works") { @@ -290,7 +288,7 @@ class IndexedStateTSuite extends CatsSuite { (i + 1, res) } - counter.untilDefinedM.run(0).value should === ((stackSafeTestSize + 2, stackSafeTestSize + 1)) + counter.untilDefinedM.run(0).value should ===((stackSafeTestSize + 2, stackSafeTestSize + 1)) } test("foreverM works") { @@ -298,7 +296,7 @@ class IndexedStateTSuite extends CatsSuite { if (i > stackSafeTestSize) Left(i) else Right((i + 1, ())) } step.foreverM.run(0) match { - case Left(big) => big should === (stackSafeTestSize + 1) + case Left(big) => big should ===(stackSafeTestSize + 1) case Right((_, _)) => fail("unreachable code due to Nothing, but scalac won't let us match on it") } } @@ -310,12 +308,14 @@ class IndexedStateTSuite extends CatsSuite { } } result.run(0) match { - case Left(sum) => sum should === (stackSafeTestSize + 1) + case Left(sum) => sum should ===(stackSafeTestSize + 1) case Right((_, _)) => fail("unreachable code due to Nothing, but scalac won't let us match on it") } } - implicit val iso = SemigroupalTests.Isomorphisms.invariant[IndexedStateT[ListWrapper, String, Int, ?]](IndexedStateT.catsDataFunctorForIndexedStateT(ListWrapper.monad)) + implicit val iso = SemigroupalTests.Isomorphisms.invariant[IndexedStateT[ListWrapper, String, Int, ?]]( + IndexedStateT.catsDataFunctorForIndexedStateT(ListWrapper.monad) + ) { // F has a Functor @@ -349,18 +349,23 @@ class IndexedStateTSuite extends CatsSuite { implicit val F: Monad[ListWrapper] = ListWrapper.monad implicit val FS: Functor[IndexedStateT[ListWrapper, String, Int, ?]] = IndexedStateT.catsDataFunctorForIndexedStateT - checkAll("IndexedStateT[ListWrapper, String, Int, Int]", FunctorTests[IndexedStateT[ListWrapper, String, Int, ?]].functor[Int, Int, Int]) - checkAll("Functor[IndexedStateT[ListWrapper, Int, ?]]", SerializableTests.serializable(Functor[IndexedStateT[ListWrapper, String, Int, ?]])) + checkAll("IndexedStateT[ListWrapper, String, Int, Int]", + FunctorTests[IndexedStateT[ListWrapper, String, Int, ?]].functor[Int, Int, Int]) + checkAll("Functor[IndexedStateT[ListWrapper, Int, ?]]", + SerializableTests.serializable(Functor[IndexedStateT[ListWrapper, String, Int, ?]])) Functor[IndexedStateT[ListWrapper, String, Int, ?]] } { implicit val F: Monad[ListWrapper] = ListWrapper.monad - implicit val FS: Contravariant[IndexedStateT[ListWrapper, ?, Int, Int]] = IndexedStateT.catsDataContravariantForIndexedStateT + implicit val FS: Contravariant[IndexedStateT[ListWrapper, ?, Int, Int]] = + IndexedStateT.catsDataContravariantForIndexedStateT - checkAll("IndexedStateT[ListWrapper, Int, Int, Int]", ContravariantTests[IndexedStateT[ListWrapper, ?, Int, Int]].contravariant[Int, Int, Int]) - checkAll("Contravariant[IndexedStateT[ListWrapper, ?, Int, Int]]", SerializableTests.serializable(Contravariant[IndexedStateT[ListWrapper, ?, Int, Int]])) + checkAll("IndexedStateT[ListWrapper, Int, Int, Int]", + ContravariantTests[IndexedStateT[ListWrapper, ?, Int, Int]].contravariant[Int, Int, Int]) + checkAll("Contravariant[IndexedStateT[ListWrapper, ?, Int, Int]]", + SerializableTests.serializable(Contravariant[IndexedStateT[ListWrapper, ?, Int, Int]])) Contravariant[IndexedStateT[ListWrapper, ?, Int, Int]] } @@ -369,18 +374,23 @@ class IndexedStateTSuite extends CatsSuite { implicit val F: Monad[ListWrapper] = ListWrapper.monad implicit val FS: Bifunctor[IndexedStateT[ListWrapper, Int, ?, ?]] = IndexedStateT.catsDataBifunctorForIndexedStateT - checkAll("IndexedStateT[ListWrapper, Int, String, Int]", BifunctorTests[IndexedStateT[ListWrapper, Int, ?, ?]].bifunctor[String, String, String, Int, Int, Int]) - checkAll("Bifunctor[IndexedStateT[ListWrapper, Int, ?, ?]]", SerializableTests.serializable(Bifunctor[IndexedStateT[ListWrapper, Int, ?, ?]])) + checkAll("IndexedStateT[ListWrapper, Int, String, Int]", + BifunctorTests[IndexedStateT[ListWrapper, Int, ?, ?]].bifunctor[String, String, String, Int, Int, Int]) + checkAll("Bifunctor[IndexedStateT[ListWrapper, Int, ?, ?]]", + SerializableTests.serializable(Bifunctor[IndexedStateT[ListWrapper, Int, ?, ?]])) Bifunctor[IndexedStateT[ListWrapper, Int, ?, ?]] } { implicit val F: Monad[ListWrapper] = ListWrapper.monad - implicit val FS: Profunctor[IndexedStateT[ListWrapper, ?, ?, Int]] = IndexedStateT.catsDataProfunctorForIndexedStateT + implicit val FS: Profunctor[IndexedStateT[ListWrapper, ?, ?, Int]] = + IndexedStateT.catsDataProfunctorForIndexedStateT - checkAll("IndexedStateT[ListWrapper, String, Int, Int]", ProfunctorTests[IndexedStateT[ListWrapper, ?, ?, Int]].profunctor[String, String, String, Int, Int, Int]) - checkAll("Profunctor[IndexedStateT[ListWrapper, ?, ?, Int]]", SerializableTests.serializable(Profunctor[IndexedStateT[ListWrapper, ?, ?, Int]])) + checkAll("IndexedStateT[ListWrapper, String, Int, Int]", + ProfunctorTests[IndexedStateT[ListWrapper, ?, ?, Int]].profunctor[String, String, String, Int, Int, Int]) + checkAll("Profunctor[IndexedStateT[ListWrapper, ?, ?, Int]]", + SerializableTests.serializable(Profunctor[IndexedStateT[ListWrapper, ?, ?, Int]])) Profunctor[IndexedStateT[ListWrapper, ?, ?, Int]] } @@ -389,8 +399,10 @@ class IndexedStateTSuite extends CatsSuite { implicit val F: Monad[ListWrapper] = ListWrapper.monad implicit val FS: Strong[IndexedStateT[ListWrapper, ?, ?, Int]] = IndexedStateT.catsDataStrongForIndexedStateT - checkAll("IndexedStateT[ListWrapper, String, Int, Int]", StrongTests[IndexedStateT[ListWrapper, ?, ?, Int]].strong[String, String, String, Int, Int, Int]) - checkAll("Strong[IndexedStateT[ListWrapper, ?, ?, Int]]", SerializableTests.serializable(Strong[IndexedStateT[ListWrapper, ?, ?, Int]])) + checkAll("IndexedStateT[ListWrapper, String, Int, Int]", + StrongTests[IndexedStateT[ListWrapper, ?, ?, Int]].strong[String, String, String, Int, Int, Int]) + checkAll("Strong[IndexedStateT[ListWrapper, ?, ?, Int]]", + SerializableTests.serializable(Strong[IndexedStateT[ListWrapper, ?, ?, Int]])) Strong[IndexedStateT[ListWrapper, ?, ?, Int]] } @@ -399,8 +411,10 @@ class IndexedStateTSuite extends CatsSuite { // F has a Monad implicit val F = ListWrapper.monad - checkAll("IndexedStateT[ListWrapper, Int, Int]", MonadTests[IndexedStateT[ListWrapper, Int, Int, ?]].monad[Int, Int, Int]) - checkAll("Monad[StateT[ListWrapper, Int, ?]]", SerializableTests.serializable(Monad[IndexedStateT[ListWrapper, Int, Int, ?]])) + checkAll("IndexedStateT[ListWrapper, Int, Int]", + MonadTests[IndexedStateT[ListWrapper, Int, Int, ?]].monad[Int, Int, Int]) + checkAll("Monad[StateT[ListWrapper, Int, ?]]", + SerializableTests.serializable(Monad[IndexedStateT[ListWrapper, Int, Int, ?]])) Monad[IndexedStateT[ListWrapper, Int, Int, ?]] FlatMap[IndexedStateT[ListWrapper, Int, Int, ?]] @@ -414,17 +428,21 @@ class IndexedStateTSuite extends CatsSuite { implicit val F = ListWrapper.monad implicit val S = ListWrapper.semigroupK - checkAll("IndexedStateT[ListWrapper, Int, Int]", SemigroupKTests[IndexedStateT[ListWrapper, Int, Int, ?]].semigroupK[Int]) - checkAll("SemigroupK[IndexedStateT[ListWrapper, Int, ?]]", SerializableTests.serializable(SemigroupK[IndexedStateT[ListWrapper, String, Int, ?]])) + checkAll("IndexedStateT[ListWrapper, Int, Int]", + SemigroupKTests[IndexedStateT[ListWrapper, Int, Int, ?]].semigroupK[Int]) + checkAll("SemigroupK[IndexedStateT[ListWrapper, Int, ?]]", + SerializableTests.serializable(SemigroupK[IndexedStateT[ListWrapper, String, Int, ?]])) } { // F has an Alternative implicit val G = ListWrapper.monad implicit val F = ListWrapper.alternative - val SA = IndexedStateT.catsDataAlternativeForIndexedStateT[ListWrapper, Int](ListWrapper.monad, ListWrapper.alternative) + val SA = + IndexedStateT.catsDataAlternativeForIndexedStateT[ListWrapper, Int](ListWrapper.monad, ListWrapper.alternative) - checkAll("IndexedStateT[ListWrapper, Int, Int, Int]", AlternativeTests[IndexedStateT[ListWrapper, Int, Int, ?]](SA).alternative[Int, Int, Int]) + checkAll("IndexedStateT[ListWrapper, Int, Int, Int]", + AlternativeTests[IndexedStateT[ListWrapper, Int, Int, ?]](SA).alternative[Int, Int, Int]) checkAll("Alternative[IndexedStateT[ListWrapper, Int, Int, ?]]", SerializableTests.serializable(SA)) Monad[IndexedStateT[ListWrapper, Int, Int, ?]] @@ -447,16 +465,18 @@ class IndexedStateTSuite extends CatsSuite { { // F has a MonadError implicit val iso = SemigroupalTests.Isomorphisms.invariant[StateT[Option, Int, ?]] - implicit val eqEitherTFA: Eq[EitherT[StateT[Option, Int , ?], Unit, Int]] = EitherT.catsDataEqForEitherT[StateT[Option, Int , ?], Unit, Int] + implicit val eqEitherTFA: Eq[EitherT[StateT[Option, Int, ?], Unit, Int]] = + EitherT.catsDataEqForEitherT[StateT[Option, Int, ?], Unit, Int] checkAll("StateT[Option, Int, Int]", MonadErrorTests[StateT[Option, Int, ?], Unit].monadError[Int, Int, Int]) - checkAll("MonadError[StateT[Option, Int, ?], Unit]", SerializableTests.serializable(MonadError[StateT[Option, Int , ?], Unit])) + checkAll("MonadError[StateT[Option, Int, ?], Unit]", + SerializableTests.serializable(MonadError[StateT[Option, Int, ?], Unit])) } } object IndexedStateTSuite extends IndexedStateTSuiteInstances { - implicit def stateEq[S:Eq:Arbitrary, A:Eq]: Eq[State[S, A]] = + implicit def stateEq[S: Eq: Arbitrary, A: Eq]: Eq[State[S, A]] = indexedStateTEq[Eval, S, S, A] val add1: State[Int, Int] = State(n => (n + 1, n)) @@ -464,7 +484,8 @@ object IndexedStateTSuite extends IndexedStateTSuiteInstances { sealed trait IndexedStateTSuiteInstances { - implicit def indexedStateTEq[F[_], SA, SB, A](implicit SA: Arbitrary[SA], FSB: Eq[F[(SB, A)]], F: FlatMap[F]): Eq[IndexedStateT[F, SA, SB, A]] = - Eq.by[IndexedStateT[F, SA, SB, A], SA => F[(SB, A)]](state => - s => state.run(s)) + implicit def indexedStateTEq[F[_], SA, SB, A](implicit SA: Arbitrary[SA], + FSB: Eq[F[(SB, A)]], + F: FlatMap[F]): Eq[IndexedStateT[F, SA, SB, A]] = + Eq.by[IndexedStateT[F, SA, SB, A], SA => F[(SB, A)]](state => s => state.run(s)) } diff --git a/tests/src/test/scala/cats/tests/InjectKSuite.scala b/tests/src/test/scala/cats/tests/InjectKSuite.scala index f057e5ec00a..64ec95219c9 100644 --- a/tests/src/test/scala/cats/tests/InjectKSuite.scala +++ b/tests/src/test/scala/cats/tests/InjectKSuite.scala @@ -9,7 +9,7 @@ class InjectKSuite extends CatsSuite { sealed trait Test1Algebra[A] - case class Test1[A](value : Int, f: Int => A) extends Test1Algebra[A] + case class Test1[A](value: Int, f: Int => A) extends Test1Algebra[A] object Test1Algebra { implicit def test1AlgebraAFunctor: Functor[Test1Algebra] = @@ -19,15 +19,16 @@ class InjectKSuite extends CatsSuite { } } - implicit def test1AlgebraArbitrary[A](implicit seqArb: Arbitrary[Int], intAArb : Arbitrary[Int => A]): Arbitrary[Test1Algebra[A]] = - Arbitrary(for {s <- seqArb.arbitrary; f <- intAArb.arbitrary} yield Test1(s, f)) + implicit def test1AlgebraArbitrary[A](implicit seqArb: Arbitrary[Int], + intAArb: Arbitrary[Int => A]): Arbitrary[Test1Algebra[A]] = + Arbitrary(for { s <- seqArb.arbitrary; f <- intAArb.arbitrary } yield Test1(s, f)) implicit def test1AlgebraEq[A](implicit ev: Eq[A]): Eq[Test1Algebra[A]] = Eq.fromUniversalEquals } sealed trait Test2Algebra[A] - case class Test2[A](value : Int, f: Int => A) extends Test2Algebra[A] + case class Test2[A](value: Int, f: Int => A) extends Test2Algebra[A] object Test2Algebra { implicit def test2AlgebraAFunctor: Functor[Test2Algebra] = @@ -37,8 +38,9 @@ class InjectKSuite extends CatsSuite { } } - implicit def test2AlgebraArbitrary[A](implicit seqArb: Arbitrary[Int], intAArb : Arbitrary[Int => A]): Arbitrary[Test2Algebra[A]] = - Arbitrary(for {s <- seqArb.arbitrary; f <- intAArb.arbitrary} yield Test2(s, f)) + implicit def test2AlgebraArbitrary[A](implicit seqArb: Arbitrary[Int], + intAArb: Arbitrary[Int => A]): Arbitrary[Test2Algebra[A]] = + Arbitrary(for { s <- seqArb.arbitrary; f <- intAArb.arbitrary } yield Test2(s, f)) implicit def test2AlgebraEq[A](implicit ev: Eq[A]): Eq[Test2Algebra[A]] = Eq.fromUniversalEquals } @@ -46,17 +48,16 @@ class InjectKSuite extends CatsSuite { type T[A] = EitherK[Test1Algebra, Test2Algebra, A] implicit def tArbitrary[A]( - implicit arb1: Arbitrary[Test1Algebra[A]], arb2: Arbitrary[Test2Algebra[A]] - ): Arbitrary[T[A]] = Arbitrary(Gen.oneOf( - arb1.arbitrary.map(EitherK.leftc(_): T[A]), - arb2.arbitrary.map(EitherK.rightc(_): T[A]))) + implicit arb1: Arbitrary[Test1Algebra[A]], + arb2: Arbitrary[Test2Algebra[A]] + ): Arbitrary[T[A]] = + Arbitrary(Gen.oneOf(arb1.arbitrary.map(EitherK.leftc(_): T[A]), arb2.arbitrary.map(EitherK.rightc(_): T[A]))) test("inj & prj") { - def distr[F[_], A](f1: F[A], f2: F[A]) - (implicit - F: Functor[F], - I0: Test1Algebra :<: F, - I1: Test2Algebra :<: F): Option[Int] = + def distr[F[_], A](f1: F[A], f2: F[A])(implicit + F: Functor[F], + I0: Test1Algebra :<: F, + I1: Test2Algebra :<: F): Option[Int] = for { Test1(x, _) <- I0.prj(f1) Test2(y, _) <- I1.prj(f2) @@ -71,11 +72,10 @@ class InjectKSuite extends CatsSuite { } test("apply & unapply") { - def distr[F[_], A](f1: F[A], f2: F[A]) - (implicit - F: Functor[F], - I0: Test1Algebra :<: F, - I1: Test2Algebra :<: F): Option[Int] = + def distr[F[_], A](f1: F[A], f2: F[A])(implicit + F: Functor[F], + I0: Test1Algebra :<: F, + I1: Test2Algebra :<: F): Option[Int] = for { Test1(x, _) <- I0.unapply(f1) Test2(y, _) <- I1.unapply(f2) diff --git a/tests/src/test/scala/cats/tests/InjectSuite.scala b/tests/src/test/scala/cats/tests/InjectSuite.scala index 60fb8c3fef3..633ad13918a 100644 --- a/tests/src/test/scala/cats/tests/InjectSuite.scala +++ b/tests/src/test/scala/cats/tests/InjectSuite.scala @@ -8,11 +8,9 @@ class InjectSuite extends CatsSuite { type StringOrInt = Either[String, Int] test("inj & prj") { - def distr[F](f1: F, f2: F) - (implicit - I0: Inject[String, F], - I1: Inject[Int, F] - ): Option[String] = + def distr[F](f1: F, f2: F)(implicit + I0: Inject[String, F], + I1: Inject[Int, F]): Option[String] = for { x <- I0.prj(f1) y <- I1.prj(f2) @@ -27,11 +25,9 @@ class InjectSuite extends CatsSuite { } test("apply & unapply") { - def distr[F](f1: F, f2: F) - (implicit - I0: Inject[String, F], - I1: Inject[Int, F] - ): Option[String] = + def distr[F](f1: F, f2: F)(implicit + I0: Inject[String, F], + I1: Inject[Int, F]): Option[String] = for { x <- I0.unapply(f1) y <- I1.unapply(f2) diff --git a/tests/src/test/scala/cats/tests/IorSuite.scala b/tests/src/test/scala/cats/tests/IorSuite.scala index a6e5a5a938e..1f28382611e 100644 --- a/tests/src/test/scala/cats/tests/IorSuite.scala +++ b/tests/src/test/scala/cats/tests/IorSuite.scala @@ -2,8 +2,15 @@ package cats package tests import cats.kernel.laws.discipline.SemigroupTests -import cats.laws.discipline.{BifunctorTests, BitraverseTests, SemigroupalTests, MonadErrorTests, SerializableTests, TraverseTests} -import cats.data.{Ior, NonEmptyChain, NonEmptyList, NonEmptySet, EitherT} +import cats.laws.discipline.{ + BifunctorTests, + BitraverseTests, + MonadErrorTests, + SemigroupalTests, + SerializableTests, + TraverseTests +} +import cats.data.{EitherT, Ior, NonEmptyChain, NonEmptyList, NonEmptySet} import cats.laws.discipline.arbitrary._ import org.scalacheck.Arbitrary._ @@ -27,29 +34,30 @@ class IorSuite extends CatsSuite { checkAll("Bitraverse[Ior]", SerializableTests.serializable(Bitraverse[Ior])) checkAll("Semigroup[Ior[A: Semigroup, B: Semigroup]]", SemigroupTests[Ior[List[Int], List[Int]]].semigroup) - checkAll("SerializableTest Semigroup[Ior[A: Semigroup, B: Semigroup]]", SerializableTests.serializable(Semigroup[Ior[List[Int], List[Int]]])) + checkAll("SerializableTest Semigroup[Ior[A: Semigroup, B: Semigroup]]", + SerializableTests.serializable(Semigroup[Ior[List[Int], List[Int]]])) test("left Option is defined left and both") { forAll { (i: Int Ior String) => - (i.isLeft || i.isBoth) should === (i.left.isDefined) + (i.isLeft || i.isBoth) should ===(i.left.isDefined) } } test("right Option is defined for right and both") { forAll { (i: Int Ior String) => - (i.isRight || i.isBoth) should === (i.right.isDefined) + (i.isRight || i.isBoth) should ===(i.right.isDefined) } } test("onlyLeftOrRight") { forAll { (i: Int Ior String) => - i.onlyLeft.map(Left(_)).orElse(i.onlyRight.map(Right(_))) should === (i.onlyLeftOrRight) + i.onlyLeft.map(Left(_)).orElse(i.onlyRight.map(Right(_))) should ===(i.onlyLeftOrRight) } } test("onlyBoth consistent with left and right") { forAll { (i: Int Ior String) => - i.onlyBoth should === (for { + i.onlyBoth should ===(for { left <- i.left right <- i.right } yield (left, right)) @@ -58,60 +66,64 @@ class IorSuite extends CatsSuite { test("pad") { forAll { (i: Int Ior String) => - i.pad should === ((i.left, i.right)) + i.pad should ===((i.left, i.right)) } } test("unwrap consistent with isBoth") { forAll { (i: Int Ior String) => - i.unwrap.isRight should === (i.isBoth) + i.unwrap.isRight should ===(i.isBoth) } } test("valueOr consistent with leftMap") { forAll { (i: Int Ior String, f: Int => String) => - i.valueOr(f) should === (i.leftMap(f).fold(identity, identity, _ + _)) + i.valueOr(f) should ===(i.leftMap(f).fold(identity, identity, _ + _)) } } test("isLeft consistent with toOption") { forAll { (i: Int Ior String) => - i.isLeft should === (i.toOption.isEmpty) + i.isLeft should ===(i.toOption.isEmpty) } } test("isLeft consistent with toList") { forAll { (i: Int Ior String) => - i.isLeft should === (i.toList.isEmpty) + i.isLeft should ===(i.toList.isEmpty) } } test("isLeft consistent with forall and exists") { forAll { (i: Int Ior String, p: String => Boolean) => if (i.isLeft) { - (i.forall(p) && !i.exists(p)) should === (true) + (i.forall(p) && !i.exists(p)) should ===(true) } } } test("leftMap then swap equivalent to swap then map") { forAll { (i: Int Ior String, f: Int => Double) => - i.leftMap(f).swap should === (i.swap.map(f)) + i.leftMap(f).swap should ===(i.swap.map(f)) } } test("foreach is noop for left") { forAll { (i: Int) => - Ior.left[Int, String](i).foreach { _ => fail("should not be called") } + Ior.left[Int, String](i).foreach { _ => + fail("should not be called") + } } } test("foreach runs for right and both") { forAll { (i: Int Ior String) => var count = 0 - i.foreach { _ => count += 1 } - if (i.isRight || i.isBoth) count should === (1) - else count should === (0) + i.foreach { _ => + count += 1 + } + if (i.isRight || i.isBoth) count should ===(1) + else count should ===(0) } } @@ -119,122 +131,121 @@ class IorSuite extends CatsSuite { val iorShow = implicitly[Show[Int Ior String]] forAll { (i: Int Ior String) => - iorShow.show(i).nonEmpty should === (true) + iorShow.show(i).nonEmpty should ===(true) } } - test("merge") { forAll { (i: Int Ior Int) => - i.merge should === (i.left.getOrElse(0) + i.right.getOrElse(0)) + i.merge should ===(i.left.getOrElse(0) + i.right.getOrElse(0)) } } test("mergeLeft") { forAll { (i: Int Ior Int) => - i.mergeLeft should === (i.left.orElse(i.right).get) + i.mergeLeft should ===(i.left.orElse(i.right).get) } } test("mergeRight") { forAll { (i: Int Ior Int) => - i.mergeRight should === (i.right.orElse(i.left).get) + i.mergeRight should ===(i.right.orElse(i.left).get) } } test("putLeft") { forAll { (i: Int Ior Int) => val expectedResult = - if (i.isLeft) - Ior.left(2) - else - Ior.both(2, i.right.get) - i.putLeft(2) should === (expectedResult) + if (i.isLeft) + Ior.left(2) + else + Ior.both(2, i.right.get) + i.putLeft(2) should ===(expectedResult) } } test("putRight") { forAll { (i: Int Ior Int) => val expectedResult = - if (i.isRight) - Ior.right(2) - else - Ior.both(i.left.get, 2) - i.putRight(2) should === (expectedResult) + if (i.isRight) + Ior.right(2) + else + Ior.both(i.left.get, 2) + i.putRight(2) should ===(expectedResult) } } test("combine left") { forAll { (i: Int Ior String, j: Int Ior String) => - i.combine(j).left should === (i.left.map(_ + j.left.getOrElse(0)).orElse(j.left)) + i.combine(j).left should ===(i.left.map(_ + j.left.getOrElse(0)).orElse(j.left)) } } test("combine right") { forAll { (i: Int Ior String, j: Int Ior String) => - i.combine(j).right should === (i.right.map(_ + j.right.getOrElse("")).orElse(j.right)) + i.combine(j).right should ===(i.right.map(_ + j.right.getOrElse("")).orElse(j.right)) } } - test("fromOptions left/right consistent with input options"){ + test("fromOptions left/right consistent with input options") { forAll { (oa: Option[String], ob: Option[Int]) => val x = Ior.fromOptions(oa, ob) - x.flatMap(_.left) should === (oa) - x.flatMap(_.right) should === (ob) + x.flatMap(_.left) should ===(oa) + x.flatMap(_.right) should ===(ob) } } - test("Option roundtrip"){ + test("Option roundtrip") { forAll { ior: String Ior Int => val iorMaybe = Ior.fromOptions(ior.left, ior.right) - iorMaybe should === (Some(ior)) + iorMaybe should ===(Some(ior)) } } test("to consistent with toList") { forAll { (x: Int Ior String) => - x.to[List, String] should === (x.toList) + x.to[List, String] should ===(x.toList) } } test("to consistent with toOption") { forAll { (x: Int Ior String) => - x.to[Option, String] should === (x.toOption) + x.to[Option, String] should ===(x.toOption) } } test("toEither consistent with right") { forAll { (x: Int Ior String) => - x.toEither.toOption should === (x.right) + x.toEither.toOption should ===(x.right) } } test("toValidated consistent with right") { forAll { (x: Int Ior String) => - x.toValidated.toOption should === (x.right) + x.toValidated.toOption should ===(x.right) } } test("toIorNec Left") { val ior = Ior.left[String, Int]("oops") - ior.toIorNec should === (Ior.left[NonEmptyChain[String], Int](NonEmptyChain.one("oops"))) + ior.toIorNec should ===(Ior.left[NonEmptyChain[String], Int](NonEmptyChain.one("oops"))) } test("toIorNec Right") { val ior = Ior.right[String, Int](42) - ior.toIorNec should === (Ior.right[NonEmptyChain[String], Int](42)) + ior.toIorNec should ===(Ior.right[NonEmptyChain[String], Int](42)) } test("toIorNec Both") { val ior = Ior.both[String, Int]("oops", 42) - ior.toIorNec should === (Ior.both[NonEmptyChain[String], Int](NonEmptyChain.one("oops"), 42)) + ior.toIorNec should ===(Ior.both[NonEmptyChain[String], Int](NonEmptyChain.one("oops"), 42)) } test("toIorNes Left") { val ior = Ior.left[String, Int]("oops") - ior.toIorNes should === (Ior.left[NonEmptySet[String], Int](NonEmptySet.one("oops"))) + ior.toIorNes should ===(Ior.left[NonEmptySet[String], Int](NonEmptySet.one("oops"))) } test("toIorNes Right") { val ior = Ior.right[String, Int](42) - ior.toIorNes should === (Ior.right[NonEmptySet[String], Int](42)) + ior.toIorNes should ===(Ior.right[NonEmptySet[String], Int](42)) } test("toIorNes Both") { val ior = Ior.both[String, Int]("oops", 42) @@ -243,46 +254,46 @@ class IorSuite extends CatsSuite { test("toIorNel Left") { val ior = Ior.left[String, Int]("oops") - ior.toIorNel should === (Ior.left[NonEmptyList[String], Int](NonEmptyList.one("oops"))) + ior.toIorNel should ===(Ior.left[NonEmptyList[String], Int](NonEmptyList.one("oops"))) } test("toIorNel Right") { val ior = Ior.right[String, Int](42) - ior.toIorNel should === (Ior.right[NonEmptyList[String], Int](42)) + ior.toIorNel should ===(Ior.right[NonEmptyList[String], Int](42)) } test("toIorNel Both") { val ior = Ior.both[String, Int]("oops", 42) - ior.toIorNel should === (Ior.both[NonEmptyList[String], Int](NonEmptyList.one("oops"), 42)) + ior.toIorNel should ===(Ior.both[NonEmptyList[String], Int](NonEmptyList.one("oops"), 42)) } test("leftNel") { forAll { (x: String) => - Ior.leftNel(x).left should === (Some(NonEmptyList.one(x))) + Ior.leftNel(x).left should ===(Some(NonEmptyList.one(x))) } } test("leftNec") { forAll { (x: String) => - Ior.leftNec(x).left should === (Some(NonEmptyChain.one(x))) + Ior.leftNec(x).left should ===(Some(NonEmptyChain.one(x))) } } test("bothNel") { forAll { (x: Int, y: String) => - Ior.bothNel(y, x).onlyBoth should === (Some((NonEmptyList.one(y), x))) + Ior.bothNel(y, x).onlyBoth should ===(Some((NonEmptyList.one(y), x))) } } test("bothNec") { forAll { (x: Int, y: String) => - Ior.bothNec(y, x).onlyBoth should === (Some((NonEmptyChain.one(y), x))) + Ior.bothNec(y, x).onlyBoth should ===(Some((NonEmptyChain.one(y), x))) } } test("getOrElse consistent with Option getOrElse") { forAll { (x: Int Ior String, default: String) => - x.getOrElse(default) should === (x.toOption.getOrElse(default)) + x.getOrElse(default) should ===(x.toOption.getOrElse(default)) } } } diff --git a/tests/src/test/scala/cats/tests/IorTSuite.scala b/tests/src/test/scala/cats/tests/IorTSuite.scala index 93b2e80e35e..91aa23275a1 100644 --- a/tests/src/test/scala/cats/tests/IorTSuite.scala +++ b/tests/src/test/scala/cats/tests/IorTSuite.scala @@ -2,11 +2,7 @@ package cats package tests import cats.data.{Ior, IorT} -import cats.kernel.laws.discipline.{ - EqTests, - MonoidTests, - SemigroupTests -} +import cats.kernel.laws.discipline.{EqTests, MonoidTests, SemigroupTests} import cats.laws.discipline._ import cats.laws.discipline.arbitrary._ @@ -17,7 +13,8 @@ class IorTSuite extends CatsSuite { { implicit val F = ListWrapper.functor - checkAll("IorT[ListWrapper, ?, ?]", BifunctorTests[IorT[ListWrapper, ?, ?]].bifunctor[Int, Int, Int, String, String, String]) + checkAll("IorT[ListWrapper, ?, ?]", + BifunctorTests[IorT[ListWrapper, ?, ?]].bifunctor[Int, Int, Int, String, String, String]) checkAll("Bifunctor[IorT[ListWrapper, ?, ?]]", SerializableTests.serializable(Bifunctor[IorT[ListWrapper, ?, ?]])) checkAll("IorT[ListWrapper, Int, ?]", FunctorTests[IorT[ListWrapper, Int, ?]].functor[Int, Int, Int]) @@ -27,22 +24,27 @@ class IorTSuite extends CatsSuite { { implicit val F = ListWrapper.traverse - checkAll("IorT[ListWrapper, Int, ?]", TraverseTests[IorT[ListWrapper, Int, ?]].traverse[Int, Int, Int, Int, Option, Option]) + checkAll("IorT[ListWrapper, Int, ?]", + TraverseTests[IorT[ListWrapper, Int, ?]].traverse[Int, Int, Int, Int, Option, Option]) checkAll("Traverse[IorT[ListWrapper, Int, ?]]", SerializableTests.serializable(Traverse[IorT[ListWrapper, Int, ?]])) } { implicit val F = ListWrapper.monad - checkAll("IorT[ListWrapper, String, Int]", MonadErrorTests[IorT[ListWrapper, String, ?], String].monadError[Int, Int, Int]) - checkAll("MonadError[IorT[List, ?, ?]]", SerializableTests.serializable(MonadError[IorT[ListWrapper, String, ?], String])) + checkAll("IorT[ListWrapper, String, Int]", + MonadErrorTests[IorT[ListWrapper, String, ?], String].monadError[Int, Int, Int]) + checkAll("MonadError[IorT[List, ?, ?]]", + SerializableTests.serializable(MonadError[IorT[ListWrapper, String, ?], String])) } { implicit val F: MonadError[Option, Unit] = catsStdInstancesForOption - checkAll("IorT[Option, String, String]", MonadErrorTests[IorT[Option, String, ?], Unit].monadError[String, String, String]) - checkAll("MonadError[IorT[Option, ?, ?]]", SerializableTests.serializable(MonadError[IorT[Option, String, ?], Unit])) + checkAll("IorT[Option, String, String]", + MonadErrorTests[IorT[Option, String, ?], Unit].monadError[String, String, String]) + checkAll("MonadError[IorT[Option, ?, ?]]", + SerializableTests.serializable(MonadError[IorT[Option, String, ?], Unit])) } { @@ -56,14 +58,16 @@ class IorTSuite extends CatsSuite { implicit val F = ListWrapper.semigroup[Ior[String, Int]] checkAll("IorT[ListWrapper, String, Int]", SemigroupTests[IorT[ListWrapper, String, Int]].semigroup) - checkAll("Semigroup[IorT[ListWrapper, String, Int]]", SerializableTests.serializable(Semigroup[IorT[ListWrapper, String, Int]])) + checkAll("Semigroup[IorT[ListWrapper, String, Int]]", + SerializableTests.serializable(Semigroup[IorT[ListWrapper, String, Int]])) } { implicit val F = ListWrapper.monoid[Ior[String, Int]] checkAll("IorT[ListWrapper, String, Int]", MonoidTests[IorT[ListWrapper, String, Int]].monoid) - checkAll("Monoid[IorT[ListWrapper, String, Int]]", SerializableTests.serializable(Monoid[IorT[ListWrapper, String, Int]])) + checkAll("Monoid[IorT[ListWrapper, String, Int]]", + SerializableTests.serializable(Monoid[IorT[ListWrapper, String, Int]])) } { @@ -75,134 +79,134 @@ class IorTSuite extends CatsSuite { test("fold with Id consistent with Ior fold") { forAll { (iort: IorT[Id, String, Int], fa: String => Long, fb: Int => Long, fab: (String, Int) => Long) => - iort.fold(fa, fb, fab) should === (iort.value.fold(fa, fb, fab)) + iort.fold(fa, fb, fab) should ===(iort.value.fold(fa, fb, fab)) } } test("isLeft with Id consistent with Ior isLeft") { forAll { (iort: IorT[Id, String, Int]) => - iort.isLeft should === (iort.value.isLeft) + iort.isLeft should ===(iort.value.isLeft) } } test("isRight with Id consistent with Ior isRight") { forAll { (iort: IorT[Id, String, Int]) => - iort.isRight should === (iort.value.isRight) + iort.isRight should ===(iort.value.isRight) } } test("isBoth with Id consistent with Ior isBoth") { forAll { (iort: IorT[Id, String, Int]) => - iort.isBoth should === (iort.value.isBoth) + iort.isBoth should ===(iort.value.isBoth) } } test("isBoth consistent with swap") { forAll { (iort: IorT[List, String, Int]) => - iort.isBoth should === (iort.swap.isBoth) + iort.isBoth should ===(iort.swap.isBoth) } } test("double swap is noop") { forAll { (iort: IorT[List, String, Int]) => - iort.swap.swap.value should === (iort.value) + iort.swap.swap.value should ===(iort.value) } } test("getOrElse with Id consistent with Ior getOrElse") { forAll { (iort: IorT[Id, String, Int], i: Int) => - iort.getOrElse(i) should === (iort.value.getOrElse(i)) + iort.getOrElse(i) should ===(iort.value.getOrElse(i)) } } test("getOrElseF with Id consistent with Ior getOrElse") { forAll { (iort: IorT[Id, String, Int], i: Int) => - iort.getOrElseF(i) should === (iort.value.getOrElse(i)) + iort.getOrElseF(i) should ===(iort.value.getOrElse(i)) } } test("valueOr with Id consistent with Ior valueOr") { forAll { (iort: IorT[Id, String, Int], f: String => Int) => - iort.valueOr(f) should === (iort.value.valueOr(f)) + iort.valueOr(f) should ===(iort.value.valueOr(f)) } } test("forall with Id consistent with Ior forall") { forAll { (iort: IorT[Id, String, Int], f: Int => Boolean) => - iort.forall(f) should === (iort.value.forall(f)) + iort.forall(f) should ===(iort.value.forall(f)) } } test("exists with Id consistent with Ior exists") { forAll { (iort: IorT[Id, String, Int], f: Int => Boolean) => - iort.exists(f) should === (iort.value.exists(f)) + iort.exists(f) should ===(iort.value.exists(f)) } } test("toOption consistent with isLeft") { forAll { (iort: IorT[List, String, Int]) => - iort.toOption.isDefined.map(! _) should === (iort.isLeft) + iort.toOption.isDefined.map(!_) should ===(iort.isLeft) } } test("toEither consistent with toOption") { forAll { (iort: IorT[List, String, Int]) => - iort.toEither.toOption should === (iort.toOption) + iort.toEither.toOption should ===(iort.toOption) } } test("toEither consistent with isLeft") { forAll { (iort: IorT[List, String, Int]) => - iort.toEither.isLeft should === (iort.isLeft) + iort.toEither.isLeft should ===(iort.isLeft) } } test("toNested has no loss") { forAll { (iort: IorT[List, String, Int]) => - iort.toNested.value should === (iort.value) + iort.toNested.value should ===(iort.value) } } test("toNestedValidated consistent with Ior toValidated") { forAll { (iort: IorT[List, String, Int]) => - iort.toNestedValidated.value should === (iort.value.map(_.toValidated)) + iort.toNestedValidated.value should ===(iort.value.map(_.toValidated)) } } test("toValidated consistent with Ior toValidated") { forAll { (iort: IorT[List, String, Int]) => - iort.toValidated should === (iort.value.map(_.toValidated)) + iort.toValidated should ===(iort.value.map(_.toValidated)) } } test("to consistent with toOption") { forAll { (iort: IorT[List, String, Int]) => - iort.to[Option] should === (iort.toOption.value) + iort.to[Option] should ===(iort.toOption.value) } } test("collectRight with List consistent with flattening a to[List]") { forAll { (iort: IorT[List, String, Int]) => - iort.collectRight should === (iort.to[List].flatten) + iort.collectRight should ===(iort.to[List].flatten) } } test("merge with Id consistent with Ior merge") { forAll { (iort: IorT[Id, Int, Int]) => - iort.merge should === (iort.value.merge) + iort.merge should ===(iort.value.merge) } } test("mapK consistent with f(value)+pure") { val f: List ~> Option = λ[List ~> Option](_.headOption) forAll { (iort: IorT[List, String, Int]) => - iort.mapK(f) should === (IorT(f(iort.value))) + iort.mapK(f) should ===(IorT(f(iort.value))) } } test("leftMap with Id consistent with Ior leftMap") { forAll { (iort: IorT[Id, String, Int], f: String => Long) => - iort.leftMap(f).value should === (iort.value.leftMap(f)) + iort.leftMap(f).value should ===(iort.value.leftMap(f)) } } @@ -232,120 +236,120 @@ class IorTSuite extends CatsSuite { test("transform consistent with value.map") { forAll { (iort: IorT[List, String, Int], f: Ior[String, Int] => Ior[Long, Double]) => - iort.transform(f) should === (IorT(iort.value.map(f))) + iort.transform(f) should ===(IorT(iort.value.map(f))) } } test("applyAlt with Id consistent with map") { forAll { (iort: IorT[Id, String, Int], f: Int => String) => - iort.applyAlt(IorT.pure(f)) should === (iort.map(f)) + iort.applyAlt(IorT.pure(f)) should ===(iort.map(f)) } } test("flatMapF consistent with flatMap") { - forAll { (iort: IorT[List, String, Int], f: Int => IorT[List, String, Int]) => - iort.flatMapF(f(_).value) should === (iort.flatMap(f)) + forAll { (iort: IorT[List, String, Int], f: Int => IorT[List, String, Int]) => + iort.flatMapF(f(_).value) should ===(iort.flatMap(f)) } } test("subflatMap consistent with value.map+flatMap") { forAll { (iort: IorT[List, String, Int], f: Int => Ior[String, Double]) => - iort.subflatMap(f) should === (IorT(iort.value.map(_.flatMap(f)))) + iort.subflatMap(f) should ===(IorT(iort.value.map(_.flatMap(f)))) } } test("semiflatMap consistent with value.flatMap+f+right/both") { forAll { (iort: IorT[List, String, Int], f: Int => List[Long]) => - iort.semiflatMap(f) should === (IorT(iort.value.flatMap { + iort.semiflatMap(f) should ===(IorT(iort.value.flatMap { case l @ Ior.Left(_) => List(l.asInstanceOf[Ior[String, Long]]) - case Ior.Right(b) => f(b).map(Ior.right) - case Ior.Both(a, b) => f(b).map(Ior.both(a, _)) + case Ior.Right(b) => f(b).map(Ior.right) + case Ior.Both(a, b) => f(b).map(Ior.both(a, _)) })) } } test("IorT.left with Option isLeft") { forAll { (option: Option[String]) => - IorT.left[Int](option).isLeft should === (option.map(_ => true)) + IorT.left[Int](option).isLeft should ===(option.map(_ => true)) } } test("IorT.leftT isLeft") { forAll { (s: String) => - IorT.leftT[Option, Int](s).isLeft should === (Some(true)) + IorT.leftT[Option, Int](s).isLeft should ===(Some(true)) } } test("IorT.right with Option isRight") { forAll { (option: Option[Int]) => - IorT.right[String](option).isRight should === (option.map(_ => true)) + IorT.right[String](option).isRight should ===(option.map(_ => true)) } } test("IorT.rightT consistent with IorT.pure") { forAll { (i: Int) => - IorT.rightT[Option, String](i).value should === (IorT.pure[Option, String](i).value) + IorT.rightT[Option, String](i).value should ===(IorT.pure[Option, String](i).value) } } test("IorT.both isBoth with Option consistent with Option zip") { forAll { (optionS: Option[String], optionI: Option[Int]) => - IorT.both(optionS, optionI).isBoth should === (optionS.zip(optionI).headOption.map(_ => true)) + IorT.both(optionS, optionI).isBoth should ===(optionS.zip(optionI).headOption.map(_ => true)) } } test("IorT.bothT isBoth") { forAll { (s: String, i: Int) => - IorT.bothT[Option](s, i).isBoth should === (Some(true)) + IorT.bothT[Option](s, i).isBoth should ===(Some(true)) } } test("IorT.pure isRight") { forAll { (i: Int) => - IorT.rightT[Option, String](i).isRight should === (Some(true)) + IorT.rightT[Option, String](i).isRight should ===(Some(true)) } } test("IorT.liftF consistent with IorT.right") { forAll { (option: Option[Int]) => - IorT.liftF[Option, String, Int](option).value should === (IorT.right[String](option).value) + IorT.liftF[Option, String, Int](option).value should ===(IorT.right[String](option).value) } } test("IorT.fromIor with Id is noop") { forAll { (ior: Ior[String, Int]) => - IorT.fromIor[Id](ior).value should === (ior) + IorT.fromIor[Id](ior).value should ===(ior) } } test("IorT.fromEither toEither is noop") { forAll { (either: Either[String, Int]) => - IorT.fromEither[Id](either).value.toEither should === (either) + IorT.fromEither[Id](either).value.toEither should ===(either) } } test("IorT.fromEitherF toEither is noop") { forAll { (either: Either[String, Int]) => - IorT.fromEitherF[Id, String, Int](either).value.toEither should === (either) + IorT.fromEitherF[Id, String, Int](either).value.toEither should ===(either) } } test("IorT.fromOption isLeft consistent with Option isEmpty") { forAll { (option: Option[Int], s: String) => - IorT.fromOption[Id](option, s).isLeft should === (option.isEmpty) + IorT.fromOption[Id](option, s).isLeft should ===(option.isEmpty) } } test("IorT.fromOptionF isLeft consistent with Option isEmpty") { forAll { (option: Option[Int], s: String) => - IorT.fromOptionF[Id, String, Int](option, s).isLeft should === (option.isEmpty) + IorT.fromOptionF[Id, String, Int](option, s).isLeft should ===(option.isEmpty) } } test("IorT.cond isRight equals test") { forAll { (test: Boolean, s: String, i: Int) => val iort = IorT.cond[Id](test, s, i) - iort.isRight && !iort.isLeft && !iort.isBoth should === (test) + iort.isRight && !iort.isLeft && !iort.isBoth should ===(test) } } diff --git a/tests/src/test/scala/cats/tests/KernelContravariantSuite.scala b/tests/src/test/scala/cats/tests/KernelContravariantSuite.scala index 39bf7071986..0619e7d5d25 100644 --- a/tests/src/test/scala/cats/tests/KernelContravariantSuite.scala +++ b/tests/src/test/scala/cats/tests/KernelContravariantSuite.scala @@ -1,7 +1,6 @@ package cats package tests - import cats.laws.discipline.arbitrary._ import cats.laws.discipline._ import cats.laws.discipline.eq._ diff --git a/tests/src/test/scala/cats/tests/KleisliSuite.scala b/tests/src/test/scala/cats/tests/KleisliSuite.scala index bf4f9cfd82c..71f9600fcfd 100644 --- a/tests/src/test/scala/cats/tests/KleisliSuite.scala +++ b/tests/src/test/scala/cats/tests/KleisliSuite.scala @@ -9,7 +9,7 @@ import cats.laws.discipline.arbitrary._ import cats.laws.discipline.eq._ import org.scalacheck.Arbitrary import cats.kernel.laws.discipline.{MonoidTests, SemigroupTests} -import cats.laws.discipline.{MonoidKTests, DeferTests, SemigroupKTests} +import cats.laws.discipline.{DeferTests, MonoidKTests, SemigroupKTests} import Helpers.CSemi import catalysts.Platform @@ -27,26 +27,34 @@ class KleisliSuite extends CatsSuite { implicit val iso2 = SemigroupalTests.Isomorphisms.invariant[Reader[Int, ?]] { - implicit val instance: ApplicativeError[Kleisli[Option, Int, ?], Unit] = Kleisli.catsDataApplicativeErrorForKleisli[Option, Unit, Int](cats.instances.option.catsStdInstancesForOption) - checkAll("Kleisli[Option, Int, Int] with Unit", ApplicativeErrorTests[Kleisli[Option, Int, ?], Unit](instance).applicativeError[Int, Int, Int]) + implicit val instance: ApplicativeError[Kleisli[Option, Int, ?], Unit] = + Kleisli.catsDataApplicativeErrorForKleisli[Option, Unit, Int](cats.instances.option.catsStdInstancesForOption) + checkAll("Kleisli[Option, Int, Int] with Unit", + ApplicativeErrorTests[Kleisli[Option, Int, ?], Unit](instance).applicativeError[Int, Int, Int]) checkAll("ApplicativeError[Kleisli[Option, Int, Int], Unit]", SerializableTests.serializable(instance)) } checkAll("Kleisli[Eval, Int, ?]", DeferTests[Kleisli[Eval, Int, ?]].defer[Int]) - checkAll("Kleisli[Option, Int, Int] with Unit", MonadErrorTests[Kleisli[Option, Int, ?], Unit].monadError[Int, Int, Int]) - checkAll("MonadError[Kleisli[Option, Int, Int], Unit]", SerializableTests.serializable(MonadError[Kleisli[Option, Int, ?], Unit])) + checkAll("Kleisli[Option, Int, Int] with Unit", + MonadErrorTests[Kleisli[Option, Int, ?], Unit].monadError[Int, Int, Int]) + checkAll("MonadError[Kleisli[Option, Int, Int], Unit]", + SerializableTests.serializable(MonadError[Kleisli[Option, Int, ?], Unit])) checkAll("Kleisli[Option, Int, Int]", SemigroupalTests[Kleisli[Option, Int, ?]].semigroupal[Int, Int, Int]) checkAll("Semigroupal[Kleisli[Option, Int, ?]]", SerializableTests.serializable(Semigroupal[Kleisli[Option, Int, ?]])) - checkAll("Kleisli[(CSemi, ?), Int, ?]", CommutativeFlatMapTests[Kleisli[(CSemi, ?), Int, ?]].commutativeFlatMap[Int, Int, Int]) - checkAll("CommutativeFlatMap[Kleisli[(CSemi, ?), Int, ?]]",SerializableTests.serializable(CommutativeFlatMap[Kleisli[(CSemi, ?), Int, ?]])) + checkAll("Kleisli[(CSemi, ?), Int, ?]", + CommutativeFlatMapTests[Kleisli[(CSemi, ?), Int, ?]].commutativeFlatMap[Int, Int, Int]) + checkAll("CommutativeFlatMap[Kleisli[(CSemi, ?), Int, ?]]", + SerializableTests.serializable(CommutativeFlatMap[Kleisli[(CSemi, ?), Int, ?]])) checkAll("Kleisli[Option, Int, ?]", CommutativeMonadTests[Kleisli[Option, Int, ?]].commutativeMonad[Int, Int, Int]) - checkAll("CommutativeMonad[Kleisli[Option, Int, ?]]",SerializableTests.serializable(CommutativeMonad[Kleisli[Option, Int, ?]])) + checkAll("CommutativeMonad[Kleisli[Option, Int, ?]]", + SerializableTests.serializable(CommutativeMonad[Kleisli[Option, Int, ?]])) checkAll("Kleisli[Id, Int, ?]", CommutativeMonadTests[Kleisli[Id, Int, ?]].commutativeMonad[Int, Int, Int]) - checkAll("CommutativeMonad[Kleisli[Id, Int, ?]]",SerializableTests.serializable(CommutativeMonad[Kleisli[Id, Int, ?]])) + checkAll("CommutativeMonad[Kleisli[Id, Int, ?]]", + SerializableTests.serializable(CommutativeMonad[Kleisli[Id, Int, ?]])) { implicit val catsDataArrowForKleisli = Kleisli.catsDataArrowChoiceForKleisli[List] @@ -62,8 +70,10 @@ class KleisliSuite extends CatsSuite { { implicit val catsDataCommutativeArrowForKleisli = Kleisli.catsDataCommutativeArrowForKleisli[Option] - checkAll("Kleisli[Option, Int, Int]", CommutativeArrowTests[Kleisli[Option, ?, ?]].commutativeArrow[Int, Int, Int, Int, Int, Int]) - checkAll("CommutativeArrow[Kleisli[Option, ?, ?]]", SerializableTests.serializable(CommutativeArrow[Kleisli[Option, ?, ?]])) + checkAll("Kleisli[Option, Int, Int]", + CommutativeArrowTests[Kleisli[Option, ?, ?]].commutativeArrow[Int, Int, Int, Int, Int, Int]) + checkAll("CommutativeArrow[Kleisli[Option, ?, ?]]", + SerializableTests.serializable(CommutativeArrow[Kleisli[Option, ?, ?]])) } { @@ -99,21 +109,24 @@ class KleisliSuite extends CatsSuite { { implicit val catsDataAlternativeForKleisli = Kleisli.catsDataAlternativeForKleisli[Option, Int] checkAll("Kleisli[Option, Int, Int]", AlternativeTests[Kleisli[Option, Int, ?]].alternative[Int, Int, Int]) - checkAll("Alternative[Kleisli[Option, Int, ?]]", SerializableTests.serializable(Alternative[Kleisli[Option, Int, ?]])) + checkAll("Alternative[Kleisli[Option, Int, ?]]", + SerializableTests.serializable(Alternative[Kleisli[Option, Int, ?]])) } { - implicit val catsDataContravariantMonoidalForKleisli = Kleisli.catsDataContravariantMonoidalForKleisli[Const[String, ?], Int] + implicit val catsDataContravariantMonoidalForKleisli = + Kleisli.catsDataContravariantMonoidalForKleisli[Const[String, ?], Int] checkAll("Kleisli[Const[String, ?], Int, Int]", - ContravariantMonoidalTests[Kleisli[Const[String, ?], Int, ?]].contravariantMonoidal[Int, Int, Int]) + ContravariantMonoidalTests[Kleisli[Const[String, ?], Int, ?]].contravariantMonoidal[Int, Int, Int]) checkAll("ContravariantMonoidal[Kleisli[Option, Int, ?]]", - SerializableTests.serializable(ContravariantMonoidal[Kleisli[Const[String, ?], Int, ?]])) + SerializableTests.serializable(ContravariantMonoidal[Kleisli[Const[String, ?], 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, ?]])) + checkAll("Applicative[Kleisli[Option, Int, ?]]", + SerializableTests.serializable(Applicative[Kleisli[Option, Int, ?]])) } { @@ -129,8 +142,10 @@ class KleisliSuite extends CatsSuite { } { - checkAll("Kleisli[Function0, Int, ?]", DistributiveTests[Kleisli[Function0, Int, ?]].distributive[Int, Int, Int, Option, Id]) - checkAll("Distributive[Kleisli[Function0, Int, ?]]", SerializableTests.serializable(Distributive[Kleisli[Function0, Int, ?]])) + checkAll("Kleisli[Function0, Int, ?]", + DistributiveTests[Kleisli[Function0, Int, ?]].distributive[Int, Int, Int, Option, Id]) + checkAll("Distributive[Kleisli[Function0, Int, ?]]", + SerializableTests.serializable(Distributive[Kleisli[Function0, Int, ?]])) } { @@ -172,96 +187,103 @@ class KleisliSuite extends CatsSuite { checkAll("Reader[Int, Int]", FunctorTests[Reader[Int, ?]].functor[Int, Int, Int]) checkAll("Kleisli[Option, ?, Int]", ContravariantTests[Kleisli[Option, ?, Int]].contravariant[Int, Int, Int]) - checkAll("Contravariant[Kleisli[Option, ?, Int]]", SerializableTests.serializable(Contravariant[Kleisli[Option, ?, Int]])) + checkAll("Contravariant[Kleisli[Option, ?, Int]]", + SerializableTests.serializable(Contravariant[Kleisli[Option, ?, Int]])) test("local composes functions") { forAll { (f: Int => Option[String], g: Int => Int, i: Int) => - f(g(i)) should === (Kleisli.local[Option, String, Int](g)(Kleisli(f)).run(i)) + f(g(i)) should ===(Kleisli.local[Option, String, Int](g)(Kleisli(f)).run(i)) } } test("pure consistent with ask") { forAll { (i: Int) => - Kleisli.pure[Option, Int, Int](i).run(i) should === (Kleisli.ask[Option, Int].run(i)) + Kleisli.pure[Option, Int, Int](i).run(i) should ===(Kleisli.ask[Option, Int].run(i)) } } test("mapF") { forAll { (f: Kleisli[List, Int, Int], t: List[Int] => List[Int], i: Int) => - t(f.run(i)) should === (f.mapF(t).run(i)) + t(f.run(i)) should ===(f.mapF(t).run(i)) } } test("mapK") { val t: List ~> Option = λ[List ~> Option](_.headOption) forAll { (f: Kleisli[List, Int, Int], i: Int) => - t(f.run(i)) should === (f.mapK(t).run(i)) + t(f.run(i)) should ===(f.mapK(t).run(i)) } } test("flatMapF") { forAll { (f: Kleisli[List, Int, Int], t: Int => List[Int], i: Int) => - f.run(i).flatMap(t) should === (f.flatMapF(t).run(i)) + f.run(i).flatMap(t) should ===(f.flatMapF(t).run(i)) } } test("lower") { forAll { (f: Kleisli[List, Int, Int], i: Int) => - f.run(i) should === (f.lower.run(i).flatten) + f.run(i) should ===(f.lower.run(i).flatten) } } test("tap") { forAll { (f: Kleisli[List, Int, String], i: Int) => - f.run(i).as(i) should === (f.tap.run(i)) + f.run(i).as(i) should ===(f.tap.run(i)) } } test("tapWith") { forAll { (f: Kleisli[List, Int, String], g: (Int, String) => Boolean, i: Int) => - f.run(i).map(s => g(i, s)) should === (f.tapWith(g).run(i)) + f.run(i).map(s => g(i, s)) should ===(f.tapWith(g).run(i)) } } test("toReader") { forAll { (f: Kleisli[List, Int, String], i: Int) => - f.run(i) should === (f.toReader.run(i)) + f.run(i) should ===(f.toReader.run(i)) } } test("tapWithF") { forAll { (f: Kleisli[List, Int, String], g: (Int, String) => List[Boolean], i: Int) => - f.run(i).flatMap(s => g(i, s)) should === (f.tapWithF(g).run(i)) + f.run(i).flatMap(s => g(i, s)) should ===(f.tapWithF(g).run(i)) } } test("apply") { forAll { (f: Kleisli[List, Int, Int], i: Int) => - f.run(i) should === (f(i)) + f.run(i) should ===(f(i)) } } test("traverse") { forAll { (f: Kleisli[List, Int, Int], i: Int) => - f.traverse(Some(i): Option[Int]) should === ((Some(i): Option[Int]).traverse(f(_))) + f.traverse(Some(i): Option[Int]) should ===((Some(i): Option[Int]).traverse(f(_))) } } test("lift") { - val f = Kleisli { (x: Int) => (Some(x + 1): Option[Int]) } + val f = Kleisli { (x: Int) => + (Some(x + 1): Option[Int]) + } val l = f.lift[List] - (List(1, 2, 3) >>= l.run) should === (List(Some(2), Some(3), Some(4))) + (List(1, 2, 3) >>= l.run) should ===(List(Some(2), Some(3), Some(4))) } test("local") { case class Config(i: Int, s: String) - val kint = Kleisli { (x: Int) => Option(x.toDouble) } + val kint = Kleisli { (x: Int) => + Option(x.toDouble) + } val kconfig1 = kint.local[Config](_.i) - val kconfig2 = Kleisli { (c: Config) => Option(c.i.toDouble) } + val kconfig2 = Kleisli { (c: Config) => + Option(c.i.toDouble) + } val config = Config(0, "cats") - kconfig1.run(config) should === (kconfig2.run(config)) + kconfig1.run(config) should ===(kconfig2.run(config)) } test("flatMap is stack safe on repeated left binds when F is") { @@ -283,8 +305,8 @@ class KleisliSuite extends CatsSuite { } /** - * Testing that implicit resolution works. If it compiles, the "test" passes. - */ + * Testing that implicit resolution works. If it compiles, the "test" passes. + */ object ImplicitResolution { // F is List Functor[Kleisli[List, Int, ?]] diff --git a/tests/src/test/scala/cats/tests/ListSuite.scala b/tests/src/test/scala/cats/tests/ListSuite.scala index 1e8ed70e04e..c5301365f1c 100644 --- a/tests/src/test/scala/cats/tests/ListSuite.scala +++ b/tests/src/test/scala/cats/tests/ListSuite.scala @@ -2,7 +2,16 @@ package cats package tests import cats.data.{NonEmptyList, ZipList} -import cats.laws.discipline.{AlternativeTests, CoflatMapTests, CommutativeApplyTests, MonadTests, SemigroupalTests, SerializableTests, TraverseFilterTests, TraverseTests} +import cats.laws.discipline.{ + AlternativeTests, + CoflatMapTests, + CommutativeApplyTests, + MonadTests, + SemigroupalTests, + SerializableTests, + TraverseFilterTests, + TraverseTests +} import cats.laws.discipline.arbitrary._ class ListSuite extends CatsSuite { @@ -25,30 +34,29 @@ class ListSuite extends CatsSuite { checkAll("List[Int]", TraverseFilterTests[List].traverseFilter[Int, Int, Int]) checkAll("TraverseFilter[List]", SerializableTests.serializable(TraverseFilter[List])) - checkAll("ZipList[Int]", CommutativeApplyTests[ZipList].commutativeApply[Int, Int, Int]) test("nel => list => nel returns original nel")( forAll { fa: NonEmptyList[Int] => - fa.toList.toNel should === (Some(fa)) + fa.toList.toNel should ===(Some(fa)) } ) - test("toNel on empty list returns None"){ - List.empty[Int].toNel should === (None) + test("toNel on empty list returns None") { + List.empty[Int].toNel should ===(None) } test("groupByNel should be consistent with groupBy")( forAll { (fa: List[Int], f: Int => Int) => - fa.groupByNel(f).map{ case (k, v) => (k, v.toList)} should === (fa.groupBy(f)) + fa.groupByNel(f).map { case (k, v) => (k, v.toList) } should ===(fa.groupBy(f)) } ) - test("show"){ - List(1, 2, 3).show should === ("List(1, 2, 3)") - (Nil: List[Int]).show should === ("List()") + test("show") { + List(1, 2, 3).show should ===("List(1, 2, 3)") + (Nil: List[Int]).show should ===("List()") forAll { l: List[String] => - l.show should === (l.toString) + l.show should ===(l.toString) } } } diff --git a/tests/src/test/scala/cats/tests/ListWrapper.scala b/tests/src/test/scala/cats/tests/ListWrapper.scala index 2f081d77358..12e2c3fa373 100644 --- a/tests/src/test/scala/cats/tests/ListWrapper.scala +++ b/tests/src/test/scala/cats/tests/ListWrapper.scala @@ -32,15 +32,14 @@ import org.scalacheck.Arbitrary.arbitrary * } * }}} */ - final case class ListWrapper[A](list: List[A]) extends AnyVal object ListWrapper { - def order[A:Order]: Order[ListWrapper[A]] = Order.by(_.list) + def order[A: Order]: Order[ListWrapper[A]] = Order.by(_.list) - def partialOrder[A:PartialOrder]: PartialOrder[ListWrapper[A]] = PartialOrder.by(_.list) + def partialOrder[A: PartialOrder]: PartialOrder[ListWrapper[A]] = PartialOrder.by(_.list) - def eqv[A : Eq]: Eq[ListWrapper[A]] = Eq.by(_.list) + def eqv[A: Eq]: Eq[ListWrapper[A]] = Eq.by(_.list) val traverse: Traverse[ListWrapper] = { val F = Traverse[List] @@ -50,9 +49,8 @@ object ListWrapper { F.foldLeft(fa.list, b)(f) def foldRight[A, B](fa: ListWrapper[A], lb: Eval[B])(f: (A, Eval[B]) => Eval[B]): Eval[B] = F.foldRight(fa.list, lb)(f) - def traverse[G[_], A, B](fa: ListWrapper[A])(f: A => G[B])(implicit G0: Applicative[G]): G[ListWrapper[B]] = { + def traverse[G[_], A, B](fa: ListWrapper[A])(f: A => G[B])(implicit G0: Applicative[G]): G[ListWrapper[B]] = G0.map(F.traverse(fa.list)(f))(ListWrapper.apply) - } } } @@ -61,7 +59,9 @@ object ListWrapper { new TraverseFilter[ListWrapper] { def traverse = ListWrapper.traverse - def traverseFilter[G[_], A, B](fa: ListWrapper[A])(f: A => G[Option[B]])(implicit G: Applicative[G]): G[ListWrapper[B]] = + def traverseFilter[G[_], A, B]( + fa: ListWrapper[A] + )(f: A => G[Option[B]])(implicit G: Applicative[G]): G[ListWrapper[B]] = G.map(F.traverseFilter(fa.list)(f))(ListWrapper.apply) } } @@ -118,9 +118,11 @@ object ListWrapper { val M = Monad[List] def pure[A](x: A): ListWrapper[A] = ListWrapper(x :: Nil) - def flatMap[A, B](fa: ListWrapper[A])(f: (A) => ListWrapper[B]): ListWrapper[B] = ListWrapper(fa.list.flatMap(f(_).list)) + def flatMap[A, B](fa: ListWrapper[A])(f: (A) => ListWrapper[B]): ListWrapper[B] = + ListWrapper(fa.list.flatMap(f(_).list)) - def tailRecM[A, B](a: A)(f: (A) => ListWrapper[Either[A, B]]): ListWrapper[B] = ListWrapper(M.tailRecM(a)(f(_).list)) + def tailRecM[A, B](a: A)(f: (A) => ListWrapper[Either[A, B]]): ListWrapper[B] = + ListWrapper(M.tailRecM(a)(f(_).list)) } val flatMap: FlatMap[ListWrapper] = monad diff --git a/tests/src/test/scala/cats/tests/MapSuite.scala b/tests/src/test/scala/cats/tests/MapSuite.scala index ec9144ae171..efa600c5674 100644 --- a/tests/src/test/scala/cats/tests/MapSuite.scala +++ b/tests/src/test/scala/cats/tests/MapSuite.scala @@ -1,8 +1,14 @@ package cats package tests - -import cats.laws.discipline.{FlatMapTests, FunctorFilterTests, SemigroupalTests, SerializableTests, UnorderedTraverseTests, ComposeTests} +import cats.laws.discipline.{ + ComposeTests, + FlatMapTests, + FunctorFilterTests, + SemigroupalTests, + SerializableTests, + UnorderedTraverseTests +} import cats.laws.discipline.arbitrary._ import cats.arrow.Compose @@ -15,7 +21,8 @@ class MapSuite extends CatsSuite { checkAll("Map[Int, Int]", FlatMapTests[Map[Int, ?]].flatMap[Int, Int, Int]) checkAll("FlatMap[Map[Int, ?]]", SerializableTests.serializable(FlatMap[Map[Int, ?]])) - checkAll("Map[Int, Int] with Option", UnorderedTraverseTests[Map[Int, ?]].unorderedTraverse[Int, Int, Int, Option, Option]) + checkAll("Map[Int, Int] with Option", + UnorderedTraverseTests[Map[Int, ?]].unorderedTraverse[Int, Int, Int, Option, Option]) checkAll("UnorderedTraverse[Map[Int, ?]]", SerializableTests.serializable(UnorderedTraverse[Map[Int, ?]])) checkAll("Map[Int, Int]", FunctorFilterTests[Map[Int, ?]].functorFilter[Int, Int, Int]) @@ -24,13 +31,11 @@ class MapSuite extends CatsSuite { checkAll("Map[Int, Long]", ComposeTests[Map].compose[Int, Long, String, Double]) checkAll("Compose[Map]", SerializableTests.serializable(Compose[Map])) - - test("show isn't empty and is formatted as expected") { forAll { (map: Map[Int, String]) => - map.show.nonEmpty should === (true) - map.show.startsWith("Map(") should === (true) - map.show should === (implicitly[Show[Map[Int, String]]].show(map)) + map.show.nonEmpty should ===(true) + map.show.startsWith("Map(") should ===(true) + map.show should ===(implicitly[Show[Map[Int, String]]].show(map)) } } } diff --git a/tests/src/test/scala/cats/tests/MonadErrorSuite.scala b/tests/src/test/scala/cats/tests/MonadErrorSuite.scala index c607dfe97e8..b989407b72d 100644 --- a/tests/src/test/scala/cats/tests/MonadErrorSuite.scala +++ b/tests/src/test/scala/cats/tests/MonadErrorSuite.scala @@ -13,47 +13,47 @@ class MonadErrorSuite extends CatsSuite { val failed: Try[Int] = Failure(failedValue) test("ensure raises an error if the predicate fails") { - successful.ensure(failedValue)(_ => false) should === (failed) + successful.ensure(failedValue)(_ => false) should ===(failed) } test("ensure returns the successful value if the predicate succeeds") { - successful.ensure(failedValue)(_ => true) should === (successful) + successful.ensure(failedValue)(_ => true) should ===(successful) } test("ensure returns the original failure, when applied to a failure") { - failed.ensure(otherValue)(_ => false) should === (failed) - failed.ensure(otherValue)(_ => true) should === (failed) + failed.ensure(otherValue)(_ => false) should ===(failed) + failed.ensure(otherValue)(_ => true) should ===(failed) } test("ensureOr raises an error if the predicate fails") { - successful.ensureOr(_ => failedValue)(_ => false) should === (failed) + successful.ensureOr(_ => failedValue)(_ => false) should ===(failed) } test("ensureOr returns the successful value if the predicate succeeds") { - successful.ensureOr(_ => failedValue)(_ => true) should === (successful) + successful.ensureOr(_ => failedValue)(_ => true) should ===(successful) } test("ensureOr returns the original failure, when applied to a failure") { - failed.ensureOr(_ => otherValue)(_ => false) should === (failed) - failed.ensureOr(_ => otherValue)(_ => true) should === (failed) + failed.ensureOr(_ => otherValue)(_ => false) should ===(failed) + failed.ensureOr(_ => otherValue)(_ => true) should ===(failed) } test("ensureP returns the successful value if the partial function is not defined") { successful.reject { case i if i < 0 => failedValue - } should === (successful) + } should ===(successful) } test("ensureP returns the original failure, when applied to a failure") { failed.reject { case i if i < 0 => otherValue - } should === (failed) + } should ===(failed) } test("ensureP raises an error if the partial function is defined") { successful.reject { case i if i > 0 => failedValue - } should === (failed) + } should ===(failed) } } diff --git a/tests/src/test/scala/cats/tests/MonadSuite.scala b/tests/src/test/scala/cats/tests/MonadSuite.scala index 25d2b3ac14f..df5bfdadb83 100644 --- a/tests/src/test/scala/cats/tests/MonadSuite.scala +++ b/tests/src/test/scala/cats/tests/MonadSuite.scala @@ -23,7 +23,7 @@ class MonadSuite extends CatsSuite { forAll(smallPosInt) { (max: Int) => val (result, aggregation) = incrementAndGet.whileM[Vector](StateT.inspect(i => !(i >= max))).run(0) result should ===(Math.max(0, max)) - aggregation should === ( if(max > 0) (1 to max).toVector else Vector.empty ) + aggregation should ===(if (max > 0) (1 to max).toVector else Vector.empty) } } @@ -38,7 +38,7 @@ class MonadSuite extends CatsSuite { forAll(smallPosInt) { (max: Int) => val (result, aggregation) = incrementAndGet.untilM[Vector](StateT.inspect(_ >= max)).run(-1) result should ===(max) - aggregation should === ((0 to max).toVector) + aggregation should ===((0 to max).toVector) } } @@ -78,25 +78,25 @@ class MonadSuite extends CatsSuite { test("iterateWhileM") { forAll(smallPosInt) { (max: Int) => - val (n, sum) = 0.iterateWhileM(s => incrementAndGet map (_ + s))(_ < max).run(0) + val (n, sum) = 0.iterateWhileM(s => incrementAndGet.map(_ + s))(_ < max).run(0) sum should ===(n * (n + 1) / 2) } } test("iterateWhileM is stack safe") { - val (n, sum) = 0.iterateWhileM(s => incrementAndGet map (_ + s))(_ < 50000000).run(0) + val (n, sum) = 0.iterateWhileM(s => incrementAndGet.map(_ + s))(_ < 50000000).run(0) sum should ===(n * (n + 1) / 2) } test("iterateUntilM") { forAll(smallPosInt) { (max: Int) => - val (n, sum) = 0.iterateUntilM(s => incrementAndGet map (_ + s))(_ > max).run(0) + val (n, sum) = 0.iterateUntilM(s => incrementAndGet.map(_ + s))(_ > max).run(0) sum should ===(n * (n + 1) / 2) } } test("iterateUntilM is stack safe") { - val (n, sum) = 0.iterateUntilM(s => incrementAndGet map (_ + s))(_ > 50000000).run(0) + val (n, sum) = 0.iterateUntilM(s => incrementAndGet.map(_ + s))(_ > 50000000).run(0) sum should ===(n * (n + 1) / 2) } diff --git a/tests/src/test/scala/cats/tests/MonoidSuite.scala b/tests/src/test/scala/cats/tests/MonoidSuite.scala index 702297b92c1..4eecd0d5b53 100644 --- a/tests/src/test/scala/cats/tests/MonoidSuite.scala +++ b/tests/src/test/scala/cats/tests/MonoidSuite.scala @@ -1,8 +1,6 @@ package cats package tests - - class MonoidSuite extends CatsSuite { { Invariant[Monoid] diff --git a/tests/src/test/scala/cats/tests/NestedSuite.scala b/tests/src/test/scala/cats/tests/NestedSuite.scala index e5b2c25bd2c..a35c4230721 100644 --- a/tests/src/test/scala/cats/tests/NestedSuite.scala +++ b/tests/src/test/scala/cats/tests/NestedSuite.scala @@ -16,13 +16,15 @@ class NestedSuite extends CatsSuite { implicit override val generatorDrivenConfig: PropertyCheckConfiguration = PropertyCheckConfiguration(minSuccessful = 20, sizeRange = 5) - checkAll("Nested[Eval, List, ?]", DeferTests[Nested[Eval, List, ?]].defer[Int]) + checkAll("Nested[Eval, List, ?]", DeferTests[Nested[Eval, List, ?]].defer[Int]) { // Invariant composition implicit val instance = ListWrapper.invariant - checkAll("Nested[ListWrapper, ListWrapper]", InvariantTests[Nested[ListWrapper, ListWrapper, ?]].invariant[Int, Int, Int]) - checkAll("Invariant[Nested[ListWrapper, ListWrapper, ?]]", SerializableTests.serializable(Invariant[Nested[ListWrapper, ListWrapper, ?]])) + checkAll("Nested[ListWrapper, ListWrapper]", + InvariantTests[Nested[ListWrapper, ListWrapper, ?]].invariant[Int, Int, Int]) + checkAll("Invariant[Nested[ListWrapper, ListWrapper, ?]]", + SerializableTests.serializable(Invariant[Nested[ListWrapper, ListWrapper, ?]])) } { @@ -30,9 +32,9 @@ class NestedSuite extends CatsSuite { implicit val instance = ListWrapper.functorFilter implicit val functorInstance = ListWrapper.functor checkAll("Nested[ListWrapper, ListWrapper]", - FunctorFilterTests[Nested[ListWrapper, ListWrapper, ?]].functorFilter[Int, Int, Int]) + FunctorFilterTests[Nested[ListWrapper, ListWrapper, ?]].functorFilter[Int, Int, Int]) checkAll("FunctorFilter[Nested[ListWrapper, ListWrapper, ?]]", - SerializableTests.serializable(FunctorFilter[Nested[ListWrapper, ListWrapper, ?]])) + SerializableTests.serializable(FunctorFilter[Nested[ListWrapper, ListWrapper, ?]])) } { @@ -40,22 +42,25 @@ class NestedSuite extends CatsSuite { implicit val instance = ListWrapper.traverseFilter implicit val traverseInstance = ListWrapper.traverse checkAll("Nested[ListWrapper, ListWrapper]", - TraverseFilterTests[Nested[ListWrapper, ListWrapper, ?]].traverseFilter[Int, Int, Int]) + TraverseFilterTests[Nested[ListWrapper, ListWrapper, ?]].traverseFilter[Int, Int, Int]) checkAll("TraverseFilter[Nested[ListWrapper, ListWrapper, ?]]", - SerializableTests.serializable(TraverseFilter[Nested[ListWrapper, ListWrapper, ?]])) + SerializableTests.serializable(TraverseFilter[Nested[ListWrapper, ListWrapper, ?]])) } { // Invariant + Covariant = Invariant val instance = Nested.catsDataInvariantForCovariantNested(ListWrapper.invariant, ListWrapper.functor) - checkAll("Nested[ListWrapper, ListWrapper] - Invariant + Covariant", InvariantTests[Nested[ListWrapper, ListWrapper, ?]](instance).invariant[Int, Int, Int]) - checkAll("Invariant[Nested[ListWrapper, ListWrapper, ?]] - Invariant + Covariant", SerializableTests.serializable(instance)) + checkAll("Nested[ListWrapper, ListWrapper] - Invariant + Covariant", + InvariantTests[Nested[ListWrapper, ListWrapper, ?]](instance).invariant[Int, Int, Int]) + checkAll("Invariant[Nested[ListWrapper, ListWrapper, ?]] - Invariant + Covariant", + SerializableTests.serializable(instance)) } { // Invariant + Contravariant = Invariant val instance = Nested.catsDataInvariantForNestedContravariant(ListWrapper.invariant, Contravariant[Show]) - checkAll("Nested[ListWrapper, Show]", InvariantTests[Nested[ListWrapper, Show, ?]](instance).invariant[Int, Int, Int]) + checkAll("Nested[ListWrapper, Show]", + InvariantTests[Nested[ListWrapper, Show, ?]](instance).invariant[Int, Int, Int]) checkAll("Invariant[Nested[ListWrapper, Show, ?]]", SerializableTests.serializable(instance)) } @@ -63,43 +68,47 @@ class NestedSuite extends CatsSuite { // Functor composition implicit val instance = ListWrapper.functor checkAll("Nested[Option, ListWrapper, ?]", FunctorTests[Nested[Option, ListWrapper, ?]].functor[Int, Int, Int]) - checkAll("Functor[Nested[Option, ListWrapper, ?]]", SerializableTests.serializable(Functor[Nested[Option, ListWrapper, ?]])) + checkAll("Functor[Nested[Option, ListWrapper, ?]]", + SerializableTests.serializable(Functor[Nested[Option, ListWrapper, ?]])) } { // Covariant + contravariant functor composition checkAll("Nested[Option, Show, ?]", ContravariantTests[Nested[Option, Show, ?]].contravariant[Int, Int, Int]) - checkAll("Contravariant[Nested[Option, Show, ?]]", SerializableTests.serializable(Contravariant[Nested[Option, Show, ?]])) + checkAll("Contravariant[Nested[Option, Show, ?]]", + SerializableTests.serializable(Contravariant[Nested[Option, Show, ?]])) } { // InvariantSemigroupal + Apply functor composition implicit val instance = ListWrapper.invariantSemigroupal checkAll("Nested[ListWrapper, Option, ?]", - InvariantSemigroupalTests[Nested[ListWrapper, Option, ?]].invariantSemigroupal[Int, Int, Int]) + InvariantSemigroupalTests[Nested[ListWrapper, Option, ?]].invariantSemigroupal[Int, Int, Int]) checkAll("InvariantSemigroupal[Nested[ListWrapper, Const[String, ?], ?]", - SerializableTests.serializable(InvariantSemigroupal[Nested[ListWrapper, Option, ?]])) + SerializableTests.serializable(InvariantSemigroupal[Nested[ListWrapper, Option, ?]])) } { // Applicative + ContravariantMonoidal functor composition checkAll("Nested[Option, Const[String, ?], ?]", - ContravariantMonoidalTests[Nested[Option, Const[String, ?], ?]].contravariantMonoidal[Int, Int, Int]) + ContravariantMonoidalTests[Nested[Option, Const[String, ?], ?]].contravariantMonoidal[Int, Int, Int]) checkAll("ContravariantMonoidal[Nested[Option, Const[String, ?], ?]", - SerializableTests.serializable(ContravariantMonoidal[Nested[Option, Const[String, ?], ?]])) + SerializableTests.serializable(ContravariantMonoidal[Nested[Option, Const[String, ?], ?]])) } { // Contravariant + Contravariant = Functor type ConstInt[A] = Const[Int, A] checkAll("Nested[Const[Int, ?], Show, ?]", FunctorTests[Nested[ConstInt, Show, ?]].functor[Int, Int, Int]) - checkAll("Functor[Nested[Const[Int, ?], Show, ?]]", SerializableTests.serializable(Functor[Nested[ConstInt, Show, ?]])) + checkAll("Functor[Nested[Const[Int, ?], Show, ?]]", + SerializableTests.serializable(Functor[Nested[ConstInt, Show, ?]])) } { // Contravariant + Functor = Contravariant checkAll("Nested[Show, Option, ?]", ContravariantTests[Nested[Show, Option, ?]].contravariant[Int, Int, Int]) - checkAll("Contravariant[Nested[Show, Option, ?]]", SerializableTests.serializable(Contravariant[Nested[Show, Option, ?]])) + checkAll("Contravariant[Nested[Show, Option, ?]]", + SerializableTests.serializable(Contravariant[Nested[Show, Option, ?]])) } { @@ -113,84 +122,110 @@ class NestedSuite extends CatsSuite { // CommutativeApply composition implicit val optionApply = Apply[Option] implicit val validatedApply = Apply[Validated[Int, ?]] - checkAll("Nested[Option, Validated[Int, ?], ?]", CommutativeApplyTests[Nested[Option, Validated[Int, ?], ?]].commutativeApply[Int, Int, Int]) - checkAll("CommutativeApply[Nested[Option, Validated[Int, ?], ?], ?]]", SerializableTests.serializable(CommutativeApply[Nested[Option, Validated[Int, ?], ?]])) + checkAll("Nested[Option, Validated[Int, ?], ?]", + CommutativeApplyTests[Nested[Option, Validated[Int, ?], ?]].commutativeApply[Int, Int, Int]) + checkAll("CommutativeApply[Nested[Option, Validated[Int, ?], ?], ?]]", + SerializableTests.serializable(CommutativeApply[Nested[Option, Validated[Int, ?], ?]])) } { // Applicative composition implicit val instance = ListWrapper.applicative checkAll("Nested[List, ListWrapper, ?]", ApplicativeTests[Nested[List, ListWrapper, ?]].applicative[Int, Int, Int]) - checkAll("Applicative[Nested[List, ListWrapper, ?]]", SerializableTests.serializable(Applicative[Nested[List, ListWrapper, ?]])) + checkAll("Applicative[Nested[List, ListWrapper, ?]]", + SerializableTests.serializable(Applicative[Nested[List, ListWrapper, ?]])) } { // CommutativeApplicative composition implicit val instance = ListWrapper.applicative - checkAll("Nested[Option, Validated[Int, ?], ?]", CommutativeApplicativeTests[Nested[Option, Validated[Int, ?], ?]].commutativeApplicative[Int, Int, Int]) - checkAll("CommutativeApplicative[Nested[List, ListWrapper, ?]]", SerializableTests.serializable(CommutativeApplicative[Nested[Option, Validated[Int, ?], ?]])) + checkAll("Nested[Option, Validated[Int, ?], ?]", + CommutativeApplicativeTests[Nested[Option, Validated[Int, ?], ?]].commutativeApplicative[Int, Int, Int]) + checkAll("CommutativeApplicative[Nested[List, ListWrapper, ?]]", + SerializableTests.serializable(CommutativeApplicative[Nested[Option, Validated[Int, ?], ?]])) } { //ApplicativeError composition implicit val instance = ListWrapper.applicative - checkAll("Nested[Validated[String, ?], ListWrapper, ?]", ApplicativeErrorTests[Nested[Validated[String, ?], ListWrapper, ?], String].applicativeError[Int, Int, Int]) - checkAll("ApplicativeError[Nested[Validated[String, ?], ListWrapper, ?]]", SerializableTests.serializable(ApplicativeError[Nested[Validated[String, ?], ListWrapper, ?], String])) + checkAll( + "Nested[Validated[String, ?], ListWrapper, ?]", + ApplicativeErrorTests[Nested[Validated[String, ?], ListWrapper, ?], String].applicativeError[Int, Int, Int] + ) + checkAll( + "ApplicativeError[Nested[Validated[String, ?], ListWrapper, ?]]", + SerializableTests.serializable(ApplicativeError[Nested[Validated[String, ?], ListWrapper, ?], String]) + ) } { // Alternative composition implicit val instance = ListWrapper.alternative checkAll("Nested[List, ListWrapper, ?]", AlternativeTests[Nested[List, ListWrapper, ?]].alternative[Int, Int, Int]) - checkAll("Alternative[Nested[List, ListWrapper, ?]]", SerializableTests.serializable(Alternative[Nested[List, ListWrapper, ?]])) + checkAll("Alternative[Nested[List, ListWrapper, ?]]", + SerializableTests.serializable(Alternative[Nested[List, ListWrapper, ?]])) } { // Foldable composition implicit val instance = ListWrapper.foldable checkAll("Nested[List, ListWrapper, ?]", FoldableTests[Nested[List, ListWrapper, ?]].foldable[Int, Int]) - checkAll("Foldable[Nested[List, ListWrapper, ?]]", SerializableTests.serializable(Foldable[Nested[List, ListWrapper, ?]])) + checkAll("Foldable[Nested[List, ListWrapper, ?]]", + SerializableTests.serializable(Foldable[Nested[List, ListWrapper, ?]])) } { // Traverse composition implicit val instance = ListWrapper.traverse - checkAll("Nested[List, ListWrapper, ?]", TraverseTests[Nested[List, ListWrapper, ?]].traverse[Int, Int, Int, Set[Int], Option, Option]) - checkAll("Traverse[Nested[List, ListWrapper, ?]]", SerializableTests.serializable(Traverse[Nested[List, ListWrapper, ?]])) + checkAll("Nested[List, ListWrapper, ?]", + TraverseTests[Nested[List, ListWrapper, ?]].traverse[Int, Int, Int, Set[Int], Option, Option]) + checkAll("Traverse[Nested[List, ListWrapper, ?]]", + SerializableTests.serializable(Traverse[Nested[List, ListWrapper, ?]])) } { // Reducible composition implicit val instance = ListWrapper.foldable - checkAll("Nested[NonEmptyList, OneAnd[ListWrapper, ?], ?]", ReducibleTests[Nested[NonEmptyList, OneAnd[ListWrapper, ?], ?]].reducible[Option, Int, Int]) - checkAll("Reducible[Nested[NonEmptyList, OneAnd[ListWrapper, ?], ?]]", SerializableTests.serializable(Reducible[Nested[NonEmptyList, OneAnd[ListWrapper, ?], ?]])) + checkAll("Nested[NonEmptyList, OneAnd[ListWrapper, ?], ?]", + ReducibleTests[Nested[NonEmptyList, OneAnd[ListWrapper, ?], ?]].reducible[Option, Int, Int]) + checkAll("Reducible[Nested[NonEmptyList, OneAnd[ListWrapper, ?], ?]]", + SerializableTests.serializable(Reducible[Nested[NonEmptyList, OneAnd[ListWrapper, ?], ?]])) } { //NonEmptyTraverse composition - checkAll("Nested[NonEmptyList, NonEmptyVector, ?]", NonEmptyTraverseTests[Nested[NonEmptyList, NonEmptyVector, ?]].nonEmptyTraverse[Option, Int, Int, Int, Int, Option, Option]) - checkAll("NonEmptyTraverse[Nested[NonEmptyList, NonEmptyVector, ?]]", SerializableTests.serializable(NonEmptyTraverse[Nested[NonEmptyList, NonEmptyVector, ?]])) + checkAll( + "Nested[NonEmptyList, NonEmptyVector, ?]", + NonEmptyTraverseTests[Nested[NonEmptyList, NonEmptyVector, ?]] + .nonEmptyTraverse[Option, Int, Int, Int, Int, Option, Option] + ) + checkAll("NonEmptyTraverse[Nested[NonEmptyList, NonEmptyVector, ?]]", + SerializableTests.serializable(NonEmptyTraverse[Nested[NonEmptyList, NonEmptyVector, ?]])) } { // SemigroupK composition implicit val instance = ListWrapper.semigroupK checkAll("Nested[ListWrapper, Option, ?]", SemigroupKTests[Nested[ListWrapper, Option, ?]].semigroupK[Int]) - checkAll("SemigroupK[Nested[ListWrapper, Option, ?]]", SerializableTests.serializable(SemigroupK[Nested[ListWrapper, Option, ?]])) + checkAll("SemigroupK[Nested[ListWrapper, Option, ?]]", + SerializableTests.serializable(SemigroupK[Nested[ListWrapper, Option, ?]])) } { // MonoidK composition implicit val instance = ListWrapper.monoidK checkAll("Nested[ListWrapper, Option, ?]", MonoidKTests[Nested[ListWrapper, Option, ?]].monoidK[Int]) - checkAll("MonoidK[Nested[ListWrapper, Option, ?]]", SerializableTests.serializable(MonoidK[Nested[ListWrapper, Option, ?]])) + checkAll("MonoidK[Nested[ListWrapper, Option, ?]]", + SerializableTests.serializable(MonoidK[Nested[ListWrapper, Option, ?]])) } { import cats.laws.discipline.eq._ //Distributive composition - checkAll("Nested[Function1[Int, ?], Function0, ?]", DistributiveTests[Nested[Function1[Int, ?], Function0, ?]].distributive[Int, Int, Int, Option, Function0]) - checkAll("Distributive[Nested[Function1[Int,?], Function0, ?]]", SerializableTests.serializable(Distributive[Nested[Function1[Int,?], Function0, ?]])) + checkAll("Nested[Function1[Int, ?], Function0, ?]", + DistributiveTests[Nested[Function1[Int, ?], Function0, ?]].distributive[Int, Int, Int, Option, Function0]) + checkAll("Distributive[Nested[Function1[Int,?], Function0, ?]]", + SerializableTests.serializable(Distributive[Nested[Function1[Int, ?], Function0, ?]])) } } diff --git a/tests/src/test/scala/cats/tests/NonEmptyChainSuite.scala b/tests/src/test/scala/cats/tests/NonEmptyChainSuite.scala index 77e26a9d358..640db1db2a2 100644 --- a/tests/src/test/scala/cats/tests/NonEmptyChainSuite.scala +++ b/tests/src/test/scala/cats/tests/NonEmptyChainSuite.scala @@ -10,7 +10,8 @@ class NonEmptyChainSuite extends CatsSuite { checkAll("NonEmptyChain[Int]", SemigroupKTests[NonEmptyChain].semigroupK[Int]) checkAll("SemigroupK[NonEmptyChain]", SerializableTests.serializable(SemigroupK[NonEmptyChain])) - checkAll("NonEmptyChain[Int] with Option", NonEmptyTraverseTests[NonEmptyChain].nonEmptyTraverse[Option, Int, Int, Int, Int, Option, Option]) + checkAll("NonEmptyChain[Int] with Option", + NonEmptyTraverseTests[NonEmptyChain].nonEmptyTraverse[Option, Int, Int, Int, Int, Option, Option]) checkAll("NonEmptyTraverse[NonEmptyChain]", SerializableTests.serializable(Traverse[NonEmptyChain])) checkAll("NonEmptyChain[Int]", BimonadTests[NonEmptyChain].bimonad[Int, Int, Int]) @@ -24,115 +25,112 @@ class NonEmptyChainSuite extends CatsSuite { { implicit val partialOrder = ListWrapper.partialOrder[Int] - checkAll("NonEmptyChain[ListWrapper[Int]]", - PartialOrderTests[NonEmptyChain[ListWrapper[Int]]].partialOrder) + checkAll("NonEmptyChain[ListWrapper[Int]]", PartialOrderTests[NonEmptyChain[ListWrapper[Int]]].partialOrder) checkAll("PartialOrder[NonEmptyChain[ListWrapper[Int]]", - SerializableTests.serializable(PartialOrder[NonEmptyChain[ListWrapper[Int]]])) + SerializableTests.serializable(PartialOrder[NonEmptyChain[ListWrapper[Int]]])) } { implicit val eqv = ListWrapper.eqv[Int] - checkAll("NonEmptyChain[ListWrapper[Int]]", - EqTests[NonEmptyChain[ListWrapper[Int]]].eqv) - checkAll("Eq[NonEmptyChain[ListWrapper[Int]]", - SerializableTests.serializable(Eq[NonEmptyChain[ListWrapper[Int]]])) + checkAll("NonEmptyChain[ListWrapper[Int]]", EqTests[NonEmptyChain[ListWrapper[Int]]].eqv) + checkAll("Eq[NonEmptyChain[ListWrapper[Int]]", SerializableTests.serializable(Eq[NonEmptyChain[ListWrapper[Int]]])) } - test("show"){ - Show[NonEmptyChain[Int]].show(NonEmptyChain(1, 2, 3)) should === ("NonEmptyChain(1, 2, 3)") + test("show") { + Show[NonEmptyChain[Int]].show(NonEmptyChain(1, 2, 3)) should ===("NonEmptyChain(1, 2, 3)") } test("size is consistent with toChain.size") { forAll { (ci: NonEmptyChain[Int]) => - ci.size should === (ci.toChain.size) + ci.size should ===(ci.toChain.size) } } test("filterNot and then exists should always be false") { forAll { (ci: NonEmptyChain[Int], f: Int => Boolean) => - ci.filterNot(f).exists(f) should === (false) + ci.filterNot(f).exists(f) should ===(false) } } test("filter and then forall should always be true") { forAll { (ci: NonEmptyChain[Int], f: Int => Boolean) => - ci.filter(f).forall(f) should === (true) + ci.filter(f).forall(f) should ===(true) } } test("exists should be consistent with find + isDefined") { forAll { (ci: NonEmptyChain[Int], f: Int => Boolean) => - ci.exists(f) should === (ci.find(f).isDefined) + ci.exists(f) should ===(ci.find(f).isDefined) } } test("deleteFirst consistent with find") { forAll { (ci: NonEmptyChain[Int], f: Int => Boolean) => - ci.find(f) should === (ci.deleteFirst(f).map(_._1)) + ci.find(f) should ===(ci.deleteFirst(f).map(_._1)) } } test("filterNot element and then contains should be false") { forAll { (ci: NonEmptyChain[Int], i: Int) => - ci.filterNot(_ === i).contains(i) should === (false) + ci.filterNot(_ === i).contains(i) should ===(false) } } test("Always nonempty after cons") { forAll { (ci: NonEmptyChain[Int], i: Int) => - (i +: ci).nonEmpty should === (true) + (i +: ci).nonEmpty should ===(true) } } test("fromNonEmptyVector . toNonEmptyVector is id") { forAll { (ci: NonEmptyChain[Int]) => - NonEmptyChain.fromNonEmptyVector(ci.toNonEmptyVector) should === (ci) + NonEmptyChain.fromNonEmptyVector(ci.toNonEmptyVector) should ===(ci) } } test("fromNonEmptyList . toNonEmptyList is id") { forAll { (ci: NonEmptyChain[Int]) => - NonEmptyChain.fromNonEmptyList(ci.toNonEmptyList) should === (ci) + NonEmptyChain.fromNonEmptyList(ci.toNonEmptyList) should ===(ci) } } test("fromChain . toChain is Option.some") { forAll { (ci: NonEmptyChain[Int]) => - NonEmptyChain.fromChain(ci.toChain) should === (Some(ci)) + NonEmptyChain.fromChain(ci.toChain) should ===(Some(ci)) } } test("fromChainUnsafe throws exception when used with empty chain") { - Either.catchNonFatal(NonEmptyChain.fromChainUnsafe(Chain.empty[Int])).isLeft should === (true) + Either.catchNonFatal(NonEmptyChain.fromChainUnsafe(Chain.empty[Int])).isLeft should ===(true) } test("fromSeq . toList . iterator is id") { forAll { (ci: NonEmptyChain[Int]) => - NonEmptyChain.fromSeq(ci.iterator.toList) should === (Option(ci)) + NonEmptyChain.fromSeq(ci.iterator.toList) should ===(Option(ci)) } } test("zipWith consistent with List#zip and then List#map") { forAll { (a: NonEmptyChain[String], b: NonEmptyChain[Int], f: (String, Int) => Int) => - a.zipWith(b)(f).toList should === (a.toList.zip(b.toList).map { case (x, y) => f(x, y) }) + a.zipWith(b)(f).toList should ===(a.toList.zip(b.toList).map { case (x, y) => f(x, y) }) } } test("groupBy consistent with List#groupBy") { forAll { (cs: NonEmptyChain[String], f: String => Int) => - cs.groupBy(f).map(_.toNonEmptyList) should === (cs.toNonEmptyList.groupByNem(f)) + cs.groupBy(f).map(_.toNonEmptyList) should ===(cs.toNonEmptyList.groupByNem(f)) } } test("reverse . reverse is id") { forAll { (ci: NonEmptyChain[Int]) => - ci.reverse.reverse should === (ci) + ci.reverse.reverse should ===(ci) } } test("reverse consistent with Chain#reverse") { forAll { (ci: NonEmptyChain[Int]) => - ci.reverse.toChain should === (ci.toChain.reverse) + ci.reverse.toChain should ===(ci.toChain.reverse) } } } diff --git a/tests/src/test/scala/cats/tests/NonEmptyListSuite.scala b/tests/src/test/scala/cats/tests/NonEmptyListSuite.scala index 948dac307c1..ed2b9a9ff33 100644 --- a/tests/src/test/scala/cats/tests/NonEmptyListSuite.scala +++ b/tests/src/test/scala/cats/tests/NonEmptyListSuite.scala @@ -1,12 +1,19 @@ package cats package tests -import cats.kernel.laws.discipline.{SemigroupTests, OrderTests, PartialOrderTests, EqTests} +import cats.kernel.laws.discipline.{EqTests, OrderTests, PartialOrderTests, SemigroupTests} -import cats.data.{NonEmptyList, NonEmptyVector, NonEmptyMap} +import cats.data.{NonEmptyList, NonEmptyMap, NonEmptyVector} import cats.data.NonEmptyList.ZipNonEmptyList import cats.laws.discipline.arbitrary._ -import cats.laws.discipline.{CommutativeApplyTests, BimonadTests, NonEmptyTraverseTests, ReducibleTests, SemigroupKTests, SerializableTests} +import cats.laws.discipline.{ + BimonadTests, + CommutativeApplyTests, + NonEmptyTraverseTests, + ReducibleTests, + SemigroupKTests, + SerializableTests +} import scala.collection.immutable.SortedMap class NonEmptyListSuite extends CatsSuite { @@ -16,7 +23,8 @@ class NonEmptyListSuite extends CatsSuite { checkAll("NonEmptyList[Int]", OrderTests[NonEmptyList[Int]].order) - checkAll("NonEmptyList[Int] with Option", NonEmptyTraverseTests[NonEmptyList].nonEmptyTraverse[Option, Int, Int, Int, Int, Option, Option]) + checkAll("NonEmptyList[Int] with Option", + NonEmptyTraverseTests[NonEmptyList].nonEmptyTraverse[Option, Int, Int, Int, Int, Option, Option]) checkAll("NonEmptyTraverse[NonEmptyList[A]]", SerializableTests.serializable(NonEmptyTraverse[NonEmptyList])) checkAll("NonEmptyList[Int]", ReducibleTests[NonEmptyList].reducible[Option, Int, Int]) @@ -39,7 +47,8 @@ class NonEmptyListSuite extends CatsSuite { { implicit val A = ListWrapper.partialOrder[Int] checkAll("NonEmptyList[ListWrapper[Int]]", PartialOrderTests[NonEmptyList[ListWrapper[Int]]].partialOrder) - checkAll("PartialOrder[NonEmptyList[ListWrapper[Int]]]", SerializableTests.serializable(PartialOrder[NonEmptyList[ListWrapper[Int]]])) + checkAll("PartialOrder[NonEmptyList[ListWrapper[Int]]]", + SerializableTests.serializable(PartialOrder[NonEmptyList[ListWrapper[Int]]])) Eq[NonEmptyList[ListWrapper[Int]]] } @@ -47,7 +56,8 @@ class NonEmptyListSuite extends CatsSuite { { implicit val A = ListWrapper.order[Int] checkAll("NonEmptyList[ListWrapper[Int]]", OrderTests[NonEmptyList[ListWrapper[Int]]].order) - checkAll("Order[NonEmptyList[ListWrapper[Int]]]", SerializableTests.serializable(Order[NonEmptyList[ListWrapper[Int]]])) + checkAll("Order[NonEmptyList[ListWrapper[Int]]]", + SerializableTests.serializable(Order[NonEmptyList[ListWrapper[Int]]])) Eq[NonEmptyList[ListWrapper[Int]]] PartialOrder[NonEmptyList[ListWrapper[Int]]] @@ -55,23 +65,23 @@ class NonEmptyListSuite extends CatsSuite { test("Show is not empty and is formatted as expected") { forAll { (nel: NonEmptyList[Int]) => - nel.show.nonEmpty should === (true) - nel.show.startsWith("NonEmptyList(") should === (true) - nel.show should === (implicitly[Show[NonEmptyList[Int]]].show(nel)) - nel.show.contains(nel.head.show) should === (true) + nel.show.nonEmpty should ===(true) + nel.show.startsWith("NonEmptyList(") should ===(true) + nel.show should ===(implicitly[Show[NonEmptyList[Int]]].show(nel)) + nel.show.contains(nel.head.show) should ===(true) } } test("Show is formatted correctly") { val nonEmptyList = NonEmptyList("Test", Nil) - nonEmptyList.show should === ("NonEmptyList(Test)") + nonEmptyList.show should ===("NonEmptyList(Test)") } test("Creating NonEmptyList + toList is identity") { forAll { (i: Int, tail: List[Int]) => val list = i :: tail val nonEmptyList = NonEmptyList.of(i, tail: _*) - list should === (nonEmptyList.toList) + list should ===(nonEmptyList.toList) } } @@ -79,62 +89,62 @@ class NonEmptyListSuite extends CatsSuite { forAll { (init: List[Int], last: Int) => val list = init :+ last val nonEmptyList = NonEmptyList.ofInitLast(init, last) - list should === (nonEmptyList.toList) + list should ===(nonEmptyList.toList) } } test("NonEmptyList#filter is consistent with List#filter") { forAll { (nel: NonEmptyList[Int], p: Int => Boolean) => val list = nel.toList - nel.filter(p) should === (list.filter(p)) + nel.filter(p) should ===(list.filter(p)) } } test("NonEmptyList#filterNot is consistent with List#filterNot") { forAll { (nel: NonEmptyList[Int], p: Int => Boolean) => val list = nel.toList - nel.filterNot(p) should === (list.filterNot(p)) + nel.filterNot(p) should ===(list.filterNot(p)) } } test("NonEmptyList#collect is consistent with List#collect") { forAll { (nel: NonEmptyList[Int], pf: PartialFunction[Int, String]) => val list = nel.toList - nel.collect(pf) should === (list.collect(pf)) + nel.collect(pf) should ===(list.collect(pf)) } } test("NonEmptyList#find is consistent with List#find") { forAll { (nel: NonEmptyList[Int], p: Int => Boolean) => val list = nel.toList - nel.find(p) should === (list.find(p)) + nel.find(p) should ===(list.find(p)) } } test("NonEmptyList#exists is consistent with List#exists") { forAll { (nel: NonEmptyList[Int], p: Int => Boolean) => val list = nel.toList - nel.exists(p) should === (list.exists(p)) + nel.exists(p) should ===(list.exists(p)) } } test("NonEmptyList#forall is consistent with List#forall") { forAll { (nel: NonEmptyList[Int], p: Int => Boolean) => val list = nel.toList - nel.forall(p) should === (list.forall(p)) + nel.forall(p) should ===(list.forall(p)) } } test("NonEmptyList#map is consistent with List#map") { forAll { (nel: NonEmptyList[Int], p: Int => String) => val list = nel.toList - nel.map(p).toList should === (list.map(p)) + nel.map(p).toList should ===(list.map(p)) } } test("reduceLeft consistent with foldLeft") { forAll { (nel: NonEmptyList[Int], f: (Int, Int) => Int) => - nel.reduceLeft(f) should === (nel.tail.foldLeft(nel.head)(f)) + nel.reduceLeft(f) should ===(nel.tail.foldLeft(nel.head)(f)) } } @@ -143,19 +153,19 @@ class NonEmptyListSuite extends CatsSuite { val got = nel.reduceRight(f).value val last :: rev = nel.toList.reverse val expected = rev.reverse.foldRight(last)((a, b) => f(a, Now(b)).value) - got should === (expected) + got should ===(expected) } } test("reduce consistent with fold") { forAll { (nel: NonEmptyList[Int]) => - nel.reduce should === (nel.fold) + nel.reduce should ===(nel.fold) } } test("reduce consistent with reduceK") { forAll { (nel: NonEmptyList[Option[Int]]) => - nel.reduce(SemigroupK[Option].algebra[Int]) should === (nel.reduceK) + nel.reduce(SemigroupK[Option].algebra[Int]) should ===(nel.reduceK) } } @@ -164,7 +174,7 @@ class NonEmptyListSuite extends CatsSuite { val expected = nel.tail.foldLeft(Option(f(nel.head))) { (opt, i) => opt.map(s => g(s, i)) } - nel.reduceLeftToOption(f)(g) should === (expected) + nel.reduceLeftToOption(f)(g) should ===(expected) } } @@ -175,7 +185,7 @@ class NonEmptyListSuite extends CatsSuite { val expected = rev.reverse.foldRight(Option(f(last))) { (i, opt) => opt.map(s => g(i, Now(s)).value) } - got should === (expected) + got should ===(expected) } } @@ -185,29 +195,29 @@ class NonEmptyListSuite extends CatsSuite { val expected = f(nel.head).flatMap { hd => nel.tail.foldM(hd)((acc, i) => f(i).map(acc + _)) } - got should === (expected) + got should ===(expected) } } test("reduceMapM consistent with foldMapM") { forAll { (nel: NonEmptyList[Int], f: Int => Option[Int]) => - nel.reduceMapM(f) should === (nel.foldMapM(f)) + nel.reduceMapM(f) should ===(nel.foldMapM(f)) } } test("fromList round trip") { forAll { l: List[Int] => - NonEmptyList.fromList(l).map(_.toList).getOrElse(List.empty) should === (l) + NonEmptyList.fromList(l).map(_.toList).getOrElse(List.empty) should ===(l) } forAll { nel: NonEmptyList[Int] => - NonEmptyList.fromList(nel.toList) should === (Some(nel)) + NonEmptyList.fromList(nel.toList) should ===(Some(nel)) } } test("fromListUnsafe/fromList consistency") { forAll { nel: NonEmptyList[Int] => - NonEmptyList.fromList(nel.toList) should === (Some(NonEmptyList.fromListUnsafe(nel.toList))) + NonEmptyList.fromList(nel.toList) should ===(Some(NonEmptyList.fromListUnsafe(nel.toList))) } } @@ -219,88 +229,86 @@ class NonEmptyListSuite extends CatsSuite { test(":: consistent with List") { forAll { (nel: NonEmptyList[Int], i: Int) => - (i :: nel).toList should === (i :: nel.toList) - nel.prepend(i).toList should === (i :: nel.toList) + (i :: nel).toList should ===(i :: nel.toList) + nel.prepend(i).toList should ===(i :: nel.toList) } } test("NonEmptyList#distinct is consistent with List#distinct") { forAll { nel: NonEmptyList[Int] => - nel.distinct.toList should === (nel.toList.distinct) + nel.distinct.toList should ===(nel.toList.distinct) } } test("NonEmptyList#reverse is consistent with List#reverse") { forAll { nel: NonEmptyList[Int] => - nel.reverse.toList should === (nel.toList.reverse) + nel.reverse.toList should ===(nel.toList.reverse) } } test("NonEmptyList#zipWithIndex is consistent with List#zipWithIndex") { forAll { nel: NonEmptyList[Int] => - nel.zipWithIndex.toList should === (nel.toList.zipWithIndex) + nel.zipWithIndex.toList should ===(nel.toList.zipWithIndex) } } test("NonEmptyList#last is consistent with List#last") { forAll { nel: NonEmptyList[Int] => - nel.last should === (nel.toList.last) + nel.last should ===(nel.toList.last) } } test("NonEmptyList#init is consistent with List#init") { forAll { nel: NonEmptyList[Int] => - nel.init should === (nel.toList.init) + nel.init should ===(nel.toList.init) } } test("NonEmptyList#size and length is consistent with List#size") { forAll { nel: NonEmptyList[Int] => - nel.size should === (nel.toList.size) - nel.length should === (nel.toList.size) + nel.size should ===(nel.toList.size) + nel.length should ===(nel.toList.size) } } test("NonEmptyList#sorted is consistent with List#sorted") { forAll { nel: NonEmptyList[Int] => - nel.sorted.toList should === (nel.toList.sorted) + nel.sorted.toList should ===(nel.toList.sorted) } } test("NonEmptyList#sortBy is consistent with List#sortBy") { forAll { (nel: NonEmptyList[Int], f: Int => Int) => - nel.sortBy(f).toList should === (nel.toList.sortBy(f)) + nel.sortBy(f).toList should ===(nel.toList.sortBy(f)) } } - test("NonEmptyList#groupBy is consistent with List#groupBy") { forAll { (nel: NonEmptyList[Int], f: Int => Int) => - nel.groupBy(f).map{ case (k, v) => (k, v.toList) } should === (nel.toList.groupBy(f)) + nel.groupBy(f).map { case (k, v) => (k, v.toList) } should ===(nel.toList.groupBy(f)) } } test("NonEmptyList#concat/concatNel is consistent with List#:::") { forAll { (nel: NonEmptyList[Int], l: List[Int], n: Int) => - (nel ++ l).toList should === (nel.toList ::: l) - nel.concat(l).toList should === (nel.toList ::: l) - nel.concatNel(NonEmptyList(n, l)).toList should === (nel.toList ::: (n :: l)) + (nel ++ l).toList should ===(nel.toList ::: l) + nel.concat(l).toList should ===(nel.toList ::: l) + nel.concatNel(NonEmptyList(n, l)).toList should ===(nel.toList ::: (n :: l)) } } test("NonEmptyList#fromFoldabale is consistent with NonEmptyList#fromList") { forAll { (xs: List[Int]) => - NonEmptyList.fromList(xs) should === (NonEmptyList.fromFoldable(xs)) + NonEmptyList.fromList(xs) should ===(NonEmptyList.fromFoldable(xs)) } } test("NonEmptyList#fromReducible is consistent with Reducible#toNonEmptyList") { forAll { (xs: NonEmptyVector[Int]) => - NonEmptyList.fromReducible(xs) should === (Reducible[NonEmptyVector].toNonEmptyList(xs)) + NonEmptyList.fromReducible(xs) should ===(Reducible[NonEmptyVector].toNonEmptyList(xs)) } } - test("NonEmptyList#zipWith is consistent with List#zip and then List#map") { forAll { (a: NonEmptyList[Int], b: NonEmptyList[Int], f: (Int, Int) => Int) => a.zipWith(b)(f).toList should ===(a.toList.zip(b.toList).map { case (x, y) => f(x, y) }) @@ -308,12 +316,11 @@ class NonEmptyListSuite extends CatsSuite { } test("NonEmptyList#nonEmptyPartition remains sorted") { forAll { (nel: NonEmptyList[Int], f: Int => Either[String, String]) => - val sorted = nel.map(f).sorted val ior = Reducible[NonEmptyList].nonEmptyPartition(sorted)(identity) - ior.left.map(xs => xs.sorted should === (xs)) - ior.right.map(xs => xs.sorted should === (xs)) + ior.left.map(xs => xs.sorted should ===(xs)) + ior.right.map(xs => xs.sorted should ===(xs)) } } @@ -329,7 +336,7 @@ class DeprecatedNonEmptyListSuite extends CatsSuite { test("Deprecated NonEmptyList#concat is consistent with List#:::") { forAll { (nel: NonEmptyList[Int], l: List[Int], n: Int) => - nel.concat(NonEmptyList(n, l)).toList should === (nel.toList ::: (n :: l)) + nel.concat(NonEmptyList(n, l)).toList should ===(nel.toList ::: (n :: l)) } } } diff --git a/tests/src/test/scala/cats/tests/NonEmptyMapSuite.scala b/tests/src/test/scala/cats/tests/NonEmptyMapSuite.scala index 756f9c784df..9b11b522af3 100644 --- a/tests/src/test/scala/cats/tests/NonEmptyMapSuite.scala +++ b/tests/src/test/scala/cats/tests/NonEmptyMapSuite.scala @@ -26,9 +26,11 @@ import scala.collection.immutable.SortedMap class NonEmptyMapSuite extends CatsSuite { - checkAll("NonEmptyMap[String, Int]", SemigroupKTests[NonEmptyMap[String, ?]].semigroupK[Int]) - checkAll("NonEmptyMap[String, Int]", NonEmptyTraverseTests[NonEmptyMap[String, ?]].nonEmptyTraverse[Option, Int, Int, Double, Int, Option, Option]) + checkAll( + "NonEmptyMap[String, Int]", + NonEmptyTraverseTests[NonEmptyMap[String, ?]].nonEmptyTraverse[Option, Int, Int, Double, Int, Option, Option] + ) checkAll("NonEmptyMap[String, Int]", BandTests[NonEmptyMap[String, Int]].band) checkAll("NonEmptyMap[String, Int]", EqTests[NonEmptyMap[String, Int]].eqv) @@ -90,13 +92,13 @@ class NonEmptyMapSuite extends CatsSuite { test("lookup is consistent with contains") { forAll { (nem: NonEmptyMap[String, Int], key: String) => - nem(key).isDefined should === (nem.contains(key)) + nem(key).isDefined should ===(nem.contains(key)) } } test("keys.contains is consistent with contains") { forAll { (nem: NonEmptyMap[String, Int], key: String) => - nem(key).isDefined should === (nem.keys.contains(key)) + nem(key).isDefined should ===(nem.keys.contains(key)) } } @@ -191,7 +193,7 @@ class NonEmptyMapSuite extends CatsSuite { test("+ consistent with Map") { forAll { (nem: NonEmptyMap[String, Int], i: (String, Int)) => - (nem add i).toSortedMap should ===(nem.toSortedMap + i) + nem.add(i).toSortedMap should ===(nem.toSortedMap + i) } } @@ -202,8 +204,8 @@ class NonEmptyMapSuite extends CatsSuite { } } - test("NonEmptyMap#toNonEmptyList is consistent with Map#toList and creating NonEmptyList from it"){ - forAll{ nem: NonEmptyMap[String, Int] => + test("NonEmptyMap#toNonEmptyList is consistent with Map#toList and creating NonEmptyList from it") { + forAll { nem: NonEmptyMap[String, Int] => nem.toNel should ===(NonEmptyList.fromListUnsafe(nem.toSortedMap.toList)) } } diff --git a/tests/src/test/scala/cats/tests/NonEmptySetSuite.scala b/tests/src/test/scala/cats/tests/NonEmptySetSuite.scala index 30b5dee8957..f65b86061a4 100644 --- a/tests/src/test/scala/cats/tests/NonEmptySetSuite.scala +++ b/tests/src/test/scala/cats/tests/NonEmptySetSuite.scala @@ -20,7 +20,7 @@ package tests import cats.laws.discipline._ import cats.laws.discipline.arbitrary._ import cats.data.NonEmptySet -import cats.kernel.laws.discipline.{SemilatticeTests, EqTests} +import cats.kernel.laws.discipline.{EqTests, SemilatticeTests} import scala.collection.immutable.SortedSet @@ -33,85 +33,87 @@ class NonEmptySetSuite extends CatsSuite { test("First element is always the smallest") { forAll { (nes: NonEmptySet[Int]) => - nes.forall { v => Order[Int].lteqv(nes.head, v) } should === (true) + nes.forall { v => + Order[Int].lteqv(nes.head, v) + } should ===(true) } } test("Show is not empty and is formatted as expected") { forAll { (nes: NonEmptySet[Int]) => - nes.show.nonEmpty should === (true) - nes.show.startsWith("NonEmptySortedSet(") should === (true) - nes.show should === (implicitly[Show[NonEmptySet[Int]]].show(nes)) - nes.show.contains(nes.head.show) should === (true) + nes.show.nonEmpty should ===(true) + nes.show.startsWith("NonEmptySortedSet(") should ===(true) + nes.show should ===(implicitly[Show[NonEmptySet[Int]]].show(nes)) + nes.show.contains(nes.head.show) should ===(true) } } test("Show is formatted correctly") { val nonEmptySet = NonEmptySet("Test", SortedSet.empty[String]) - nonEmptySet.show should === ("NonEmptySortedSet(Test)") + nonEmptySet.show should ===("NonEmptySortedSet(Test)") } test("Creating NonEmptySet + toSet is identity") { forAll { (i: Int, tail: SortedSet[Int]) => val set = tail + i val nonEmptySet = NonEmptySet(i, tail) - set should === (nonEmptySet.toSortedSet) + set should ===(nonEmptySet.toSortedSet) } } test("NonEmptySet#filter is consistent with Set#filter") { forAll { (nes: NonEmptySet[Int], p: Int => Boolean) => val set = nes.toSortedSet - nes.filter(p) should === (set.filter(p)) + nes.filter(p) should ===(set.filter(p)) } } test("NonEmptySet#filterNot is consistent with Set#filterNot") { forAll { (nes: NonEmptySet[Int], p: Int => Boolean) => val set = nes.toSortedSet - nes.filterNot(p) should === (set.filterNot(p)) + nes.filterNot(p) should ===(set.filterNot(p)) } } test("NonEmptySet#collect is consistent with Set#collect") { forAll { (nes: NonEmptySet[Int], pf: PartialFunction[Int, String]) => val set = nes.toSortedSet - nes.collect(pf) should === (set.collect(pf)) + nes.collect(pf) should ===(set.collect(pf)) } } test("NonEmptySet#find is consistent with Set#find") { forAll { (nes: NonEmptySet[Int], p: Int => Boolean) => val set = nes.toSortedSet - nes.find(p) should === (set.find(p)) + nes.find(p) should ===(set.find(p)) } } test("NonEmptySet#exists is consistent with Set#exists") { forAll { (nes: NonEmptySet[Int], p: Int => Boolean) => val set = nes.toSortedSet - nes.exists(p) should === (set.exists(p)) + nes.exists(p) should ===(set.exists(p)) } } test("NonEmptySet#forall is consistent with Set#forall") { forAll { (nes: NonEmptySet[Int], p: Int => Boolean) => val set = nes.toSortedSet - nes.forall(p) should === (set.forall(p)) + nes.forall(p) should ===(set.forall(p)) } } test("NonEmptySet#map is consistent with Set#map") { forAll { (nes: NonEmptySet[Int], p: Int => String) => val set = nes.toSortedSet - nes.map(p).toSortedSet should === (set.map(p)) + nes.map(p).toSortedSet should ===(set.map(p)) } } test("reduceLeft consistent with foldLeft") { forAll { (nes: NonEmptySet[Int], f: (Int, Int) => Int) => - nes.reduceLeft(f) should === (nes.tail.foldLeft(nes.head)(f)) + nes.reduceLeft(f) should ===(nes.tail.foldLeft(nes.head)(f)) } } @@ -121,20 +123,19 @@ class NonEmptySetSuite extends CatsSuite { val last = nes.last val rev = nes - last val expected = rev.foldRight(last)((a, b) => f(a, Now(b)).value) - got should === (expected) + got should ===(expected) } } test("reduce consistent with fold") { forAll { (nes: NonEmptySet[Int]) => - nes.reduce should === (nes.fold) + nes.reduce should ===(nes.fold) } } - test("reduce consistent with reduceK") { forAll { (nes: NonEmptySet[Option[Int]]) => - nes.reduce(SemigroupK[Option].algebra[Int]) should === (nes.reduceK) + nes.reduce(SemigroupK[Option].algebra[Int]) should ===(nes.reduceK) } } @@ -143,7 +144,7 @@ class NonEmptySetSuite extends CatsSuite { val expected = nes.tail.foldLeft(Option(f(nes.head))) { (opt, i) => opt.map(s => g(s, i)) } - nes.reduceLeftToOption(f)(g) should === (expected) + nes.reduceLeftToOption(f)(g) should ===(expected) } } @@ -155,7 +156,7 @@ class NonEmptySetSuite extends CatsSuite { val expected = rev.foldRight(Option(f(last))) { (i, opt) => opt.map(s => g(i, Now(s)).value) } - got should === (expected) + got should ===(expected) } } @@ -165,29 +166,29 @@ class NonEmptySetSuite extends CatsSuite { val expected = f(nes.head).flatMap { hd => nes.tail.foldM(hd)((acc, i) => f(i).map(acc + _)) } - got should === (expected) + got should ===(expected) } } test("reduceMapM consistent with foldMapM") { forAll { (nes: NonEmptySet[Int], f: Int => Option[Int]) => - nes.reduceMapM(f) should === (nes.foldMapM(f)) + nes.reduceMapM(f) should ===(nes.foldMapM(f)) } } test("fromSet round trip") { forAll { l: SortedSet[Int] => - NonEmptySet.fromSet(l).map(_.toSortedSet).getOrElse(SortedSet.empty[Int]) should === (l) + NonEmptySet.fromSet(l).map(_.toSortedSet).getOrElse(SortedSet.empty[Int]) should ===(l) } forAll { nes: NonEmptySet[Int] => - NonEmptySet.fromSet(nes.toSortedSet) should === (Some(nes)) + NonEmptySet.fromSet(nes.toSortedSet) should ===(Some(nes)) } } test("fromSetUnsafe/fromSet consistency") { forAll { nes: NonEmptySet[Int] => - NonEmptySet.fromSet(nes.toSortedSet) should === (Some(NonEmptySet.fromSetUnsafe(nes.toSortedSet))) + NonEmptySet.fromSet(nes.toSortedSet) should ===(Some(NonEmptySet.fromSetUnsafe(nes.toSortedSet))) } } @@ -199,25 +200,25 @@ class NonEmptySetSuite extends CatsSuite { test("+ consistent with Set") { forAll { (nes: NonEmptySet[Int], i: Int) => - (nes add i).toSortedSet should === (nes.toSortedSet + i) + nes.add(i).toSortedSet should ===(nes.toSortedSet + i) } } test("NonEmptySet#zipWithIndex is consistent with Set#zipWithIndex") { forAll { nes: NonEmptySet[Int] => - nes.zipWithIndex.toSortedSet should === (nes.toSortedSet.zipWithIndex) + nes.zipWithIndex.toSortedSet should ===(nes.toSortedSet.zipWithIndex) } } test("NonEmptySet#length is consistent with Set#size") { forAll { nes: NonEmptySet[Int] => - nes.length should === (nes.toSortedSet.size) + nes.length should ===(nes.toSortedSet.size) } } test("NonEmptySet#concat is consistent with Set#++") { forAll { (nes: NonEmptySet[Int], l: SortedSet[Int], n: Int) => - nes.union(NonEmptySet(n, l)).toSortedSet should === (nes.toSortedSet ++ (l + n)) + nes.union(NonEmptySet(n, l)).toSortedSet should ===(nes.toSortedSet ++ (l + n)) } } @@ -235,7 +236,7 @@ class NonEmptySetSuite extends CatsSuite { test("NonEmptySet#groupBy is consistent with Set#groupBy") { forAll { (nes: NonEmptySet[Int], f: Int => Int) => - nes.groupBy(f).map(_.toSortedSet).toSortedMap should === (nes.toSortedSet.groupBy(f)) + nes.groupBy(f).map(_.toSortedSet).toSortedMap should ===(nes.toSortedSet.groupBy(f)) } } } diff --git a/tests/src/test/scala/cats/tests/NonEmptyVectorSuite.scala b/tests/src/test/scala/cats/tests/NonEmptyVectorSuite.scala index 55b3798b407..2c319b46d78 100644 --- a/tests/src/test/scala/cats/tests/NonEmptyVectorSuite.scala +++ b/tests/src/test/scala/cats/tests/NonEmptyVectorSuite.scala @@ -5,10 +5,18 @@ import catalysts.Platform import cats.data.NonEmptyVector.ZipNonEmptyVector -import cats.kernel.laws.discipline.{SemigroupTests, EqTests} +import cats.kernel.laws.discipline.{EqTests, SemigroupTests} import cats.data.NonEmptyVector -import cats.laws.discipline.{CommutativeApplyTests, BimonadTests, SemigroupKTests, FoldableTests, SerializableTests, NonEmptyTraverseTests, ReducibleTests} +import cats.laws.discipline.{ + BimonadTests, + CommutativeApplyTests, + FoldableTests, + NonEmptyTraverseTests, + ReducibleTests, + SemigroupKTests, + SerializableTests +} import cats.laws.discipline.arbitrary._ import scala.util.Properties @@ -20,13 +28,13 @@ class NonEmptyVectorSuite extends CatsSuite { checkAll("NonEmptyVector[Int]", EqTests[NonEmptyVector[Int]].eqv) - checkAll("NonEmptyVector[Int] with Option", NonEmptyTraverseTests[NonEmptyVector].nonEmptyTraverse[Option, Int, Int, Int, Int, Option, Option]) + checkAll("NonEmptyVector[Int] with Option", + NonEmptyTraverseTests[NonEmptyVector].nonEmptyTraverse[Option, Int, Int, Int, Int, Option, Option]) checkAll("NonEmptyTraverse[NonEmptyVector[A]]", SerializableTests.serializable(NonEmptyTraverse[NonEmptyVector])) checkAll("NonEmptyVector[Int]", ReducibleTests[NonEmptyVector].reducible[Option, Int, Int]) checkAll("Reducible[NonEmptyVector]", SerializableTests.serializable(Reducible[NonEmptyVector])) - // Test instances that have more general constraints checkAll("NonEmptyVector[Int]", SemigroupKTests[NonEmptyVector].semigroupK[Int]) @@ -34,12 +42,9 @@ class NonEmptyVectorSuite extends CatsSuite { checkAll("SemigroupK[NonEmptyVector]", SerializableTests.serializable(SemigroupK[NonEmptyVector])) checkAll("Semigroup[NonEmptyVector[Int]]", SerializableTests.serializable(Semigroup[NonEmptyVector[Int]])) - - checkAll("NonEmptyVector[Int]", FoldableTests[NonEmptyVector].foldable[Int, Int]) checkAll("Foldable[NonEmptyVector]", SerializableTests.serializable(Foldable[NonEmptyVector])) - checkAll("ZipNonEmptyVector[Int]", CommutativeApplyTests[ZipNonEmptyVector].commutativeApply[Int, Int, Int]) checkAll("CommutativeApply[ZipNonEmptyVector]", SerializableTests.serializable(CommutativeApply[ZipNonEmptyVector])) @@ -49,89 +54,85 @@ class NonEmptyVectorSuite extends CatsSuite { implicitly[Comonad[NonEmptyVector]] implicitly[Bimonad[NonEmptyVector]] - - checkAll("NonEmptyVector[Int]", BimonadTests[NonEmptyVector].bimonad[Int, Int, Int]) checkAll("Bimonad[NonEmptyVector]", SerializableTests.serializable(Bimonad[NonEmptyVector])) - test("size is consistent with toList.size") { forAll { (nonEmptyVector: NonEmptyVector[Int]) => - nonEmptyVector.size should === (nonEmptyVector.toList.size.toLong) + nonEmptyVector.size should ===(nonEmptyVector.toList.size.toLong) } } - test("Show is not empty and is formatted as expected") { forAll { (nonEmptyVector: NonEmptyVector[Int]) => - nonEmptyVector.show.nonEmpty should === (true) - nonEmptyVector.show.startsWith("NonEmptyVector(") should === (true) - nonEmptyVector.show should === (implicitly[Show[NonEmptyVector[Int]]].show(nonEmptyVector)) - nonEmptyVector.show.contains(nonEmptyVector.head.show) should === (true) + nonEmptyVector.show.nonEmpty should ===(true) + nonEmptyVector.show.startsWith("NonEmptyVector(") should ===(true) + nonEmptyVector.show should ===(implicitly[Show[NonEmptyVector[Int]]].show(nonEmptyVector)) + nonEmptyVector.show.contains(nonEmptyVector.head.show) should ===(true) } } test("Show is formatted correctly") { val v1 = NonEmptyVector("Test", Vector.empty) - v1.show should === ("NonEmptyVector(Test)") + v1.show should ===("NonEmptyVector(Test)") val v2 = NonEmptyVector.of("foo", "bar", "baz") - v2.show should === ("NonEmptyVector(foo, bar, baz)") + v2.show should ===("NonEmptyVector(foo, bar, baz)") } test("Creating NonEmptyVector + toVector is identity") { forAll { (i: Int, tail: Vector[Int]) => val vector = i +: tail val nonEmptyVector = NonEmptyVector(i, tail) - vector should === (nonEmptyVector.toVector) + vector should ===(nonEmptyVector.toVector) } } test("NonEmptyVector#filter is consistent with Vector#filter") { forAll { (nonEmptyVector: NonEmptyVector[Int], p: Int => Boolean) => val vector = nonEmptyVector.toVector - nonEmptyVector.filter(p) should === (vector.filter(p)) + nonEmptyVector.filter(p) should ===(vector.filter(p)) } } test("NonEmptyVector#filterNot is consistent with Vector#filterNot") { forAll { (nonEmptyVector: NonEmptyVector[Int], p: Int => Boolean) => val vector = nonEmptyVector.toVector - nonEmptyVector.filterNot(p) should === (vector.filterNot(p)) + nonEmptyVector.filterNot(p) should ===(vector.filterNot(p)) } } test("NonEmptyVector#find is consistent with Vector#find") { forAll { (nonEmptyVector: NonEmptyVector[Int], p: Int => Boolean) => val vector = nonEmptyVector.toVector - nonEmptyVector.find(p) should === (vector.find(p)) + nonEmptyVector.find(p) should ===(vector.find(p)) } } test("NonEmptyVector#exists is consistent with Vector#exists") { forAll { (nonEmptyVector: NonEmptyVector[Int], p: Int => Boolean) => val vector = nonEmptyVector.toVector - nonEmptyVector.exists(p) should === (vector.exists(p)) + nonEmptyVector.exists(p) should ===(vector.exists(p)) } } test("NonEmptyVector#forall is consistent with Vector#forall") { forAll { (nonEmptyVector: NonEmptyVector[Int], p: Int => Boolean) => val vector = nonEmptyVector.toVector - nonEmptyVector.forall(p) should === (vector.forall(p)) + nonEmptyVector.forall(p) should ===(vector.forall(p)) } } test("NonEmptyVector#map is consistent with Vector#map") { forAll { (nonEmptyVector: NonEmptyVector[Int], p: Int => String) => val vector = nonEmptyVector.toVector - nonEmptyVector.map(p).toVector should === (vector.map(p)) + nonEmptyVector.map(p).toVector should ===(vector.map(p)) } } test("reduceLeft consistent with foldLeft") { forAll { (nonEmptyVector: NonEmptyVector[Int], f: (Int, Int) => Int) => - nonEmptyVector.reduceLeft(f) should === (nonEmptyVector.tail.foldLeft(nonEmptyVector.head)(f)) + nonEmptyVector.reduceLeft(f) should ===(nonEmptyVector.tail.foldLeft(nonEmptyVector.head)(f)) } } @@ -143,19 +144,19 @@ class NonEmptyVectorSuite extends CatsSuite { val got = nonEmptyVector.reduceRight(f).value val (first, last) = excise(nonEmptyVector.toVector) val expected = first.foldRight(last)((a, b) => f(a, Now(b)).value) - got should === (expected) + got should ===(expected) } } test("reduce consistent with fold") { forAll { (nonEmptyVector: NonEmptyVector[Int]) => - nonEmptyVector.reduce should === (nonEmptyVector.fold) + nonEmptyVector.reduce should ===(nonEmptyVector.fold) } } test("reduce consistent with reduceK") { forAll { (nonEmptyVector: NonEmptyVector[Option[Int]]) => - nonEmptyVector.reduce(SemigroupK[Option].algebra[Int]) should === (nonEmptyVector.reduceK) + nonEmptyVector.reduce(SemigroupK[Option].algebra[Int]) should ===(nonEmptyVector.reduceK) } } @@ -164,7 +165,7 @@ class NonEmptyVectorSuite extends CatsSuite { val expected = nonEmptyVector.tail.foldLeft(Option(f(nonEmptyVector.head))) { (opt, i) => opt.map(s => g(s, i)) } - nonEmptyVector.reduceLeftToOption(f)(g) should === (expected) + nonEmptyVector.reduceLeftToOption(f)(g) should ===(expected) } } @@ -174,12 +175,12 @@ class NonEmptyVectorSuite extends CatsSuite { val expected = first.foldRight(Option(f(last))) { (i, opt) => opt.map(s => g(i, Now(s)).value) } - nonEmptyVector.reduceRightToOption(f)(g).value should === (expected) + nonEmptyVector.reduceRightToOption(f)(g).value should ===(expected) } } test("fromVector returns None when the input vector is empty") { - NonEmptyVector.fromVector(Vector.empty[Int]) should === (Option.empty[NonEmptyVector[Int]]) + NonEmptyVector.fromVector(Vector.empty[Int]) should ===(Option.empty[NonEmptyVector[Int]]) } test("fromVectorUnsafe throws an exception when the input vector is empty") { @@ -190,53 +191,53 @@ class NonEmptyVectorSuite extends CatsSuite { test("++ Vector is consistent with concatNev") { forAll { (nonEmptyVector: NonEmptyVector[Int], other: NonEmptyVector[Int]) => - nonEmptyVector ++ other.toVector should === (nonEmptyVector.concatNev(other)) + nonEmptyVector ++ other.toVector should ===(nonEmptyVector.concatNev(other)) } } test("++ Vector is consistent with concat") { forAll { (nonEmptyVector: NonEmptyVector[Int], vector: Vector[Int]) => - nonEmptyVector ++ vector should === (nonEmptyVector.concat(vector)) + nonEmptyVector ++ vector should ===(nonEmptyVector.concat(vector)) } } test(":+ is consistent with concat") { forAll { (nonEmptyVector: NonEmptyVector[Int], i: Int) => - nonEmptyVector :+ i should === (nonEmptyVector.concat(Vector(i))) + nonEmptyVector :+ i should ===(nonEmptyVector.concat(Vector(i))) } } test("append is consistent with :+") { forAll { (nonEmptyVector: NonEmptyVector[Int], i: Int) => - nonEmptyVector append i should === (nonEmptyVector :+ i) + nonEmptyVector.append(i) should ===(nonEmptyVector :+ i) } } test("+: is consistent with concatNev") { forAll { (nonEmptyVector: NonEmptyVector[Int], i: Int) => - i +: nonEmptyVector should === (NonEmptyVector.one(i).concatNev(nonEmptyVector)) + i +: nonEmptyVector should ===(NonEmptyVector.one(i).concatNev(nonEmptyVector)) } } test("prepend is consistent with +:") { forAll { (nonEmptyVector: NonEmptyVector[Int], i: Int) => - nonEmptyVector prepend i should === (i +: nonEmptyVector) + nonEmptyVector.prepend(i) should ===(i +: nonEmptyVector) } } test("NonEmptyVector#of on varargs is consistent with NonEmptyVector#apply on Vector") { forAll { (head: Int, tail: Vector[Int]) => - NonEmptyVector.of(head, tail:_*) should === (NonEmptyVector(head, tail)) + NonEmptyVector.of(head, tail: _*) should ===(NonEmptyVector(head, tail)) } } test("NonEmptyVector#get returns a None when the element does not exist") { forAll { (nonEmptyVector: NonEmptyVector[Int]) => val size = nonEmptyVector.toVector.size - nonEmptyVector.get(size) should === (None) + nonEmptyVector.get(size) should ===(None) } } test("NonEmptyVector#getUnsafe throws an exception when the element does not exist") { - forAll{ (nonEmptyVector: NonEmptyVector[Int]) => + forAll { (nonEmptyVector: NonEmptyVector[Int]) => val size = nonEmptyVector.toVector.size val _ = intercept[IndexOutOfBoundsException] { nonEmptyVector.getUnsafe(size) @@ -247,7 +248,7 @@ class NonEmptyVectorSuite extends CatsSuite { test("NonEmptyVector#updated returns a None when the element does not exist") { forAll { (nonEmptyVector: NonEmptyVector[Int], element: Int) => val size = nonEmptyVector.toVector.size - nonEmptyVector.updated(size, element) should === (None) + nonEmptyVector.updated(size, element) should ===(None) } } @@ -262,36 +263,36 @@ class NonEmptyVectorSuite extends CatsSuite { test("NonEmptyVector#hashCode consistent with Vector#hashCode") { forAll { (nonEmptyVector: NonEmptyVector[Int]) => - nonEmptyVector.hashCode should === (nonEmptyVector.toVector.hashCode) + nonEmptyVector.hashCode should ===(nonEmptyVector.toVector.hashCode) } } test("NonEmptyVector#equals consistent with Vector#equals") { forAll { (lhs: NonEmptyVector[Int], rhs: NonEmptyVector[Int]) => - lhs.equals(rhs) should === (lhs.toVector.equals(rhs.toVector)) + lhs.equals(rhs) should ===(lhs.toVector.equals(rhs.toVector)) } } test("NonEmptyVector#toString produces correct output") { forAll { (nonEmptyVector: NonEmptyVector[Int]) => - nonEmptyVector.toString should === (s"NonEmpty${nonEmptyVector.toVector.toString}") + nonEmptyVector.toString should ===(s"NonEmpty${nonEmptyVector.toVector.toString}") } - NonEmptyVector(1, Vector.empty).toString should === ("NonEmptyVector(1)") - NonEmptyVector(1, Vector.empty).toVector.toString should === ("Vector(1)") + NonEmptyVector(1, Vector.empty).toString should ===("NonEmptyVector(1)") + NonEmptyVector(1, Vector.empty).toVector.toString should ===("Vector(1)") } test("NonEmptyVector.unapply supports pattern matching") { forAll { (nonEmptyVector: NonEmptyVector[Int]) => nonEmptyVector match { case NonEmptyVector(head, tail) => - head should === (nonEmptyVector.head) - tail should === (nonEmptyVector.tail) + head should ===(nonEmptyVector.head) + tail should ===(nonEmptyVector.tail) } } } test("Cannot create a new NonEmptyVector from constructor") { - if(Platform.isJvm) { + if (Platform.isJvm) { if (!Properties.versionNumberString.startsWith("2.10")) { // A bug in scala 2.10 allows private constructors to be accessed. // We should still ensure that on scala 2.11 and up we cannot construct the @@ -311,7 +312,7 @@ class NonEmptyVectorSuite extends CatsSuite { test("NonEmptyVector#distinct is consistent with Vector#distinct") { forAll { nonEmptyVector: NonEmptyVector[Int] => - nonEmptyVector.distinct.toVector should === (nonEmptyVector.toVector.distinct) + nonEmptyVector.distinct.toVector should ===(nonEmptyVector.toVector.distinct) } } @@ -324,30 +325,29 @@ class NonEmptyVectorSuite extends CatsSuite { test("NonEmptyVector#zipWith is consistent with #zipWithIndex") { forAll { nev: NonEmptyVector[Int] => val zw = nev.zipWith(NonEmptyVector.fromVectorUnsafe((0 until nev.length).toVector))(Tuple2.apply) - nev.zipWithIndex should === (zw) + nev.zipWithIndex should ===(zw) } } test("NonEmptyVector#nonEmptyPartition remains sorted") { forAll { (nev: NonEmptyVector[Int], f: Int => Either[String, String]) => - val sorted = NonEmptyVector.fromVectorUnsafe(nev.map(f).toVector.sorted) val ior = Reducible[NonEmptyVector].nonEmptyPartition(sorted)(identity) - ior.left.map(xs => xs.sorted should === (xs)) - ior.right.map(xs => xs.sorted should === (xs)) + ior.left.map(xs => xs.sorted should ===(xs)) + ior.right.map(xs => xs.sorted should ===(xs)) } } test("NonEmptyVector#last is consistent with Vector#last") { forAll { nonEmptyVector: NonEmptyVector[Int] => - nonEmptyVector.last should === (nonEmptyVector.toVector.last) + nonEmptyVector.last should ===(nonEmptyVector.toVector.last) } } test("NonEmptyVector#init is consistent with Vector#init") { forAll { nonEmptyVector: NonEmptyVector[Int] => - nonEmptyVector.init should === (nonEmptyVector.toVector.init) + nonEmptyVector.init should ===(nonEmptyVector.toVector.init) } } @@ -356,35 +356,37 @@ class NonEmptyVectorSuite extends CatsSuite { case i if (i % 2 == 0) => i.toDouble } forAll { nonEmptyVector: NonEmptyVector[Int] => - nonEmptyVector.collect(pf) should === (nonEmptyVector.toVector.collect(pf)) + nonEmptyVector.collect(pf) should ===(nonEmptyVector.toVector.collect(pf)) } } test("NonEmptyVector#length and size is consistent with Vector#length") { forAll { nonEmptyVector: NonEmptyVector[Int] => - nonEmptyVector.length should === (nonEmptyVector.toVector.length) - nonEmptyVector.size should === (nonEmptyVector.toVector.length.toLong) + nonEmptyVector.length should ===(nonEmptyVector.toVector.length) + nonEmptyVector.size should ===(nonEmptyVector.toVector.length.toLong) } } test("NonEmptyVector#reverse is consistent with Vector#reverse") { forAll { nonEmptyVector: NonEmptyVector[Int] => - nonEmptyVector.reverse should === (NonEmptyVector.fromVectorUnsafe(nonEmptyVector.toVector.reverse)) + nonEmptyVector.reverse should ===(NonEmptyVector.fromVectorUnsafe(nonEmptyVector.toVector.reverse)) } } test("NonEmptyVector#zipWithIndex is consistent with Vector#zipWithIndex") { forAll { nonEmptyVector: NonEmptyVector[Int] => val expected = NonEmptyVector.fromVectorUnsafe(nonEmptyVector.toVector.zipWithIndex) - nonEmptyVector.zipWithIndex should === (expected) - Traverse[NonEmptyVector].zipWithIndex(nonEmptyVector) should === (expected) + nonEmptyVector.zipWithIndex should ===(expected) + Traverse[NonEmptyVector].zipWithIndex(nonEmptyVector) should ===(expected) } } test("NonEmptyVector#sorted and sortBy is consistent with Vector#sorted and sortBy") { forAll { nonEmptyVector: NonEmptyVector[Int] => - nonEmptyVector.sorted should === (NonEmptyVector.fromVectorUnsafe(nonEmptyVector.toVector.sorted)) - nonEmptyVector.sortBy(i => -i) should === (NonEmptyVector.fromVectorUnsafe(nonEmptyVector.toVector.sortBy(i => -i))) + nonEmptyVector.sorted should ===(NonEmptyVector.fromVectorUnsafe(nonEmptyVector.toVector.sorted)) + nonEmptyVector.sortBy(i => -i) should ===( + NonEmptyVector.fromVectorUnsafe(nonEmptyVector.toVector.sortBy(i => -i)) + ) } } } diff --git a/tests/src/test/scala/cats/tests/OneAndSuite.scala b/tests/src/test/scala/cats/tests/OneAndSuite.scala index 04bb440f087..f73f0e20f74 100644 --- a/tests/src/test/scala/cats/tests/OneAndSuite.scala +++ b/tests/src/test/scala/cats/tests/OneAndSuite.scala @@ -1,11 +1,23 @@ package cats package tests -import cats.kernel.laws.discipline.{SemigroupTests, EqTests} +import cats.kernel.laws.discipline.{EqTests, SemigroupTests} import cats.instances.stream._ import cats.data.{NonEmptyStream, OneAnd} -import cats.laws.discipline.{ApplicativeTests, SemigroupalTests, ComonadTests, FoldableTests, FunctorTests, MonadTests, NonEmptyTraverseTests, ReducibleTests, SemigroupKTests, SerializableTests, TraverseTests} +import cats.laws.discipline.{ + ApplicativeTests, + ComonadTests, + FoldableTests, + FunctorTests, + MonadTests, + NonEmptyTraverseTests, + ReducibleTests, + SemigroupKTests, + SemigroupalTests, + SerializableTests, + TraverseTests +} import cats.laws.discipline.arbitrary._ class OneAndSuite extends CatsSuite { @@ -15,19 +27,22 @@ class OneAndSuite extends CatsSuite { checkAll("OneAnd[Stream, Int]", EqTests[OneAnd[Stream, Int]].eqv) - checkAll("OneAnd[Stream, Int] with Option", NonEmptyTraverseTests[OneAnd[Stream, ?]].nonEmptyTraverse[Option, Int, Int, Int, Int, Option, Option]) + checkAll("OneAnd[Stream, Int] with Option", + NonEmptyTraverseTests[OneAnd[Stream, ?]].nonEmptyTraverse[Option, Int, Int, Int, Int, Option, Option]) checkAll("NonEmptyTraverse[OneAnd[Stream, A]]", SerializableTests.serializable(NonEmptyTraverse[OneAnd[Stream, ?]])) { implicit val traverse = OneAnd.catsDataTraverseForOneAnd(ListWrapper.traverse) - checkAll("OneAnd[ListWrapper, Int] with Option", TraverseTests[OneAnd[ListWrapper, ?]].traverse[Int, Int, Int, Int, Option, Option]) + checkAll("OneAnd[ListWrapper, Int] with Option", + TraverseTests[OneAnd[ListWrapper, ?]].traverse[Int, Int, Int, Int, Option, Option]) checkAll("Traverse[OneAnd[ListWrapper, A]]", SerializableTests.serializable(Traverse[OneAnd[ListWrapper, ?]])) } checkAll("OneAnd[Stream, Int]", ReducibleTests[OneAnd[Stream, ?]].reducible[Option, Int, Int]) checkAll("Reducible[OneAnd[Stream, ?]]", SerializableTests.serializable(Reducible[OneAnd[Stream, ?]])) - implicit val iso = SemigroupalTests.Isomorphisms.invariant[OneAnd[ListWrapper, ?]](OneAnd.catsDataFunctorForOneAnd(ListWrapper.functor)) + implicit val iso = SemigroupalTests.Isomorphisms + .invariant[OneAnd[ListWrapper, ?]](OneAnd.catsDataFunctorForOneAnd(ListWrapper.functor)) // Test instances that have more general constraints { @@ -80,76 +95,75 @@ class OneAndSuite extends CatsSuite { test("size is consistent with toList.size") { forAll { (oa: OneAnd[Vector, Int]) => - oa.size should === (oa.toList.size.toLong) + oa.size should ===(oa.toList.size.toLong) } } test("Show is not empty and is formatted as expected") { forAll { (nel: NonEmptyStream[Int]) => - nel.show.nonEmpty should === (true) - nel.show.startsWith("OneAnd(") should === (true) - nel.show should === (implicitly[Show[NonEmptyStream[Int]]].show(nel)) - nel.show.contains(nel.head.show) should === (true) + nel.show.nonEmpty should ===(true) + nel.show.startsWith("OneAnd(") should ===(true) + nel.show should ===(implicitly[Show[NonEmptyStream[Int]]].show(nel)) + nel.show.contains(nel.head.show) should ===(true) } } test("Show is formatted correctly") { val oneAnd = NonEmptyStream("Test") - oneAnd.show should === ("OneAnd(Test, Stream())") + oneAnd.show should ===("OneAnd(Test, Stream())") } test("Creating OneAnd + unwrap is identity") { forAll { (i: Int, tail: Stream[Int]) => val stream = i #:: tail val oneAnd = NonEmptyStream(i, tail: _*) - stream should === (oneAnd.unwrap) + stream should ===(oneAnd.unwrap) } } test("NonEmptyStream#find is consistent with Stream#find") { forAll { (nel: NonEmptyStream[Int], p: Int => Boolean) => val stream = nel.unwrap - nel.find(p) should === (stream.find(p)) + nel.find(p) should ===(stream.find(p)) } } test("NonEmptyStream#exists is consistent with Stream#exists") { forAll { (nel: NonEmptyStream[Int], p: Int => Boolean) => val stream = nel.unwrap - nel.exists(p) should === (stream.exists(p)) + nel.exists(p) should ===(stream.exists(p)) } } test("NonEmptyStream#forall is consistent with Stream#forall") { forAll { (nel: NonEmptyStream[Int], p: Int => Boolean) => val stream = nel.unwrap - nel.forall(p) should === (stream.forall(p)) + nel.forall(p) should ===(stream.forall(p)) } } test("NonEmptyStream#map is consistent with Stream#map") { forAll { (nel: NonEmptyStream[Int], p: Int => String) => val stream = nel.unwrap - nel.map(p).unwrap should === (stream.map(p)) + nel.map(p).unwrap should ===(stream.map(p)) } } test("NonEmptyStream#nonEmptyPartition remains sorted") { forAll { (nes: NonEmptyStream[Int], f: Int => Either[String, String]) => - val nesf = nes.map(f) val sortedStream = (nesf.head #:: nesf.tail).sorted val sortedNes = OneAnd(sortedStream.head, sortedStream.tail) val ior = Reducible[NonEmptyStream].nonEmptyPartition(sortedNes)(identity) - ior.left.map(xs => xs.sorted should === (xs)) - ior.right.map(xs => xs.sorted should === (xs)) + ior.left.map(xs => xs.sorted should ===(xs)) + ior.right.map(xs => xs.sorted should ===(xs)) } } test("reduceLeft consistent with foldLeft") { forAll { (nel: NonEmptyStream[Int], f: (Int, Int) => Int) => - nel.reduceLeft(f) should === (nel.tail.foldLeft(nel.head)(f)) + nel.reduceLeft(f) should ===(nel.tail.foldLeft(nel.head)(f)) } } @@ -158,19 +172,19 @@ class OneAndSuite extends CatsSuite { val got = nel.reduceRight(f).value val last :: rev = nel.unwrap.toList.reverse val expected = rev.reverse.foldRight(last)((a, b) => f(a, Now(b)).value) - got should === (expected) + got should ===(expected) } } test("reduce consistent with fold") { forAll { (nel: NonEmptyStream[Int]) => - nel.reduce should === (nel.fold) + nel.reduce should ===(nel.fold) } } test("reduce consistent with reduceK") { forAll { (nel: NonEmptyStream[Option[Int]]) => - nel.reduce(SemigroupK[Option].algebra[Int]) should === (nel.reduceK) + nel.reduce(SemigroupK[Option].algebra[Int]) should ===(nel.reduceK) } } @@ -179,7 +193,7 @@ class OneAndSuite extends CatsSuite { val expected = nel.tail.foldLeft(Option(f(nel.head))) { (opt, i) => opt.map(s => g(s, i)) } - nel.reduceLeftToOption(f)(g) should === (expected) + nel.reduceLeftToOption(f)(g) should ===(expected) } } @@ -190,7 +204,7 @@ class OneAndSuite extends CatsSuite { val expected = rev.reverse.foldRight(Option(f(last))) { (i, opt) => opt.map(s => g(i, Now(s)).value) } - got should === (expected) + got should ===(expected) } } diff --git a/tests/src/test/scala/cats/tests/OpSuite.scala b/tests/src/test/scala/cats/tests/OpSuite.scala index 0b2e4ed3584..e4a6015d878 100644 --- a/tests/src/test/scala/cats/tests/OpSuite.scala +++ b/tests/src/test/scala/cats/tests/OpSuite.scala @@ -22,8 +22,8 @@ class OpSuite extends CatsSuite { } /** - * Testing that implicit resolution works. If it compiles, the "test" passes. - */ + * Testing that implicit resolution works. If it compiles, the "test" passes. + */ object ImplicitResolution { // Arr is Function1 Category[Op[Function1, ?, ?]] diff --git a/tests/src/test/scala/cats/tests/OptionSuite.scala b/tests/src/test/scala/cats/tests/OptionSuite.scala index ae36f201298..e76a681fd91 100644 --- a/tests/src/test/scala/cats/tests/OptionSuite.scala +++ b/tests/src/test/scala/cats/tests/OptionSuite.scala @@ -28,11 +28,11 @@ class OptionSuite extends CatsSuite { checkAll("MonadError[Option, Unit]", SerializableTests.serializable(MonadError[Option, Unit])) test("show") { - none[Int].show should === ("None") - 1.some.show should === ("Some(1)") + none[Int].show should ===("None") + 1.some.show should ===("Some(1)") forAll { fs: Option[String] => - fs.show should === (fs.toString) + fs.show should ===(fs.toString) } } @@ -42,31 +42,23 @@ class OptionSuite extends CatsSuite { // instances. test("Kleisli associativity") { - forAll { (l: Long, - f: Long => Option[Int], - g: Int => Option[Char], - h: Char => Option[String]) => + forAll { (l: Long, f: Long => Option[Int], g: Int => Option[Char], h: Char => Option[String]) => val isEq = FlatMapLaws[Option].kleisliAssociativity(f, g, h, l) - isEq.lhs should === (isEq.rhs) + isEq.lhs should ===(isEq.rhs) } } test("Cokleisli associativity") { - forAll { (l: Option[Long], - f: Option[Long] => Int, - g: Option[Int] => Char, - h: Option[Char] => String) => + forAll { (l: Option[Long], f: Option[Long] => Int, g: Option[Int] => Char, h: Option[Char] => String) => val isEq = CoflatMapLaws[Option].cokleisliAssociativity(f, g, h, l) - isEq.lhs should === (isEq.rhs) + isEq.lhs should ===(isEq.rhs) } } test("applicative composition") { - forAll { (fa: Option[Int], - fab: Option[Int => Long], - fbc: Option[Long => Char]) => + forAll { (fa: Option[Int], fab: Option[Int => Long], fbc: Option[Long => Char]) => val isEq = ApplicativeLaws[Option].applicativeComposition(fa, fab, fbc) - isEq.lhs should === (isEq.rhs) + isEq.lhs should ===(isEq.rhs) } } @@ -75,14 +67,14 @@ class OptionSuite extends CatsSuite { test("Kleisli left identity") { forAll { (a: Int, f: Int => Option[Long]) => val isEq = monadLaws.kleisliLeftIdentity(a, f) - isEq.lhs should === (isEq.rhs) + isEq.lhs should ===(isEq.rhs) } } test("Kleisli right identity") { forAll { (a: Int, f: Int => Option[Long]) => val isEq = monadLaws.kleisliRightIdentity(a, f) - isEq.lhs should === (isEq.rhs) + isEq.lhs should ===(isEq.rhs) } } @@ -96,11 +88,11 @@ class OptionSuite extends CatsSuite { test("map2Eval is lazy") { val bomb: Eval[Option[Int]] = Later(sys.error("boom")) - none[Int].map2Eval(bomb)(_ + _).value should === (None) + none[Int].map2Eval(bomb)(_ + _).value should ===(None) } - test("toOptionT consistency"){ - List(false) should === (1.some.toOptionT[List].isEmpty) - List(true) should === (Option.empty[Int].toOptionT[List].isEmpty) + test("toOptionT consistency") { + List(false) should ===(1.some.toOptionT[List].isEmpty) + List(true) should ===(Option.empty[Int].toOptionT[List].isEmpty) } } diff --git a/tests/src/test/scala/cats/tests/OptionTSuite.scala b/tests/src/test/scala/cats/tests/OptionTSuite.scala index d8bb1474ffd..62801dab91d 100644 --- a/tests/src/test/scala/cats/tests/OptionTSuite.scala +++ b/tests/src/test/scala/cats/tests/OptionTSuite.scala @@ -9,32 +9,29 @@ import cats.laws.discipline.arbitrary._ import cats.laws.discipline.eq._ class OptionTSuite extends CatsSuite { - implicit val iso = SemigroupalTests.Isomorphisms.invariant[OptionT[ListWrapper, ?]](OptionT.catsDataFunctorForOptionT(ListWrapper.functor)) + implicit val iso = SemigroupalTests.Isomorphisms + .invariant[OptionT[ListWrapper, ?]](OptionT.catsDataFunctorForOptionT(ListWrapper.functor)) checkAll("OptionT[Eval, ?]", DeferTests[OptionT[Eval, ?]].defer[Int]) checkAll("OptionT[Eval, ?]", FunctorFilterTests[OptionT[Eval, ?]].functorFilter[Int, Int, Int]) - { //If a Functor for F is defined implicit val F = ListWrapper.functor - checkAll("OptionT[ListWrapper, ?]", - FunctorFilterTests[OptionT[ListWrapper, ?]].functorFilter[Int, Int, Int]) + checkAll("OptionT[ListWrapper, ?]", FunctorFilterTests[OptionT[ListWrapper, ?]].functorFilter[Int, Int, Int]) checkAll("FunctorFilter[OptionT[ListWrapper, ?]]", - SerializableTests.serializable(FunctorFilter[OptionT[ListWrapper, ?]])) + SerializableTests.serializable(FunctorFilter[OptionT[ListWrapper, ?]])) } - { //If a Traverse for F is defined implicit val F = ListWrapper.traverse - checkAll("OptionT[ListWrapper, ?]", - TraverseFilterTests[OptionT[ListWrapper, ?]].traverseFilter[Int, Int, Int]) + checkAll("OptionT[ListWrapper, ?]", TraverseFilterTests[OptionT[ListWrapper, ?]].traverseFilter[Int, Int, Int]) checkAll("TraverseFilter[OptionT[ListWrapper, ?]]", - SerializableTests.serializable(TraverseFilter[OptionT[ListWrapper, ?]])) + SerializableTests.serializable(TraverseFilter[OptionT[ListWrapper, ?]])) } @@ -49,7 +46,8 @@ class OptionTSuite extends CatsSuite { implicit val F = ListWrapper.partialOrder[Option[Int]] checkAll("OptionT[ListWrapper, Int]", PartialOrderTests[OptionT[ListWrapper, Int]].partialOrder) - checkAll("PartialOrder[OptionT[ListWrapper, Int]]", SerializableTests.serializable(PartialOrder[OptionT[ListWrapper, Int]])) + checkAll("PartialOrder[OptionT[ListWrapper, Int]]", + SerializableTests.serializable(PartialOrder[OptionT[ListWrapper, Int]])) Eq[OptionT[ListWrapper, Int]] } @@ -93,9 +91,10 @@ class OptionTSuite extends CatsSuite { { // F has a ContravariantMonoidal - checkAll("OptionT[Const[String, ?], Int]", ContravariantMonoidalTests[OptionT[Const[String, ?], ?]].contravariantMonoidal[Int, Int, Int]) + checkAll("OptionT[Const[String, ?], Int]", + ContravariantMonoidalTests[OptionT[Const[String, ?], ?]].contravariantMonoidal[Int, Int, Int]) checkAll("ContravariantMonoidal[OptionT[Const[String, ?], Int]]", - SerializableTests.serializable(ContravariantMonoidal[OptionT[Const[String, ?], ?]])) + SerializableTests.serializable(ContravariantMonoidal[OptionT[Const[String, ?], ?]])) } { @@ -128,7 +127,6 @@ class OptionTSuite extends CatsSuite { implicit val monadError = OptionT.catsDataMonadErrorForOptionT[SEither, String] - checkAll("OptionT[Either[String, ?], Int]", MonadErrorTests[OptionT[SEither, ?], String].monadError[Int, Int, Int]) checkAll("MonadError[OptionT[Either[String, ?], ?]]", SerializableTests.serializable(monadError)) @@ -151,7 +149,8 @@ class OptionTSuite extends CatsSuite { // F has a Traverse implicit val F = ListWrapper.traverse - checkAll("OptionT[ListWrapper, Int] with Option", TraverseTests[OptionT[ListWrapper, ?]].traverse[Int, Int, Int, Int, Option, Option]) + checkAll("OptionT[ListWrapper, Int] with Option", + TraverseTests[OptionT[ListWrapper, ?]].traverse[Int, Int, Int, Int, Option, Option]) checkAll("Traverse[OptionT[ListWrapper, ?]]", SerializableTests.serializable(Traverse[OptionT[ListWrapper, ?]])) Foldable[OptionT[ListWrapper, ?]] @@ -160,7 +159,7 @@ class OptionTSuite extends CatsSuite { } { - // F[Option[A]] has a monoid + // F[Option[A]] has a monoid implicit val FA: Monoid[ListWrapper[Option[Int]]] = ListWrapper.monoid[Option[Int]] checkAll("OptionT[ListWrapper, Int]", MonoidTests[OptionT[ListWrapper, Int]].monoid) @@ -174,7 +173,8 @@ class OptionTSuite extends CatsSuite { implicit val FA: Semigroup[ListWrapper[Option[Int]]] = ListWrapper.semigroup[Option[Int]] checkAll("OptionT[ListWrapper, Int]", SemigroupTests[OptionT[ListWrapper, Int]].semigroup) - checkAll("Semigroup[OptionT[ListWrapper, Int]]", SerializableTests.serializable(Semigroup[OptionT[ListWrapper, Int]])) + checkAll("Semigroup[OptionT[ListWrapper, Int]]", + SerializableTests.serializable(Semigroup[OptionT[ListWrapper, Int]])) } { @@ -186,127 +186,131 @@ class OptionTSuite extends CatsSuite { test("fold and cata consistent") { forAll { (o: OptionT[List, Int], s: String, f: Int => String) => - o.fold(s)(f) should === (o.cata(s, f)) + o.fold(s)(f) should ===(o.cata(s, f)) } } test("OptionT[Id, A].fold consistent with Option.fold") { forAll { (o: Option[Int], s: String, f: Int => String) => - o.fold(s)(f) should === (OptionT[Id, Int](o).fold(s)(f)) + o.fold(s)(f) should ===(OptionT[Id, Int](o).fold(s)(f)) } } test("OptionT[Id, A].getOrElse consistent with Option.getOrElse") { forAll { (o: Option[Int], i: Int) => - o.getOrElse(i) should === (OptionT[Id, Int](o).getOrElse(i)) + o.getOrElse(i) should ===(OptionT[Id, Int](o).getOrElse(i)) } } test("OptionT[Id, A].getOrElse consistent with Option.getOrElse, with respect to types") { forAll { (o: Option[Int]) => - o.map(Right.apply).getOrElse(Left("error")) should === (OptionT[Id, Int](o).map(Right.apply).getOrElse("error".asLeft[Int])) + o.map(Right.apply).getOrElse(Left("error")) should ===( + OptionT[Id, Int](o).map(Right.apply).getOrElse("error".asLeft[Int]) + ) } } test("OptionT[Id, A].getOrElseF consistent with Option.getOrElse") { forAll { (o: Option[Int], i: Int) => - o.getOrElse(i) should === (OptionT[Id, Int](o).getOrElseF(i)) + o.getOrElse(i) should ===(OptionT[Id, Int](o).getOrElseF(i)) } } test("OptionT[Id, A].getOrElseF consistent with Option.getOrElse, with respect to types") { forAll { (o: Option[Int]) => - o.map(Right.apply).getOrElse(Left("error")) should === (OptionT[Id, Int](o).map(Right.apply).getOrElseF("error".asLeft[Int])) + o.map(Right.apply).getOrElse(Left("error")) should ===( + OptionT[Id, Int](o).map(Right.apply).getOrElseF("error".asLeft[Int]) + ) } } test("OptionT[Id, A].collect consistent with Option.collect") { forAll { (o: Option[Int], f: Int => Option[String]) => val p = Function.unlift(f) - o.collect(p) should === (OptionT[Id, Int](o).collect(p).value) + o.collect(p) should ===(OptionT[Id, Int](o).collect(p).value) } } test("OptionT[Id, A].exists consistent with Option.exists") { forAll { (o: Option[Int], f: Int => Boolean) => - o.exists(f) should === (OptionT[Id, Int](o).exists(f)) + o.exists(f) should ===(OptionT[Id, Int](o).exists(f)) } } test("OptionT[Id, A].filter consistent with Option.filter") { forAll { (o: Option[Int], f: Int => Boolean) => - o.filter(f) should === (OptionT[Id, Int](o).filter(f).value) + o.filter(f) should ===(OptionT[Id, Int](o).filter(f).value) } } - test("OptionT[Id, A].withFilter consistent with Option.withFilter"){ + test("OptionT[Id, A].withFilter consistent with Option.withFilter") { forAll { (o: Option[Int], f: Int => Boolean) => - (for {x <- o if f(x)} yield x) should === ((for {x <- OptionT[Id, Int](o) if f(x)} yield x).value) + (for { x <- o if f(x) } yield x) should ===((for { x <- OptionT[Id, Int](o) if f(x) } yield x).value) } } test("OptionT[Id, A].filterNot consistent with Option.filterNot") { forAll { (o: Option[Int], f: Int => Boolean) => - o.filterNot(f) should === (OptionT[Id, Int](o).filterNot(f).value) + o.filterNot(f) should ===(OptionT[Id, Int](o).filterNot(f).value) } } test("OptionT[Id, A].forall consistent with Option.forall") { forAll { (o: Option[Int], f: Int => Boolean) => - o.forall(f) should === (OptionT[Id, Int](o).forall(f)) + o.forall(f) should ===(OptionT[Id, Int](o).forall(f)) } } test("OptionT[Id, A].isDefined consistent with Option.isDefined") { forAll { o: Option[Int] => - o.isDefined should === (OptionT[Id, Int](o).isDefined) + o.isDefined should ===(OptionT[Id, Int](o).isDefined) } } test("OptionT[Id, A].isEmpty consistent with Option.isEmpty") { forAll { o: Option[Int] => - o.isEmpty should === (OptionT[Id, Int](o).isEmpty) + o.isEmpty should ===(OptionT[Id, Int](o).isEmpty) } } test("orElse and orElseF consistent") { forAll { (o1: OptionT[List, Int], o2: OptionT[List, Int]) => - o1.orElse(o2) should === (o1.orElseF(o2.value)) + o1.orElse(o2) should ===(o1.orElseF(o2.value)) } } test("flatMap and flatMapF consistent") { - forAll { (optionT: OptionT[List, Int], f: Int => OptionT[List, Int]) => - optionT.flatMap(f) should === (optionT.flatMapF(f(_).value)) + forAll { (optionT: OptionT[List, Int], f: Int => OptionT[List, Int]) => + optionT.flatMap(f) should ===(optionT.flatMapF(f(_).value)) } } test("OptionT[Id, A].toRight consistent with Either.fromOption") { forAll { (o: OptionT[Id, Int], s: String) => - o.toRight(s).value should === (Either.fromOption(o.value, s)) + o.toRight(s).value should ===(Either.fromOption(o.value, s)) } } test("toRight consistent with isDefined") { forAll { (o: OptionT[List, Int], s: String) => - o.toRight(s).isRight should === (o.isDefined) + o.toRight(s).isRight should ===(o.isDefined) } } test("toLeft consistent with isDefined") { forAll { (o: OptionT[List, Int], s: String) => - o.toLeft(s).isLeft should === (o.isDefined) + o.toLeft(s).isLeft should ===(o.isDefined) } } test("isDefined is negation of isEmpty") { forAll { (o: OptionT[List, Int]) => - o.isDefined should === (o.isEmpty.map(! _)) + o.isDefined should ===(o.isEmpty.map(!_)) } } test("fromOption") { forAll { (o: Option[Int]) => - List(o) should === (OptionT.fromOption[List](o).value) + List(o) should ===(OptionT.fromOption[List](o).value) } } @@ -318,42 +322,42 @@ class OptionTSuite extends CatsSuite { test("show") { val either: Either[String, Option[Int]] = Either.right(Some(1)) - OptionT[Either[String, ?], Int](either).show should === ("Right(Some(1))") + OptionT[Either[String, ?], Int](either).show should ===("Right(Some(1))") } test("none") { - OptionT.none[List, Int] should === (OptionT[List, Int](List(None))) + OptionT.none[List, Int] should ===(OptionT[List, Int](List(None))) } test("implicit Show[OptionT] instance and explicit show method are consistent") { forAll { optionT: OptionT[List, Int] => - optionT.show should === (implicitly[Show[OptionT[List, Int]]].show(optionT)) + optionT.show should ===(implicitly[Show[OptionT[List, Int]]].show(optionT)) } } test("transform consistent with value.map") { forAll { (o: OptionT[List, Int], f: Option[Int] => Option[String]) => - o.transform(f) should === (OptionT(o.value.map(f))) + o.transform(f) should ===(OptionT(o.value.map(f))) } } test("flatTransform consistent with value.flatMap") { forAll { (o: OptionT[List, Int], f: Option[Int] => List[Option[String]]) => - o.flatTransform(f) should === (OptionT(o.value.flatMap(f))) + o.flatTransform(f) should ===(OptionT(o.value.flatMap(f))) } } test("mapK consistent with f(value)+pure") { val f: List ~> Option = λ[List ~> Option](_.headOption) forAll { (optiont: OptionT[List, Int]) => - optiont.mapK(f) should === (OptionT(f(optiont.value))) + optiont.mapK(f) should ===(OptionT(f(optiont.value))) } } test("semiflatMap consistent with value.flatMap+f+pure") { forAll { (o: OptionT[List, Int], f: Int => List[String]) => - o.semiflatMap(f) should === (OptionT(o.value.flatMap { - case None => List(None) + o.semiflatMap(f) should ===(OptionT(o.value.flatMap { + case None => List(None) case Some(a) => f(a).map(Some(_)) })) } @@ -361,20 +365,20 @@ class OptionTSuite extends CatsSuite { test("subflatMap consistent with value.map+flatMap") { forAll { (o: OptionT[List, Int], f: Int => Option[String]) => - o.subflatMap(f) should === (OptionT(o.value.map(_.flatMap(f)))) + o.subflatMap(f) should ===(OptionT(o.value.map(_.flatMap(f)))) } } test("mapFilter consistent with subflatMap") { forAll { (o: OptionT[List, Int], f: Int => Option[String]) => - o.mapFilter(f) should === (o.subflatMap(f)) + o.mapFilter(f) should ===(o.subflatMap(f)) } } /** - * Testing that implicit resolution works. If it compiles, the "test" passes. - */ - object ImplicitResolution{ + * Testing that implicit resolution works. If it compiles, the "test" passes. + */ + object ImplicitResolution { Eq[OptionT[List, Int]] PartialOrder[OptionT[List, Int]] Order[OptionT[List, Int]] diff --git a/tests/src/test/scala/cats/tests/OrderSuite.scala b/tests/src/test/scala/cats/tests/OrderSuite.scala index db973db828e..44f4e3c9257 100644 --- a/tests/src/test/scala/cats/tests/OrderSuite.scala +++ b/tests/src/test/scala/cats/tests/OrderSuite.scala @@ -22,22 +22,22 @@ class OrderSuite extends CatsSuite { checkAll("Order", ContravariantMonoidalTests[Order].contravariantMonoidal[Int, Int, Int]) checkAll("ContravariantMonoidal[Order]", SerializableTests.serializable(ContravariantMonoidal[Order])) - test("order ops syntax"){ + test("order ops syntax") { forAll { (i: Ord, j: Ord) => - (i compare j) should ===(Order.compare(i, j)) - (i min j) should ===(Order.min(i, j)) - (i max j) should === (Order.max(i, j)) - (i comparison j) should ===(Order.comparison(i, j)) + (i.compare(j)) should ===(Order.compare(i, j)) + (i.min(j)) should ===(Order.min(i, j)) + (i.max(j)) should ===(Order.max(i, j)) + (i.comparison(j)) should ===(Order.comparison(i, j)) // partial order syntax should also work when an Order instance exists (i > j) should ===(PartialOrder.gt(i, j)) (i >= j) should ===(PartialOrder.gteqv(i, j)) (i < j) should ===(PartialOrder.lt(i, j)) (i <= j) should ===(PartialOrder.lteqv(i, j)) - (i partialCompare j) should ===(PartialOrder.partialCompare(i, j)) - (i tryCompare j) should ===(PartialOrder.tryCompare(i, j)) - (i pmin j) should ===(PartialOrder.pmin(i, j)) - (i pmax j) should ===(PartialOrder.pmax(i, j)) + (i.partialCompare(j)) should ===(PartialOrder.partialCompare(i, j)) + (i.tryCompare(j)) should ===(PartialOrder.tryCompare(i, j)) + (i.pmin(j)) should ===(PartialOrder.pmin(i, j)) + (i.pmax(j)) should ===(PartialOrder.pmax(i, j)) } } } diff --git a/tests/src/test/scala/cats/tests/OrderingSuite.scala b/tests/src/test/scala/cats/tests/OrderingSuite.scala index 42e8323de5e..1996e01b64b 100644 --- a/tests/src/test/scala/cats/tests/OrderingSuite.scala +++ b/tests/src/test/scala/cats/tests/OrderingSuite.scala @@ -1,7 +1,6 @@ package cats package tests - import cats.laws.discipline.arbitrary._ import cats.laws.discipline._ import cats.laws.discipline.eq._ @@ -16,8 +15,6 @@ class OrderingSuite extends CatsSuite { checkAll("Contravariant[Ordering]", ContravariantTests[Ordering].contravariant[Int, Int, Int]) checkAll("Semigroupal[Ordering]", SemigroupalTests[Ordering].semigroupal[Int, Int, Int]) - checkAll("ContravariantMonoidal[Ordering]", - ContravariantMonoidalTests[Ordering].contravariantMonoidal[Int, Int, Int]) - checkAll("ContravariantMonoidal[Ordering]", - SerializableTests.serializable(ContravariantMonoidal[Ordering])) + checkAll("ContravariantMonoidal[Ordering]", ContravariantMonoidalTests[Ordering].contravariantMonoidal[Int, Int, Int]) + checkAll("ContravariantMonoidal[Ordering]", SerializableTests.serializable(ContravariantMonoidal[Ordering])) } diff --git a/tests/src/test/scala/cats/tests/ParallelSuite.scala b/tests/src/test/scala/cats/tests/ParallelSuite.scala index 9b93b5fcd74..f99728ac68e 100644 --- a/tests/src/test/scala/cats/tests/ParallelSuite.scala +++ b/tests/src/test/scala/cats/tests/ParallelSuite.scala @@ -6,7 +6,7 @@ import cats.data.NonEmptyList.ZipNonEmptyList import cats.data.NonEmptyVector.ZipNonEmptyVector import cats.data._ import org.scalatest.FunSuite -import cats.laws.discipline.{ApplicativeErrorTests, NonEmptyParallelTests, SerializableTests, ParallelTests} +import cats.laws.discipline.{ApplicativeErrorTests, NonEmptyParallelTests, ParallelTests, SerializableTests} import cats.laws.discipline.eq._ import cats.laws.discipline.arbitrary._ import org.scalacheck.Arbitrary @@ -15,65 +15,69 @@ import scala.collection.immutable.SortedSet class ParallelSuite extends CatsSuite with ApplicativeErrorForEitherTest { - test("ParSequence Either should accumulate errors") { forAll { es: List[Either[String, Int]] => - val lefts = es.collect { - case Left(e) => e - }.foldMap(identity) + val lefts = es + .collect { + case Left(e) => e + } + .foldMap(identity) - es.parSequence.fold(identity, i => Monoid[String].empty) should === (lefts) + es.parSequence.fold(identity, i => Monoid[String].empty) should ===(lefts) } } test("ParSequence Ior should accumulate errors") { forAll { es: List[Ior[String, Int]] => - val lefts = es.map(_.left).collect { - case Some(e) => e - }.foldMap(identity) - es.parSequence.left.getOrElse(Monoid[String].empty) should === (lefts) + val lefts = es + .map(_.left) + .collect { + case Some(e) => e + } + .foldMap(identity) + es.parSequence.left.getOrElse(Monoid[String].empty) should ===(lefts) } } test("ParSequence Ior should sequence values") { forAll { es: List[Ior[String, Int]] => - es.parSequence.right should === (es.map(_.toOption).sequence) + es.parSequence.right should ===(es.map(_.toOption).sequence) } } test("ParTraverse identity should be equivalent to parSequence") { forAll { es: List[Either[String, Int]] => - es.parTraverse(identity) should === (es.parSequence) + es.parTraverse(identity) should ===(es.parSequence) } } test("ParTraverse_ identity should be equivalent to parSequence_") { forAll { es: SortedSet[Either[String, Int]] => - Parallel.parTraverse_(es)(identity) should === (Parallel.parSequence_(es)) + Parallel.parTraverse_(es)(identity) should ===(Parallel.parSequence_(es)) } } test("ParTraverse_ syntax should be equivalent to Parallel.parTraverse_") { forAll { es: SortedSet[Either[String, Int]] => - Parallel.parTraverse_(es)(identity) should === (es.parTraverse_(identity)) + Parallel.parTraverse_(es)(identity) should ===(es.parTraverse_(identity)) } } test("ParSequence_ syntax should be equivalent to Parallel.parSequence_") { forAll { es: SortedSet[Either[String, Int]] => - Parallel.parSequence_(es) should === (es.parSequence_) + Parallel.parSequence_(es) should ===(es.parSequence_) } } test("ParNonEmptyTraverse identity should be equivalent to parNonEmptySequence") { forAll { es: NonEmptyVector[Either[String, Int]] => - Parallel.parNonEmptyTraverse(es)(identity) should === (Parallel.parNonEmptySequence(es)) + Parallel.parNonEmptyTraverse(es)(identity) should ===(Parallel.parNonEmptySequence(es)) } } test("ParNonEmptyTraverse_ identity should be equivalent to parNonEmptySequence_") { forAll { es: NonEmptyList[Either[String, Int]] => - Parallel.parNonEmptyTraverse_(es)(identity) should === (Parallel.parNonEmptySequence_(es)) + Parallel.parNonEmptyTraverse_(es)(identity) should ===(Parallel.parNonEmptySequence_(es)) } } @@ -81,19 +85,19 @@ class ParallelSuite extends CatsSuite with ApplicativeErrorForEitherTest { forAll { es: List[Either[String, Int]] => val f: Int => List[Int] = i => List(i, i + 1) Parallel.parFlatTraverse(es)(e => e.map(f)) should - === (es.parTraverse(e => e.map(f)).map(_.flatten)) + ===(es.parTraverse(e => e.map(f)).map(_.flatten)) } } test("ParFlatTraverse identity should be equivalent to parFlatSequence") { forAll { es: List[Either[String, List[Int]]] => - Parallel.parFlatTraverse(es)(identity) should === (Parallel.parFlatSequence(es)) + Parallel.parFlatTraverse(es)(identity) should ===(Parallel.parFlatSequence(es)) } } test("ParFlatSequence syntax should be equivalent to Parallel.parFlatSequence") { forAll { es: List[Either[String, List[Int]]] => - es.parFlatSequence should === (Parallel.parFlatSequence(es)) + es.parFlatSequence should ===(Parallel.parFlatSequence(es)) } } @@ -101,7 +105,7 @@ class ParallelSuite extends CatsSuite with ApplicativeErrorForEitherTest { forAll { es: List[Either[String, Int]] => val f: Int => List[Int] = i => List(i, i + 1) Parallel.parFlatTraverse(es)(e => e.map(f)) should - === (es.parFlatTraverse(e => e.map(f))) + ===(es.parFlatTraverse(e => e.map(f))) } } @@ -109,25 +113,25 @@ class ParallelSuite extends CatsSuite with ApplicativeErrorForEitherTest { forAll { es: NonEmptyList[Either[String, Int]] => val f: Int => NonEmptyList[Int] = i => NonEmptyList.of(i, i + 1) Parallel.parNonEmptyFlatTraverse(es)(e => e.map(f)) should - === (Parallel.parNonEmptyTraverse(es)(e => e.map(f)).map(_.flatten)) + ===(Parallel.parNonEmptyTraverse(es)(e => e.map(f)).map(_.flatten)) } } test("ParNonEmptyFlatTraverse identity should be equivalent to parNonEmptyFlatSequence") { forAll { es: NonEmptyList[Either[String, NonEmptyList[Int]]] => - Parallel.parNonEmptyFlatTraverse(es)(identity) should === (Parallel.parNonEmptyFlatSequence(es)) + Parallel.parNonEmptyFlatTraverse(es)(identity) should ===(Parallel.parNonEmptyFlatSequence(es)) } } test("parAp accumulates errors in order") { val right: Either[String, Int => Int] = Left("Hello") - Parallel.parAp(right)("World".asLeft) should === (Left("HelloWorld")) + Parallel.parAp(right)("World".asLeft) should ===(Left("HelloWorld")) } test("parAp2 accumulates errors in order") { val plus = (_: Int) + (_: Int) val rightPlus: Either[String, (Int, Int) => Int] = Right(plus) - Parallel.parAp2(rightPlus)("Hello".asLeft, "World".asLeft) should === (Left("HelloWorld")) + Parallel.parAp2(rightPlus)("Hello".asLeft, "World".asLeft) should ===(Left("HelloWorld")) } test("Kleisli with Either should accumulate errors") { @@ -135,7 +139,7 @@ class ParallelSuite extends CatsSuite with ApplicativeErrorForEitherTest { val k2: Kleisli[Either[String, ?], String, Int] = Kleisli(s => Left("Boo")) val k3: Kleisli[Either[String, ?], String, Int] = Kleisli(s => Left("Nope")) - (List(k1,k2,k3).parSequence.run("Hello")) should === (Left("BooNope")) + (List(k1, k2, k3).parSequence.run("Hello")) should ===(Left("BooNope")) } @@ -143,55 +147,67 @@ class ParallelSuite extends CatsSuite with ApplicativeErrorForEitherTest { val w1: WriterT[Either[String, ?], String, Int] = WriterT.liftF(Left("Too ")) val w2: WriterT[Either[String, ?], String, Int] = WriterT.liftF(Left("bad.")) - ((w1,w2).parMapN(_ + _).value) should === (Left("Too bad.")) + ((w1, w2).parMapN(_ + _).value) should ===(Left("Too bad.")) } test("ParMap over NonEmptyList should be consistent with zip") { forAll { (as: NonEmptyList[Int], bs: NonEmptyList[Int], cs: NonEmptyList[Int]) => - (as, bs, cs).parMapN(_ + _ + _) should === (as.zipWith(bs)(_ + _).zipWith(cs)(_ + _)) + (as, bs, cs).parMapN(_ + _ + _) should ===(as.zipWith(bs)(_ + _).zipWith(cs)(_ + _)) } } test("ParMap over NonEmptyVector should be consistent with zip") { forAll { (as: NonEmptyVector[Int], bs: NonEmptyVector[Int], cs: NonEmptyVector[Int]) => - (as, bs, cs).parMapN(_ + _ + _) should === (as.zipWith(bs)(_ + _).zipWith(cs)(_ + _)) + (as, bs, cs).parMapN(_ + _ + _) should ===(as.zipWith(bs)(_ + _).zipWith(cs)(_ + _)) } } test("ParMap over List should be consistent with zip") { forAll { (as: List[Int], bs: List[Int], cs: List[Int]) => - val zipped = as.zip(bs).map { - case (a, b) => a + b - }.zip(cs).map { - case (a, b) => a + b - } + val zipped = as + .zip(bs) + .map { + case (a, b) => a + b + } + .zip(cs) + .map { + case (a, b) => a + b + } - (as, bs, cs).parMapN(_ + _ + _) should === (zipped) + (as, bs, cs).parMapN(_ + _ + _) should ===(zipped) } } test("ParMap over Vector should be consistent with zip") { forAll { (as: Vector[Int], bs: Vector[Int], cs: Vector[Int]) => - val zipped = as.zip(bs).map { - case (a, b) => a + b - }.zip(cs).map { - case (a, b) => a + b - } + val zipped = as + .zip(bs) + .map { + case (a, b) => a + b + } + .zip(cs) + .map { + case (a, b) => a + b + } - (as, bs, cs).parMapN(_ + _ + _) should === (zipped) + (as, bs, cs).parMapN(_ + _ + _) should ===(zipped) } } test("ParMap over Stream should be consistent with zip") { forAll { (as: Stream[Int], bs: Stream[Int], cs: Stream[Int]) => - val zipped = as.zip(bs).map { - case (a, b) => a + b - }.zip(cs).map { - case (a, b) => a + b - } + val zipped = as + .zip(bs) + .map { + case (a, b) => a + b + } + .zip(cs) + .map { + case (a, b) => a + b + } - (as, bs, cs).parMapN(_ + _ + _) should === (zipped) + (as, bs, cs).parMapN(_ + _ + _) should ===(zipped) } } @@ -221,28 +237,28 @@ class ParallelSuite extends CatsSuite with ApplicativeErrorForEitherTest { test("ParTupled of Stream should be consistent with ParMap of Tuple.apply") { forAll { (fa: Stream[Int], fb: Stream[Int], fc: Stream[Int], fd: Stream[Int]) => - (fa, fb, fc, fd).parTupled should === ((fa, fb, fc, fd).parMapN(Tuple4.apply)) + (fa, fb, fc, fd).parTupled should ===((fa, fb, fc, fd).parMapN(Tuple4.apply)) } } test("ParTupled of List should be consistent with zip") { forAll { (fa: List[Int], fb: List[Int], fc: List[Int], fd: List[Int]) => - (fa, fb, fc, fd).parTupled should === (fa.zip(fb).zip(fc).zip(fd).map { case (((a, b), c), d) => (a, b, c, d) }) + (fa, fb, fc, fd).parTupled should ===(fa.zip(fb).zip(fc).zip(fd).map { case (((a, b), c), d) => (a, b, c, d) }) } } test("ParTupled of Vector should be consistent with zip") { forAll { (fa: Vector[Int], fb: Vector[Int], fc: Vector[Int], fd: Vector[Int]) => - (fa, fb, fc, fd).parTupled should === (fa.zip(fb).zip(fc).zip(fd).map { case (((a, b), c), d) => (a, b, c, d) }) + (fa, fb, fc, fd).parTupled should ===(fa.zip(fb).zip(fc).zip(fd).map { case (((a, b), c), d) => (a, b, c, d) }) } } test("ParTupled of Stream should be consistent with zip") { forAll { (fa: Stream[Int], fb: Stream[Int], fc: Stream[Int], fd: Stream[Int]) => - (fa, fb, fc, fd).parTupled should === (fa.zip(fb).zip(fc).zip(fd).map { case (((a, b), c), d) => (a, b, c, d) }) + (fa, fb, fc, fd).parTupled should ===(fa.zip(fb).zip(fc).zip(fd).map { case (((a, b), c), d) => (a, b, c, d) }) } } - + test("IorT leverages parallel effect instances when it exists") { case class Marker(value: String) extends Exception("marker") { override def fillInStackTrace: Throwable = null @@ -251,7 +267,7 @@ class ParallelSuite extends CatsSuite with ApplicativeErrorForEitherTest { def checkMarker[A](f: => A): Option[String] = try { f; None } catch { case marker: Marker => marker.value.some - case _: Throwable => None + case _: Throwable => None } final case class Effect[A](value: A) @@ -271,10 +287,9 @@ class ParallelSuite extends CatsSuite with ApplicativeErrorForEitherTest { def monad: Monad[Effect] = monadInstance } - val iorts: List[IorT[Effect, String, Int]] = List( - IorT.leftT("hello")(monadInstance), - IorT.bothT(" world", 404)(monadInstance), - IorT.rightT(123)(monadInstance)) + val iorts: List[IorT[Effect, String, Int]] = List(IorT.leftT("hello")(monadInstance), + IorT.bothT(" world", 404)(monadInstance), + IorT.rightT(123)(monadInstance)) val resultSansInstance = { implicit val ev0 = monadInstance @@ -286,41 +301,67 @@ class ParallelSuite extends CatsSuite with ApplicativeErrorForEitherTest { checkMarker(iorts.parSequence) } - resultSansInstance should === ("sequential".some) - resultWithInstance should === ("parallel".some) - } - - checkAll("Parallel[Either[String, ?], Validated[String, ?]]", ParallelTests[Either[String, ?], Validated[String, ?]].parallel[Int, String]) - checkAll("Parallel[Ior[String, ?], Ior[String, ?]]", ParallelTests[Ior[String, ?], Ior[String, ?]].parallel[Int, String]) - checkAll("Parallel[IorT[F, String, ?], IorT[F, String, ?]] with parallel effect", ParallelTests[IorT[Either[String, ?], String, ?], IorT[Validated[String, ?], String, ?]].parallel[Int, String]) - checkAll("Parallel[IorT[F, String, ?], IorT[F, String, ?]] with sequential effect", ParallelTests[IorT[Option, String, ?], IorT[Option, String, ?]].parallel[Int, String]) - checkAll("Parallel[OptionT[M, ?], Nested[F, Option, ?]]", ParallelTests[OptionT[Either[String, ?], ?], Nested[Validated[String, ?], Option, ?]].parallel[Int, String]) - checkAll("Parallel[EitherT[M, String, ?], Nested[F, Validated[String, ?], ?]]", ParallelTests[EitherT[Either[String, ?], String, ?], Nested[Validated[String, ?], Validated[String, ?], ?]].parallel[Int, String]) - checkAll("Parallel[EitherT[Option, String, ?], Nested[Option, Validated[String, ?], ?]]", ParallelTests[EitherT[Option, String, ?], Nested[Option, Validated[String, ?], ?]].parallel[Int, String]) - checkAll("Parallel[WriterT[M, Int, ?], WriterT[F, Int, ?]]", ParallelTests[WriterT[Either[String, ?], Int, ?], WriterT[Validated[String, ?], Int, ?]].parallel[Int, String]) - checkAll("NonEmptyParallel[Vector, ZipVector]", NonEmptyParallelTests[Vector, ZipVector].nonEmptyParallel[Int, String]) + resultSansInstance should ===("sequential".some) + resultWithInstance should ===("parallel".some) + } + + checkAll("Parallel[Either[String, ?], Validated[String, ?]]", + ParallelTests[Either[String, ?], Validated[String, ?]].parallel[Int, String]) + checkAll("Parallel[Ior[String, ?], Ior[String, ?]]", + ParallelTests[Ior[String, ?], Ior[String, ?]].parallel[Int, String]) + checkAll( + "Parallel[IorT[F, String, ?], IorT[F, String, ?]] with parallel effect", + ParallelTests[IorT[Either[String, ?], String, ?], IorT[Validated[String, ?], String, ?]].parallel[Int, String] + ) + checkAll( + "Parallel[IorT[F, String, ?], IorT[F, String, ?]] with sequential effect", + ParallelTests[IorT[Option, String, ?], IorT[Option, String, ?]].parallel[Int, String] + ) + checkAll("Parallel[OptionT[M, ?], Nested[F, Option, ?]]", + ParallelTests[OptionT[Either[String, ?], ?], Nested[Validated[String, ?], Option, ?]].parallel[Int, String]) + checkAll( + "Parallel[EitherT[M, String, ?], Nested[F, Validated[String, ?], ?]]", + ParallelTests[EitherT[Either[String, ?], String, ?], Nested[Validated[String, ?], Validated[String, ?], ?]] + .parallel[Int, String] + ) + checkAll( + "Parallel[EitherT[Option, String, ?], Nested[Option, Validated[String, ?], ?]]", + ParallelTests[EitherT[Option, String, ?], Nested[Option, Validated[String, ?], ?]].parallel[Int, String] + ) + checkAll( + "Parallel[WriterT[M, Int, ?], WriterT[F, Int, ?]]", + ParallelTests[WriterT[Either[String, ?], Int, ?], WriterT[Validated[String, ?], Int, ?]].parallel[Int, String] + ) + checkAll("NonEmptyParallel[Vector, ZipVector]", + NonEmptyParallelTests[Vector, ZipVector].nonEmptyParallel[Int, String]) checkAll("NonEmptyParallel[List, ZipList]", NonEmptyParallelTests[List, ZipList].nonEmptyParallel[Int, String]) // Can't test Parallel here, as Applicative[ZipStream].pure doesn't terminate checkAll("Parallel[Stream, ZipStream]", NonEmptyParallelTests[Stream, ZipStream].nonEmptyParallel[Int, String]) - checkAll("NonEmptyParallel[NonEmptyVector, ZipNonEmptyVector]", NonEmptyParallelTests[NonEmptyVector, ZipNonEmptyVector].nonEmptyParallel[Int, String]) - checkAll("NonEmptyParallel[NonEmptyList, ZipNonEmptyList]", NonEmptyParallelTests[NonEmptyList, ZipNonEmptyList].nonEmptyParallel[Int, String]) - checkAll("Parallel[NonEmptyStream, OneAnd[ZipStream, ?]", ParallelTests[NonEmptyStream, OneAnd[ZipStream, ?]].parallel[Int, String]) - + checkAll("NonEmptyParallel[NonEmptyVector, ZipNonEmptyVector]", + NonEmptyParallelTests[NonEmptyVector, ZipNonEmptyVector].nonEmptyParallel[Int, String]) + checkAll("NonEmptyParallel[NonEmptyList, ZipNonEmptyList]", + NonEmptyParallelTests[NonEmptyList, ZipNonEmptyList].nonEmptyParallel[Int, String]) + checkAll("Parallel[NonEmptyStream, OneAnd[ZipStream, ?]", + ParallelTests[NonEmptyStream, OneAnd[ZipStream, ?]].parallel[Int, String]) checkAll("Parallel[Id, Id]", ParallelTests[Id, Id].parallel[Int, String]) - checkAll("NonEmptyParallel[NonEmptyList, ZipNonEmptyList]", SerializableTests.serializable(NonEmptyParallel[NonEmptyList, ZipNonEmptyList])) + checkAll("NonEmptyParallel[NonEmptyList, ZipNonEmptyList]", + SerializableTests.serializable(NonEmptyParallel[NonEmptyList, ZipNonEmptyList])) - checkAll("Parallel[Either[String, ?], Validated[String, ?]]", SerializableTests.serializable(Parallel[Either[String, ?], Validated[String, ?]])) + checkAll("Parallel[Either[String, ?], Validated[String, ?]]", + SerializableTests.serializable(Parallel[Either[String, ?], Validated[String, ?]])) { 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) - checkAll("Parallel[KlesliT[M, ?], Nested[F, Option, ?]]", ParallelTests[Kleisli[Either[String, ?], Int, ?], Kleisli[Validated[String, ?], Int, ?]].parallel[Int, String]) + checkAll( + "Parallel[KlesliT[M, ?], Nested[F, Option, ?]]", + ParallelTests[Kleisli[Either[String, ?], Int, ?], Kleisli[Validated[String, ?], Int, ?]].parallel[Int, String] + ) } - } trait ApplicativeErrorForEitherTest extends FunSuite with Discipline { @@ -337,6 +378,7 @@ trait ApplicativeErrorForEitherTest extends FunSuite with Discipline { { implicit val parVal = Parallel.applicativeError[Either[String, ?], Validated[String, ?], String] - checkAll("ApplicativeError[Validated[String, Int]]", ApplicativeErrorTests[Validated[String, ?], String].applicativeError[Int, Int, Int]) + checkAll("ApplicativeError[Validated[String, Int]]", + ApplicativeErrorTests[Validated[String, ?], String].applicativeError[Int, Int, Int]) } } diff --git a/tests/src/test/scala/cats/tests/PartialOrderSuite.scala b/tests/src/test/scala/cats/tests/PartialOrderSuite.scala index 5db795ecac2..810a2ca5d9b 100644 --- a/tests/src/test/scala/cats/tests/PartialOrderSuite.scala +++ b/tests/src/test/scala/cats/tests/PartialOrderSuite.scala @@ -11,12 +11,11 @@ import cats.laws.discipline.eq._ class PartialOrderSuite extends CatsSuite { /** - * Check that two partial compare results are "the same". - * This works around the fact that `NaN` is not equal to itself. - */ - def checkPartialCompare(res1: Double, res2: Double): Assertion = { + * Check that two partial compare results are "the same". + * This works around the fact that `NaN` is not equal to itself. + */ + def checkPartialCompare(res1: Double, res2: Double): Assertion = (res1 == res2 || (res1.isNaN && res2.isNaN)) should ===(true) - } { Invariant[PartialOrder] @@ -46,10 +45,10 @@ class PartialOrderSuite extends CatsSuite { (i < j) should ===(PartialOrder.lt(i, j)) (i <= j) should ===(PartialOrder.lteqv(i, j)) - checkPartialCompare(i partialCompare j, PartialOrder.partialCompare(i, j)) - (i tryCompare j) should ===(PartialOrder.tryCompare(i, j)) - (i pmin j) should ===(PartialOrder.pmin(i, j)) - (i pmax j) should ===(PartialOrder.pmax(i, j)) + checkPartialCompare(i.partialCompare(j), PartialOrder.partialCompare(i, j)) + (i.tryCompare(j)) should ===(PartialOrder.tryCompare(i, j)) + (i.pmin(j)) should ===(PartialOrder.pmin(i, j)) + (i.pmax(j)) should ===(PartialOrder.pmax(i, j)) } } } diff --git a/tests/src/test/scala/cats/tests/PartialOrderingSuite.scala b/tests/src/test/scala/cats/tests/PartialOrderingSuite.scala index 4e1c99d6579..631f297537d 100644 --- a/tests/src/test/scala/cats/tests/PartialOrderingSuite.scala +++ b/tests/src/test/scala/cats/tests/PartialOrderingSuite.scala @@ -1,7 +1,6 @@ package cats package tests - import cats.laws.discipline.arbitrary._ import cats.laws.discipline._ import cats.laws.discipline.eq._ @@ -18,5 +17,6 @@ class PartialOrderingSuite extends CatsSuite { checkAll("Contravariant[PartialOrdering]", SerializableTests.serializable(Contravariant[PartialOrdering])) checkAll("PartialOrdering[Int]", ContravariantMonoidalTests[PartialOrdering].contravariantMonoidal[Int, Int, Int]) - checkAll("ContravariantMonoidal[PartialOrdering]", SerializableTests.serializable(ContravariantMonoidal[PartialOrdering])) + checkAll("ContravariantMonoidal[PartialOrdering]", + SerializableTests.serializable(ContravariantMonoidal[PartialOrdering])) } diff --git a/tests/src/test/scala/cats/tests/QueueSuite.scala b/tests/src/test/scala/cats/tests/QueueSuite.scala index aa75a474d2d..a6320224658 100644 --- a/tests/src/test/scala/cats/tests/QueueSuite.scala +++ b/tests/src/test/scala/cats/tests/QueueSuite.scala @@ -3,7 +3,14 @@ package tests import scala.collection.immutable.Queue -import cats.laws.discipline.{CoflatMapTests, MonadTests, AlternativeTests, SerializableTests, TraverseTests, SemigroupalTests} +import cats.laws.discipline.{ + AlternativeTests, + CoflatMapTests, + MonadTests, + SemigroupalTests, + SerializableTests, + TraverseTests +} class QueueSuite extends CatsSuite { checkAll("Queue[Int]", SemigroupalTests[Queue].semigroupal[Int, Int, Int]) @@ -22,7 +29,7 @@ class QueueSuite extends CatsSuite { checkAll("Traverse[Queue]", SerializableTests.serializable(Traverse[Queue])) test("show") { - Queue(1, 2, 3).show should === ("Queue(1, 2, 3)") - Queue.empty[Int].show should === ("Queue()") + Queue(1, 2, 3).show should ===("Queue(1, 2, 3)") + Queue.empty[Int].show should ===("Queue()") } } diff --git a/tests/src/test/scala/cats/tests/ReducibleSuite.scala b/tests/src/test/scala/cats/tests/ReducibleSuite.scala index b7d3afe4f57..d5afd6f4bcc 100644 --- a/tests/src/test/scala/cats/tests/ReducibleSuite.scala +++ b/tests/src/test/scala/cats/tests/ReducibleSuite.scala @@ -11,9 +11,9 @@ class ReducibleSuiteAdditional extends CatsSuite { if (x == 0) None else Some(acc + x) val n = 100000L - val expected = n*(n+1)/2 + val expected = n * (n + 1) / 2 val actual = (1L to n).toList.toNel.flatMap(_.reduceLeftM(Option.apply)(nonzero)) - actual should === (Some(expected)) + actual should ===(Some(expected)) } // exists method written in terms of reduceRightTo @@ -27,9 +27,9 @@ class ReducibleSuiteAdditional extends CatsSuite { def split[A](nel: NonEmptyList[A]): (A, List[A]) = (nel.head, nel.tail) } val nel = NonEmptyList.of(1, 2, 3) - R.get(nel)(1L) should === (nel.get(1L)) - R.size(nel) should === (nel.size.toLong) - R.get(nel)(4L) should === (None) + R.get(nel)(1L) should ===(nel.get(1L)) + R.size(nel) should ===(nel.size.toLong) + R.get(nel)(4L) should ===(None) } test("Reducible[NonEmptyList]") { @@ -39,20 +39,22 @@ class ReducibleSuiteAdditional extends CatsSuite { val tail = (2 to 10).toList val total = 1 + tail.sum val nel = NonEmptyList(1, tail) - R.reduceLeft(nel)(_ + _) should === (total) - R.reduceRight(nel)((x, ly) => ly.map(x + _)).value should === (total) - R.reduce(nel) should === (total) + R.reduceLeft(nel)(_ + _) should ===(total) + R.reduceRight(nel)((x, ly) => ly.map(x + _)).value should ===(total) + R.reduce(nel) should ===(total) // more basic checks val names = NonEmptyList.of("Aaron", "Betty", "Calvin", "Deirdra") val totalLength = names.toList.map(_.length).sum - R.reduceLeftTo(names)(_.length)((sum, s) => s.length + sum) should === (totalLength) - R.reduceMap(names)(_.length) should === (totalLength) + R.reduceLeftTo(names)(_.length)((sum, s) => s.length + sum) should ===(totalLength) + R.reduceMap(names)(_.length) should ===(totalLength) val sumLeftM = R.reduceLeftM(names)(Some(_): Option[String]) { (acc, x) => (Some(acc + x): Option[String]) } assert(sumLeftM == Some("AaronBettyCalvinDeirdra")) - val sumMapM = R.reduceMapM(names) { x => (Some(x): Option[String]) } + val sumMapM = R.reduceMapM(names) { x => + (Some(x): Option[String]) + } assert(sumMapM == Some("AaronBettyCalvinDeirdra")) val isNotCalvin: String => Option[String] = x => if (x == "Calvin") None else Some(x) @@ -70,9 +72,9 @@ class ReducibleSuiteAdditional extends CatsSuite { } -abstract class ReducibleSuite[F[_]: Reducible](name: String)( - implicit ArbFInt: Arbitrary[F[Int]], - ArbFString: Arbitrary[F[String]]) extends FoldableSuite[F](name) { +abstract class ReducibleSuite[F[_]: Reducible](name: String)(implicit ArbFInt: Arbitrary[F[Int]], + ArbFString: Arbitrary[F[String]]) + extends FoldableSuite[F](name) { def range(start: Long, endInclusive: Long): F[Long] @@ -81,14 +83,14 @@ abstract class ReducibleSuite[F[_]: Reducible](name: String)( if (x == 0) None else Some(acc + x) val n = 100000L - val expected = n*(n+1)/2 + val expected = n * (n + 1) / 2 val actual = range(1L, n).reduceLeftM(Option.apply)(nonzero) - actual should === (Some(expected)) + actual should ===(Some(expected)) } test(s"Reducible[$name].toNonEmptyList/toList consistency") { forAll { fa: F[Int] => - fa.toList.toNel should === (Some(fa.toNonEmptyList)) + fa.toList.toNel should ===(Some(fa.toNonEmptyList)) } } @@ -98,24 +100,23 @@ abstract class ReducibleSuite[F[_]: Reducible](name: String)( } } - test("Reducible#nonEmptyPartition retains size") { forAll { (fi: F[Int], f: Int => Either[String, String]) => val folded = fi.nonEmptyPartition(f).fold(identity, identity, _ ++ _.toList) - folded.size.toLong should === (fi.size) + folded.size.toLong should ===(fi.size) } } test("Reducible#nonEmptyPartition to one side is identity") { forAll { (fi: F[Int], f: Int => String) => - val g: Int => Either[Double, String] = f andThen Right.apply - val h: Int => Either[String, Double] = f andThen Left.apply + val g: Int => Either[Double, String] = f.andThen(Right.apply) + val h: Int => Either[String, Double] = f.andThen(Left.apply) val withG = fi.nonEmptyPartition(g).right.getOrElse(NonEmptyList.one("")) - withG should === (Reducible[F].toNonEmptyList(fi).map(f)) + withG should ===(Reducible[F].toNonEmptyList(fi).map(f)) val withH = fi.nonEmptyPartition(h).left.getOrElse(NonEmptyList.one("")) - withH should === (Reducible[F].toNonEmptyList(fi).map(f)) + withH should ===(Reducible[F].toNonEmptyList(fi).map(f)) } } diff --git a/tests/src/test/scala/cats/tests/RegressionSuite.scala b/tests/src/test/scala/cats/tests/RegressionSuite.scala index b5b9f28803c..261b1f5139a 100644 --- a/tests/src/test/scala/cats/tests/RegressionSuite.scala +++ b/tests/src/test/scala/cats/tests/RegressionSuite.scala @@ -10,13 +10,17 @@ class RegressionSuite extends CatsSuite { // not stack safe, very minimal, not for actual use case class State[S, A](run: S => (A, S)) { self => def map[B](f: A => B): State[S, B] = - State({ s => val (a, s2) = self.run(s); (f(a), s2) }) + State({ s => + val (a, s2) = self.run(s); (f(a), s2) + }) def flatMap[B](f: A => State[S, B]): State[S, B] = - State({ s => val (a, s2) = self.run(s); f(a).run(s2) }) + State({ s => + val (a, s2) = self.run(s); f(a).run(s2) + }) } object State { - implicit def instance[S]: Monad[State[S, ?]] = new Monad[State[S, ?]] with StackSafeMonad[State[S, ?]] { // lies! + implicit def instance[S]: Monad[State[S, ?]] = new Monad[State[S, ?]] with StackSafeMonad[State[S, ?]] { // lies! def pure[A](a: A): State[S, A] = State(s => (a, s)) def flatMap[A, B](sa: State[S, A])(f: A => State[S, B]): State[S, B] = sa.flatMap(f) } @@ -38,48 +42,57 @@ class RegressionSuite extends CatsSuite { // test result order val ons = List(Option(1), Option(2), Option(3)) - Traverse[List].sequence(ons) should === (Some(List(1, 2, 3))) + Traverse[List].sequence(ons) should ===(Some(List(1, 2, 3))) // test order of effects using a contrived, unsafe state monad. val names = List("Alice", "Bob", "Claire") val allocated = names.map(alloc) - val state = Traverse[List].sequence[State[Int, ?],Person](allocated) + val state = Traverse[List].sequence[State[Int, ?], Person](allocated) val (people, counter) = state.run(0) - people should === (List(Person(0, "Alice"), Person(1, "Bob"), Person(2, "Claire"))) - counter should === (3) + people should ===(List(Person(0, "Alice"), Person(1, "Bob"), Person(2, "Claire"))) + counter should ===(3) // ensure that side-effects occurred in "correct" order - buf.toList should === (names) + buf.toList should ===(names) } test("#167: confirm ap2 order") { - val twelve = Apply[State[String, ?]].ap2(State.instance[String].pure((_: Unit, _: Unit) => ()))( - State[String, Unit](s => ((), s + "1")), - State[String, Unit](s => ((), s + "2")) - ).run("")._2 - twelve should === ("12") + val twelve = Apply[State[String, ?]] + .ap2(State.instance[String].pure((_: Unit, _: Unit) => ()))( + State[String, Unit](s => ((), s + "1")), + State[String, Unit](s => ((), s + "2")) + ) + .run("") + ._2 + twelve should ===("12") } test("#167: confirm map2 order") { - val twelve = Apply[State[String, ?]].map2( - State[String, Unit](s => ((), s + "1")), - State[String, Unit](s => ((), s + "2")) - )((_: Unit, _: Unit) => ()).run("")._2 - twelve should === ("12") + val twelve = Apply[State[String, ?]] + .map2( + State[String, Unit](s => ((), s + "1")), + State[String, Unit](s => ((), s + "2")) + )((_: Unit, _: Unit) => ()) + .run("") + ._2 + twelve should ===("12") } test("#167: confirm map3 order") { - val oneTwoThree = Apply[State[String, ?]].map3( - State[String, Unit](s => ((), s + "1")), - State[String, Unit](s => ((), s + "2")), - State[String, Unit](s => ((), s + "3")) - )((_: Unit, _: Unit, _: Unit) => ()).run("")._2 - oneTwoThree should === ("123") + val oneTwoThree = Apply[State[String, ?]] + .map3( + State[String, Unit](s => ((), s + "1")), + State[String, Unit](s => ((), s + "2")), + State[String, Unit](s => ((), s + "3")) + )((_: Unit, _: Unit, _: Unit) => ()) + .run("") + ._2 + oneTwoThree should ===("123") } test("#500: foldMap - traverse consistency") { assert( - List(1,2,3).traverse(i => Const.of[List[Int]](List(i))).getConst == List(1,2,3).foldMap(List(_)) + List(1, 2, 3).traverse(i => Const.of[List[Int]](List(i))).getConst == List(1, 2, 3).foldMap(List(_)) ) } @@ -91,51 +104,50 @@ class RegressionSuite extends CatsSuite { } def checkAndResetCount(expected: Int): Unit = { - count should === (expected) + count should ===(expected) count = 0 } - List(1,2,6,8).traverse(validate) should === (Either.left("6 is greater than 5")) + List(1, 2, 6, 8).traverse(validate) should ===(Either.left("6 is greater than 5")) // shouldn't have ever evaluted validate(8) checkAndResetCount(3) - Stream(1,2,6,8).traverse(validate) should === (Either.left("6 is greater than 5")) + Stream(1, 2, 6, 8).traverse(validate) should ===(Either.left("6 is greater than 5")) checkAndResetCount(3) type StringMap[A] = SortedMap[String, A] val intMap: StringMap[Int] = SortedMap("A" -> 1, "B" -> 2, "C" -> 6, "D" -> 8) - intMap.traverse(validate) should === (Either.left("6 is greater than 5")) + intMap.traverse(validate) should ===(Either.left("6 is greater than 5")) checkAndResetCount(3) - NonEmptyList.of(1,2,6,8).traverse(validate) should === (Either.left("6 is greater than 5")) + NonEmptyList.of(1, 2, 6, 8).traverse(validate) should ===(Either.left("6 is greater than 5")) checkAndResetCount(3) - NonEmptyList.of(6,8).traverse(validate) should === (Either.left("6 is greater than 5")) + NonEmptyList.of(6, 8).traverse(validate) should ===(Either.left("6 is greater than 5")) checkAndResetCount(1) - Vector(1,2,6,8).traverse(validate) should === (Either.left("6 is greater than 5")) + Vector(1, 2, 6, 8).traverse(validate) should ===(Either.left("6 is greater than 5")) checkAndResetCount(3) - List(1,2,6,8).traverse_(validate) should === (Either.left("6 is greater than 5")) + List(1, 2, 6, 8).traverse_(validate) should ===(Either.left("6 is greater than 5")) checkAndResetCount(3) - Stream(1,2,6,8).traverse_(validate) should === (Either.left("6 is greater than 5")) + Stream(1, 2, 6, 8).traverse_(validate) should ===(Either.left("6 is greater than 5")) checkAndResetCount(3) - Vector(1,2,6,8).traverse_(validate) should === (Either.left("6 is greater than 5")) + Vector(1, 2, 6, 8).traverse_(validate) should ===(Either.left("6 is greater than 5")) checkAndResetCount(3) - NonEmptyList.of(1,2,6,7,8).traverse_(validate) should === (Either.left("6 is greater than 5")) + NonEmptyList.of(1, 2, 6, 7, 8).traverse_(validate) should ===(Either.left("6 is greater than 5")) checkAndResetCount(3) - NonEmptyList.of(6,7,8).traverse_(validate) should === (Either.left("6 is greater than 5")) + NonEmptyList.of(6, 7, 8).traverse_(validate) should ===(Either.left("6 is greater than 5")) checkAndResetCount(1) } test("#2022 EitherT syntax no long works the old way") { import data._ - EitherT.right[String](Option(1)).handleErrorWith((_: String) => EitherT.pure(2)) { @@ -143,7 +155,6 @@ class RegressionSuite extends CatsSuite { EitherT.right[String](Option(1)).handleErrorWith((_: Unit) => EitherT.pure(2)) } - } } diff --git a/tests/src/test/scala/cats/tests/RepresentableStoreSuite.scala b/tests/src/test/scala/cats/tests/RepresentableStoreSuite.scala index 2a9b08294c1..ea6a9dd1713 100644 --- a/tests/src/test/scala/cats/tests/RepresentableStoreSuite.scala +++ b/tests/src/test/scala/cats/tests/RepresentableStoreSuite.scala @@ -16,24 +16,29 @@ class RepresentableStoreSuite extends CatsSuite { implicit val arbStore = catsLawsArbitraryForRepresentableStore[λ[P => (P, P)], Boolean, Int] implicit val cogenStore = catsLawsCogenForRepresentableStore[λ[P => (P, P)], Boolean, Int] implicit val eqStore = cats.laws.discipline.eq.catsLawsEqForRepresentableStore[λ[P => (P, P)], Boolean, Int] - implicit val eqStoreStore = cats.laws.discipline.eq.catsLawsEqForRepresentableStore[λ[P => (P, P)], Boolean, RepresentableStore[λ[P => (P, P)], Boolean, Int]] - implicit val eqStoreStoreStore = cats.laws.discipline.eq.catsLawsEqForRepresentableStore[λ[P => (P, P)], Boolean, RepresentableStore[λ[P => (P, P)], Boolean, RepresentableStore[λ[P => (P, P)], Boolean, Int]]] - checkAll("Comonad[RepresentableStore[λ[P => (P, P)], Boolean, ?]]", ComonadTests[RepresentableStore[λ[P => (P, P)], Boolean, ?]].comonad[Int, Int, Int]) - - checkAll("Comonad[RepresentableStore[λ[P => (P, P)], Boolean, ?]]", SerializableTests.serializable(Comonad[RepresentableStore[λ[P => (P, P)], Boolean, ?]])) + implicit val eqStoreStore = cats.laws.discipline.eq + .catsLawsEqForRepresentableStore[λ[P => (P, P)], Boolean, RepresentableStore[λ[P => (P, P)], Boolean, Int]] + implicit val eqStoreStoreStore = + cats.laws.discipline.eq.catsLawsEqForRepresentableStore[λ[P => (P, P)], Boolean, RepresentableStore[λ[ + P => (P, P) + ], Boolean, RepresentableStore[λ[P => (P, P)], Boolean, Int]]] + checkAll("Comonad[RepresentableStore[λ[P => (P, P)], Boolean, ?]]", + ComonadTests[RepresentableStore[λ[P => (P, P)], Boolean, ?]].comonad[Int, Int, Int]) + + checkAll("Comonad[RepresentableStore[λ[P => (P, P)], Boolean, ?]]", + SerializableTests.serializable(Comonad[RepresentableStore[λ[P => (P, P)], Boolean, ?]])) } - test("extract and peek are consistent") { forAll { (store: Store[String, String]) => - store.extract should === (store.peek(store.index)) + store.extract should ===(store.peek(store.index)) } } test("use store alias constructor") { forAll { (f: String => Int, s: String) => val store = Store(f, s) - store.extract should === (f(s)) + store.extract should ===(f(s)) } } -} \ No newline at end of file +} diff --git a/tests/src/test/scala/cats/tests/RepresentableSuite.scala b/tests/src/test/scala/cats/tests/RepresentableSuite.scala index 2455d5fd4ed..77ff37eea52 100644 --- a/tests/src/test/scala/cats/tests/RepresentableSuite.scala +++ b/tests/src/test/scala/cats/tests/RepresentableSuite.scala @@ -30,8 +30,8 @@ class RepresentableSuite 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) - checkAll("Kleisli[Pair, String, Int] <-> (String, Boolean) => Int", - + checkAll( + "Kleisli[Pair, String, Int] <-> (String, Boolean) => Int", // Have to summon all implicits using 'implicitly' otherwise we get a diverging implicits error RepresentableTests[Kleisli[Pair, String, ?], (String, Boolean)].representable[Int]( implicitly[Arbitrary[Int]], @@ -43,7 +43,8 @@ class RepresentableSuite extends CatsSuite { ) ) - checkAll("Representable[Kleisli[Pair, String, ?]]", SerializableTests.serializable(Representable[Kleisli[Pair, String, ?]])) + checkAll("Representable[Kleisli[Pair, String, ?]]", + SerializableTests.serializable(Representable[Kleisli[Pair, String, ?]])) } { @@ -76,7 +77,3 @@ class RepresentableSuite extends CatsSuite { val tabulatedFunction = indexedFunction.tabulate } } - - - - diff --git a/tests/src/test/scala/cats/tests/SemigroupSuite.scala b/tests/src/test/scala/cats/tests/SemigroupSuite.scala index c29a081b2a8..f8efb2f3c34 100644 --- a/tests/src/test/scala/cats/tests/SemigroupSuite.scala +++ b/tests/src/test/scala/cats/tests/SemigroupSuite.scala @@ -4,7 +4,6 @@ package tests import org.scalatest._ import org.scalatest.prop.GeneratorDrivenPropertyChecks - class SemigroupSuite extends FunSuite with Matchers with GeneratorDrivenPropertyChecks { { import cats.implicits._ @@ -25,8 +24,8 @@ class SemigroupSuite extends FunSuite with Matchers with GeneratorDrivenProperty val add: (Int, Int) => Int = (a, b) => a + b forAll { (a: Int, b: Int) => - Semigroup.instance(mult).combine(a, b) should === (a * b) - Semigroup.instance(add).combine(a, b) should === (a + b) + Semigroup.instance(mult).combine(a, b) should ===(a * b) + Semigroup.instance(add).combine(a, b) should ===(a + b) } } } diff --git a/tests/src/test/scala/cats/tests/SetSuite.scala b/tests/src/test/scala/cats/tests/SetSuite.scala index c8724cb1248..a55853c2515 100644 --- a/tests/src/test/scala/cats/tests/SetSuite.scala +++ b/tests/src/test/scala/cats/tests/SetSuite.scala @@ -15,17 +15,17 @@ class SetSuite extends CatsSuite { checkAll("Set[Int]", UnorderedTraverseTests[Set].unorderedTraverse[Int, Int, Int, Validated[Int, ?], Option]) checkAll("UnorderedTraverse[Set]", SerializableTests.serializable(UnorderedTraverse[Set])) - test("show"){ - Set(1, 1, 2, 3).show should === ("Set(1, 2, 3)") - Set.empty[String].show should === ("Set()") + test("show") { + Set(1, 1, 2, 3).show should ===("Set(1, 2, 3)") + Set.empty[String].show should ===("Set()") } - test("show keeps separate entries for items that map to identical strings"){ + test("show keeps separate entries for items that map to identical strings") { //note: this val name has to be the same to shadow the cats.instances 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. - Set(1, 2, 3).show should === ("Set(1, 1, 1)") + Set(1, 2, 3).show should ===("Set(1, 1, 1)") } } diff --git a/tests/src/test/scala/cats/tests/SortedMapSuite.scala b/tests/src/test/scala/cats/tests/SortedMapSuite.scala index 5c4af5c6fd1..d20adcb8ca4 100644 --- a/tests/src/test/scala/cats/tests/SortedMapSuite.scala +++ b/tests/src/test/scala/cats/tests/SortedMapSuite.scala @@ -17,7 +17,8 @@ class SortedMapSuite extends CatsSuite { checkAll("SortedMap[Int, Int]", FlatMapTests[SortedMap[Int, ?]].flatMap[Int, Int, Int]) checkAll("FlatMap[SortedMap[Int, ?]]", SerializableTests.serializable(FlatMap[SortedMap[Int, ?]])) - checkAll("SortedMap[Int, Int] with Option", TraverseTests[SortedMap[Int, ?]].traverse[Int, Int, Int, Int, Option, Option]) + checkAll("SortedMap[Int, Int] with Option", + TraverseTests[SortedMap[Int, ?]].traverse[Int, Int, Int, Int, Option, Option]) checkAll("Traverse[SortedMap[Int, ?]]", SerializableTests.serializable(Traverse[SortedMap[Int, ?]])) checkAll("SortedMap[Int, Int]", TraverseFilterTests[SortedMap[Int, ?]].traverseFilter[Int, Int, Int]) @@ -25,15 +26,17 @@ class SortedMapSuite extends CatsSuite { test("show isn't empty and is formatted as expected") { forAll { (map: SortedMap[Int, String]) => - map.show.nonEmpty should === (true) - map.show.startsWith("SortedMap(") should === (true) - map.show should === (implicitly[Show[SortedMap[Int, String]]].show(map)) + map.show.nonEmpty should ===(true) + map.show.startsWith("SortedMap(") should ===(true) + map.show should ===(implicitly[Show[SortedMap[Int, String]]].show(map)) } } - checkAll("Hash[SortedMap[Int, String]]" , HashTests[SortedMap[Int, String]].hash) - checkAll("CommutativeMonoid[SortedMap[String, Int]]", CommutativeMonoidTests[SortedMap[String, Int]].commutativeMonoid) - checkAll("CommutativeMonoid[SortedMap[String, Int]]", SerializableTests.serializable(CommutativeMonoid[SortedMap[String, Int]])) + checkAll("Hash[SortedMap[Int, String]]", HashTests[SortedMap[Int, String]].hash) + checkAll("CommutativeMonoid[SortedMap[String, Int]]", + CommutativeMonoidTests[SortedMap[String, Int]].commutativeMonoid) + checkAll("CommutativeMonoid[SortedMap[String, Int]]", + SerializableTests.serializable(CommutativeMonoid[SortedMap[String, Int]])) checkAll("Monoid[SortedMap[String, String]]", MonoidTests[SortedMap[String, String]].monoid) checkAll("Monoid[SortedMap[String, String]]", SerializableTests.serializable(Monoid[SortedMap[String, String]])) } diff --git a/tests/src/test/scala/cats/tests/SortedSetSuite.scala b/tests/src/test/scala/cats/tests/SortedSetSuite.scala index 0c5ca70f263..9aa058dea63 100644 --- a/tests/src/test/scala/cats/tests/SortedSetSuite.scala +++ b/tests/src/test/scala/cats/tests/SortedSetSuite.scala @@ -14,23 +14,29 @@ class SortedSetSuite extends CatsSuite { checkAll("SortedSet[Int]", FoldableTests[SortedSet].foldable[Int, Int]) checkAll("PartialOrder[SortedSet[Int]]", PartialOrderTests[SortedSet[Int]].partialOrder) - checkAll("PartialOrder.reverse(PartialOrder[SortedSet[Int]])", PartialOrderTests(PartialOrder.reverse(PartialOrder[SortedSet[Int]])).partialOrder) - checkAll("PartialOrder.reverse(PartialOrder.reverse(PartialOrder[SortedSet[Int]]))", PartialOrderTests(PartialOrder.reverse(PartialOrder.reverse(PartialOrder[SortedSet[Int]]))).partialOrder) + checkAll("PartialOrder.reverse(PartialOrder[SortedSet[Int]])", + PartialOrderTests(PartialOrder.reverse(PartialOrder[SortedSet[Int]])).partialOrder) + checkAll( + "PartialOrder.reverse(PartialOrder.reverse(PartialOrder[SortedSet[Int]]))", + PartialOrderTests(PartialOrder.reverse(PartialOrder.reverse(PartialOrder[SortedSet[Int]]))).partialOrder + ) checkAll("BoundedSemilattice[SortedSet[String]]", BoundedSemilatticeTests[SortedSet[String]].boundedSemilattice) - checkAll("BoundedSemilattice[SortedSet[String]]", SerializableTests.serializable(BoundedSemilattice[SortedSet[String]])) + checkAll("BoundedSemilattice[SortedSet[String]]", + SerializableTests.serializable(BoundedSemilattice[SortedSet[String]])) - checkAll("Semilattice.asMeetPartialOrder[SortedSet[Int]]", PartialOrderTests(Semilattice.asMeetPartialOrder[SortedSet[Int]]).partialOrder) - checkAll("Semilattice.asJoinPartialOrder[SortedSet[Int]]", PartialOrderTests(Semilattice.asJoinPartialOrder[SortedSet[Int]]).partialOrder) - checkAll("Hash[SortedSet[Int]]" , HashTests[SortedSet[Int]].hash) + checkAll("Semilattice.asMeetPartialOrder[SortedSet[Int]]", + PartialOrderTests(Semilattice.asMeetPartialOrder[SortedSet[Int]]).partialOrder) + checkAll("Semilattice.asJoinPartialOrder[SortedSet[Int]]", + PartialOrderTests(Semilattice.asJoinPartialOrder[SortedSet[Int]]).partialOrder) + checkAll("Hash[SortedSet[Int]]", HashTests[SortedSet[Int]].hash) - - test("show keeps separate entries for items that map to identical strings"){ + test("show keeps separate entries for items that map to identical strings") { //note: this val name has to be the same to shadow the cats.instances 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 SortedSet.map combines // duplicate items in the codomain. - SortedSet(1, 2, 3).show should === ("SortedSet(1, 1, 1)") + SortedSet(1, 2, 3).show should ===("SortedSet(1, 1, 1)") } } diff --git a/tests/src/test/scala/cats/tests/SplitSuite.scala b/tests/src/test/scala/cats/tests/SplitSuite.scala index f68bfe723d9..4aafcf5df30 100644 --- a/tests/src/test/scala/cats/tests/SplitSuite.scala +++ b/tests/src/test/scala/cats/tests/SplitSuite.scala @@ -3,7 +3,7 @@ package tests class SplitSuite extends CatsSuite { test("syntax") { - val f = (((_: Int) + 1) split ((_: Int) / 2)) + val f = ((_: Int) + 1).split((_: Int) / 2) f((1, 2)) should be((2, 1)) } } diff --git a/tests/src/test/scala/cats/tests/Spooky.scala b/tests/src/test/scala/cats/tests/Spooky.scala index 467d55cd20e..17be651f8e2 100644 --- a/tests/src/test/scala/cats/tests/Spooky.scala +++ b/tests/src/test/scala/cats/tests/Spooky.scala @@ -10,4 +10,3 @@ package tests class Spooky(var counter: Int = 0) { def increment(): Unit = counter += 1 } - diff --git a/tests/src/test/scala/cats/tests/StreamSuite.scala b/tests/src/test/scala/cats/tests/StreamSuite.scala index 25f7c1bb4df..b26c744464c 100644 --- a/tests/src/test/scala/cats/tests/StreamSuite.scala +++ b/tests/src/test/scala/cats/tests/StreamSuite.scala @@ -1,7 +1,16 @@ package cats package tests -import cats.laws.discipline.{AlternativeTests, CoflatMapTests, CommutativeApplyTests, MonadTests, SemigroupalTests, SerializableTests, TraverseFilterTests, TraverseTests} +import cats.laws.discipline.{ + AlternativeTests, + CoflatMapTests, + CommutativeApplyTests, + MonadTests, + SemigroupalTests, + SerializableTests, + TraverseFilterTests, + TraverseTests +} import cats.data.ZipStream import cats.laws.discipline.arbitrary._ @@ -28,23 +37,23 @@ class StreamSuite extends CatsSuite { checkAll("ZipStream[Int]", CommutativeApplyTests[ZipStream].apply[Int, Int, Int]) test("show") { - Stream(1, 2, 3).show should === ("Stream(1, ?)") - Stream.empty[Int].show should === ("Stream()") + Stream(1, 2, 3).show should ===("Stream(1, ?)") + Stream.empty[Int].show should ===("Stream()") } test("Show[Stream] is referentially transparent, unlike Stream.toString") { forAll { stream: Stream[Int] => if (!stream.isEmpty) { - val unevaluatedStream = stream map identity + val unevaluatedStream = stream.map(identity) val initialShow = unevaluatedStream.show // Evaluating the tail can cause Stream.toString to return different values, // depending on the internal state of the Stream. Show[Stream] should return // consistent values independent of internal state. unevaluatedStream.tail - initialShow should === (unevaluatedStream.show) + initialShow should ===(unevaluatedStream.show) } else { - stream.show should === (stream.toString) + stream.show should ===(stream.toString) } } } diff --git a/tests/src/test/scala/cats/tests/SyntaxSuite.scala b/tests/src/test/scala/cats/tests/SyntaxSuite.scala index 01ead70966e..00806a0d6a4 100644 --- a/tests/src/test/scala/cats/tests/SyntaxSuite.scala +++ b/tests/src/test/scala/cats/tests/SyntaxSuite.scala @@ -9,23 +9,23 @@ import cats.instances.AllInstances import cats.syntax.{AllSyntax, AllSyntaxBinCompat} /** - * Test that our syntax implicits are working. - * - * Each method should correspond to one type class worth of syntax. - * Ideally, we should be testing every operator or method that we - * expect to add to generic parameters. This file is a safeguard - * against accidentally breaking (or removing) syntax which was - * otherwise untested. - * - * The strategy here is to create "mock" values of particular types, - * and then ensure that the syntax we want is available. We never plan - * to run any of these methods, so we don't need real values. All - * values in the methods should be generic -- we rely on parametricity - * to guarantee that the syntax will be available for any type with - * the proper type class instance(s). - * - * None of these tests should ever run, or do any runtime checks. - */ + * Test that our syntax implicits are working. + * + * Each method should correspond to one type class worth of syntax. + * Ideally, we should be testing every operator or method that we + * expect to add to generic parameters. This file is a safeguard + * against accidentally breaking (or removing) syntax which was + * otherwise untested. + * + * The strategy here is to create "mock" values of particular types, + * and then ensure that the syntax we want is available. We never plan + * to run any of these methods, so we don't need real values. All + * values in the methods should be generic -- we rely on parametricity + * to guarantee that the syntax will be available for any type with + * the proper type class instance(s). + * + * None of these tests should ever run, or do any runtime checks. + */ object SyntaxSuite extends AllSyntaxBinCompat with AllInstances with AllSyntax { // pretend we have a value of type A @@ -49,7 +49,7 @@ object SyntaxSuite extends AllSyntaxBinCompat with AllInstances with AllSyntax { val z: Boolean = x.isEmpty } - def testCompose[F[_,_] : Compose, A, B, C, D]: Unit = { + def testCompose[F[_, _]: Compose, A, B, C, D]: Unit = { val x = mock[F[A, B]] val y = mock[F[B, C]] val z = mock[F[C, D]] @@ -64,8 +64,8 @@ object SyntaxSuite extends AllSyntaxBinCompat with AllInstances with AllSyntax { val y = mock[A] val b0: Boolean = x === y val b1: Boolean = x =!= y - val b2: Boolean = x eqv y - val b3: Boolean = x neqv y + val b2: Boolean = x.eqv(y) + val b3: Boolean = x.neqv(y) } def testPartialOrder[A: PartialOrder]: Unit = { @@ -75,18 +75,18 @@ object SyntaxSuite extends AllSyntaxBinCompat with AllInstances with AllSyntax { val b1: Boolean = x <= y val b2: Boolean = x > y val b3: Boolean = x >= y - val f: Double = x partialCompare y - val oi: Option[Int] = x tryCompare y - val oz0: Option[A] = x pmin y - val oz1: Option[A] = x pmax y + val f: Double = x.partialCompare(y) + val oi: Option[Int] = x.tryCompare(y) + val oz0: Option[A] = x.pmin(y) + val oz1: Option[A] = x.pmax(y) } def testOrder[A: Order]: Unit = { val x = mock[A] val y = mock[A] - val i: Int = x compare y - val z0: A = x min y - val z1: A = x max y + val i: Int = x.compare(y) + val z0: A = x.min(y) + val z1: A = x.max(y) } def testInvariantFunctor[F[_]: Invariant, A, B]: Unit = { @@ -149,11 +149,10 @@ object SyntaxSuite extends AllSyntaxBinCompat with AllInstances with AllSyntax { val ft = mock[(A, B, C) => G[Z]] - val gfabc = tfabc traverseN ft - val gfabc2 = (fa, fb, fc) traverseN ft + val gfabc = tfabc.traverseN(ft) + val gfabc2 = (fa, fb, fc).traverseN(ft) } - def testNonEmptyTraverse[F[_]: NonEmptyTraverse: FlatMap, G[_]: Apply: SemigroupK, A: Semigroup, B, Z]: Unit = { val fa = mock[F[A]] val f1 = mock[A => G[B]] @@ -166,8 +165,6 @@ object SyntaxSuite extends AllSyntaxBinCompat with AllInstances with AllSyntax { val gunit: G[F[A]] = fga.nonEmptySequence } - - def testParallel[M[_]: Monad, F[_], T[_]: Traverse, A, B](implicit P: Parallel[M, F]): Unit = { val ta = mock[T[A]] val f = mock[A => M[B]] @@ -199,8 +196,8 @@ object SyntaxSuite extends AllSyntaxBinCompat with AllInstances with AllSyntax { val fc = mock[M[C]] val f = mock[(A, B, C) => Z] - tfabc parMapN f - (fa, fb, fc) parMapN f + tfabc.parMapN(f) + (fa, fb, fc).parMapN(f) } def testReducible[F[_]: Reducible, G[_]: Apply: SemigroupK, A: Semigroup, B, Z]: Unit = { @@ -244,7 +241,7 @@ object SyntaxSuite extends AllSyntaxBinCompat with AllInstances with AllSyntax { val fb1: F[B] = fa.as(b) } - def testApply[F[_]: Apply : Semigroupal, G[_]: Contravariant : Semigroupal, H[_]: Invariant : Semigroupal, A, B, C, D, E, Z] = { + def testApply[F[_]: Apply: Semigroupal, G[_]: Contravariant: Semigroupal, H[_]: Invariant: Semigroupal, A, B, C, D, E, Z] = { val tfabc = mock[(F[A], F[B], F[C])] val fa = mock[F[A]] val fb = mock[F[B]] @@ -255,17 +252,17 @@ object SyntaxSuite extends AllSyntaxBinCompat with AllInstances with AllSyntax { fa *> fb fb <* fc - tfabc mapN f - (fa, fb, fc) mapN f - (fa, fb, fc) apWith ff + tfabc.mapN(f) + (fa, fb, fc).mapN(f) + (fa, fb, fc).apWith(ff) val tgabc = mock[(G[A], G[B])] val ga = mock[G[A]] val gb = mock[G[B]] val g = mock[Z => (A, B)] - tgabc contramapN g - (ga, gb) contramapN g + tgabc.contramapN(g) + (ga, gb).contramapN(g) val thabcde = mock[(H[A], H[B], H[C], H[D], H[E])] val ha = mock[H[A]] @@ -320,7 +317,7 @@ object SyntaxSuite extends AllSyntaxBinCompat with AllInstances with AllSyntax { val fa = a.pure[F] } - def testFlatMap[F[_] : FlatMap, A, B]: Unit = { + def testFlatMap[F[_]: FlatMap, A, B]: Unit = { val a = mock[A] val returnValue = mock[F[Either[A, B]]] val done = a.tailRecM[F, B](a => returnValue) @@ -367,7 +364,7 @@ object SyntaxSuite extends AllSyntaxBinCompat with AllInstances with AllSyntax { val binested: Binested[F, G, H, A, B] = fgahb.binested } - def testNonEmptySet[A, B: Order] : Unit = { + def testNonEmptySet[A, B: Order]: Unit = { val f = mock[A => B] val set = mock[SortedSet[A]] @@ -375,7 +372,7 @@ object SyntaxSuite extends AllSyntaxBinCompat with AllInstances with AllSyntax { val grouped: SortedMap[B, NonEmptySet[A]] = set.groupByNes(f) } - def testNonEmptyList[A, B: Order] : Unit = { + def testNonEmptyList[A, B: Order]: Unit = { val f = mock[A => B] val list = mock[List[A]] @@ -383,7 +380,7 @@ object SyntaxSuite extends AllSyntaxBinCompat with AllInstances with AllSyntax { val grouped: SortedMap[B, NonEmptyList[A]] = list.groupByNel(f) } - def testNonEmptyChain[A, B: Order] : Unit = { + def testNonEmptyChain[A, B: Order]: Unit = { val f = mock[A => B] val list = mock[List[A]] @@ -391,4 +388,3 @@ object SyntaxSuite extends AllSyntaxBinCompat with AllInstances with AllSyntax { } } - diff --git a/tests/src/test/scala/cats/tests/TraverseSuite.scala b/tests/src/test/scala/cats/tests/TraverseSuite.scala index b912201a9bc..e99b17f4237 100644 --- a/tests/src/test/scala/cats/tests/TraverseSuite.scala +++ b/tests/src/test/scala/cats/tests/TraverseSuite.scala @@ -6,17 +6,19 @@ import org.scalacheck.Arbitrary import cats.instances.all._ -abstract class TraverseSuite[F[_]: Traverse](name: String)(implicit ArbFInt: Arbitrary[F[Int]]) extends CatsSuite with PropertyChecks { +abstract class TraverseSuite[F[_]: Traverse](name: String)(implicit ArbFInt: Arbitrary[F[Int]]) + extends CatsSuite + with PropertyChecks { test(s"Traverse[$name].zipWithIndex") { forAll { (fa: F[Int]) => - fa.zipWithIndex.toList should === (fa.toList.zipWithIndex) + fa.zipWithIndex.toList should ===(fa.toList.zipWithIndex) } } test(s"Traverse[$name].mapWithIndex") { forAll { (fa: F[Int], fn: ((Int, Int)) => Int) => - fa.mapWithIndex((a, i) => fn((a, i))).toList should === (fa.toList.zipWithIndex.map(fn)) + fa.mapWithIndex((a, i) => fn((a, i))).toList should ===(fa.toList.zipWithIndex.map(fn)) } } @@ -24,7 +26,7 @@ abstract class TraverseSuite[F[_]: Traverse](name: String)(implicit ArbFInt: Arb forAll { (fa: F[Int], fn: ((Int, Int)) => (Int, Int)) => val left = fa.traverseWithIndexM((a, i) => fn((a, i))).map(_.toList) val (xs, values) = fa.toList.zipWithIndex.map(fn).unzip - left should === ((xs.combineAll, values)) + left should ===((xs.combineAll, values)) } } @@ -47,11 +49,11 @@ object TraverseSuite { } } -class TraverseListSuite extends TraverseSuite[List]("List") +class TraverseListSuite extends TraverseSuite[List]("List") class TraverseStreamSuite extends TraverseSuite[Stream]("Stream") class TraverseVectorSuite extends TraverseSuite[Vector]("Vector") -class TraverseListSuiteUnderlying extends TraverseSuite.Underlying[List]("List") +class TraverseListSuiteUnderlying extends TraverseSuite.Underlying[List]("List") class TraverseStreamSuiteUnderlying extends TraverseSuite.Underlying[Stream]("Stream") class TraverseVectorSuiteUnderlying extends TraverseSuite.Underlying[Vector]("Vector") diff --git a/tests/src/test/scala/cats/tests/TrySuite.scala b/tests/src/test/scala/cats/tests/TrySuite.scala index e07ae3eddfc..f59ad050a70 100644 --- a/tests/src/test/scala/cats/tests/TrySuite.scala +++ b/tests/src/test/scala/cats/tests/TrySuite.scala @@ -1,7 +1,7 @@ package cats package tests -import cats.kernel.laws.discipline.{SemigroupTests, MonoidTests} +import cats.kernel.laws.discipline.{MonoidTests, SemigroupTests} import cats.laws.{ApplicativeLaws, CoflatMapLaws, FlatMapLaws, MonadLaws} import cats.laws.discipline._ import cats.laws.discipline.arbitrary._ @@ -38,7 +38,7 @@ class TrySuite extends CatsSuite { test("show") { forAll { fs: Try[String] => - fs.show should === (fs.toString) + fs.show should ===(fs.toString) } } @@ -63,7 +63,7 @@ class TrySuite extends CatsSuite { } test("fromTry works") { forAll { t: Try[Int] => - (MonadError[Try, Throwable].fromTry(t)) should === (t) + (MonadError[Try, Throwable].fromTry(t)) should ===(t) } } @@ -73,31 +73,23 @@ class TrySuite extends CatsSuite { // instances. test("Kleisli associativity") { - forAll { (l: Long, - f: Long => Try[Int], - g: Int => Try[Char], - h: Char => Try[String]) => + 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) + isEq.lhs should ===(isEq.rhs) } } test("Cokleisli associativity") { - forAll { (l: Try[Long], - f: Try[Long] => Int, - g: Try[Int] => Char, - h: Try[Char] => String) => + 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) + isEq.lhs should ===(isEq.rhs) } } test("applicative composition") { - forAll { (fa: Try[Int], - fab: Try[Int => Long], - fbc: Try[Long => Char]) => + 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) + isEq.lhs should ===(isEq.rhs) } } @@ -106,14 +98,14 @@ class TrySuite extends CatsSuite { test("Kleisli left identity") { forAll { (a: Int, f: Int => Try[Long]) => val isEq = monadLaws.kleisliLeftIdentity(a, f) - isEq.lhs should === (isEq.rhs) + 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) + isEq.lhs should ===(isEq.rhs) } } @@ -121,6 +113,6 @@ class TrySuite extends CatsSuite { var evals = 0 val bomb: Eval[Try[Int]] = Later { evals += 1; Success(1) } Try[Int](sys.error("boom0")).map2Eval(bomb)(_ + _).value - evals should === (0) + evals should ===(0) } } diff --git a/tests/src/test/scala/cats/tests/Tuple2KSuite.scala b/tests/src/test/scala/cats/tests/Tuple2KSuite.scala index 8c65f52661e..bf9e7be5064 100644 --- a/tests/src/test/scala/cats/tests/Tuple2KSuite.scala +++ b/tests/src/test/scala/cats/tests/Tuple2KSuite.scala @@ -1,94 +1,120 @@ package cats package tests - import cats.data.{Const, Tuple2K, Validated} import cats.Contravariant import cats.laws.discipline._ import cats.laws.discipline.arbitrary._ import cats.laws.discipline.eq._ -import cats.kernel.laws.discipline.{OrderTests, PartialOrderTests, EqTests} +import cats.kernel.laws.discipline.{EqTests, OrderTests, PartialOrderTests} class Tuple2KSuite extends CatsSuite { implicit val iso = SemigroupalTests.Isomorphisms.invariant[Tuple2K[Option, List, ?]] checkAll("Tuple2K[Eval, Eval, ?]", DeferTests[Tuple2K[Eval, Eval, ?]].defer[Int]) checkAll("Tuple2K[Option, List, Int]", SemigroupalTests[λ[α => Tuple2K[Option, List, α]]].semigroupal[Int, Int, Int]) - checkAll("Semigroupal[Tuple2K[Option, List, Int]]", SerializableTests.serializable(Semigroupal[λ[α => Tuple2K[Option, List, α]]])) + checkAll("Semigroupal[Tuple2K[Option, List, Int]]", + SerializableTests.serializable(Semigroupal[λ[α => Tuple2K[Option, List, α]]])) checkAll("Tuple2K[Option, List, Int]", AlternativeTests[λ[α => Tuple2K[Option, List, α]]].alternative[Int, Int, Int]) - checkAll("Alternative[Tuple2K[Option, List, Int]]", SerializableTests.serializable(Alternative[λ[α => Tuple2K[Option, List, α]]])) - - checkAll("Tuple2K[Show, Order, Int]", ContravariantTests[λ[α => Tuple2K[Show, Order, α]]].contravariant[Int, Int, Int]) - checkAll("Contravariant[Tuple2K[Show, Order, Int]]", SerializableTests.serializable(Contravariant[λ[α => Tuple2K[Show, Order, α]]])) - - checkAll("Tuple2K[Const[String, ?], Const[Int, ?], Int]", - ContravariantMonoidalTests[λ[α => Tuple2K[Const[String, ?], Const[Int, ?], α]]].contravariantMonoidal[Int, Int, Int]) - checkAll("ContravariantMonoidal[Tuple2K[Const[String, ?], Const[Int, ?], Int]]", - SerializableTests.serializable(ContravariantMonoidal[λ[α => Tuple2K[Const[String, ?], Const[Int, ?], α]]])) + checkAll("Alternative[Tuple2K[Option, List, Int]]", + SerializableTests.serializable(Alternative[λ[α => Tuple2K[Option, List, α]]])) + + checkAll("Tuple2K[Show, Order, Int]", + ContravariantTests[λ[α => Tuple2K[Show, Order, α]]].contravariant[Int, Int, Int]) + checkAll("Contravariant[Tuple2K[Show, Order, Int]]", + SerializableTests.serializable(Contravariant[λ[α => Tuple2K[Show, Order, α]]])) + + checkAll( + "Tuple2K[Const[String, ?], Const[Int, ?], Int]", + ContravariantMonoidalTests[λ[α => Tuple2K[Const[String, ?], Const[Int, ?], α]]].contravariantMonoidal[Int, Int, Int] + ) + checkAll( + "ContravariantMonoidal[Tuple2K[Const[String, ?], Const[Int, ?], Int]]", + SerializableTests.serializable(ContravariantMonoidal[λ[α => Tuple2K[Const[String, ?], Const[Int, ?], α]]]) + ) checkAll("Show[Tuple2K[Option, Option, Int]]", SerializableTests.serializable(Show[Tuple2K[Option, Option, Int]])) { implicit val monoidK = ListWrapper.monoidK checkAll("Tuple2K[ListWrapper, ListWrapper, ?]", MonoidKTests[Tuple2K[ListWrapper, ListWrapper, ?]].monoidK[Int]) - checkAll("MonoidK[Tuple2K[ListWrapper, ListWrapper, ?]]", SerializableTests.serializable(MonoidK[Tuple2K[ListWrapper, ListWrapper, ?]])) + checkAll("MonoidK[Tuple2K[ListWrapper, ListWrapper, ?]]", + SerializableTests.serializable(MonoidK[Tuple2K[ListWrapper, ListWrapper, ?]])) } { implicit val semigroupK = ListWrapper.semigroupK - checkAll("Tuple2K[ListWrapper, ListWrapper, ?]", SemigroupKTests[Tuple2K[ListWrapper, ListWrapper, ?]].semigroupK[Int]) - checkAll("SemigroupK[Tuple2K[ListWrapper, ListWrapper, ?]]", SerializableTests.serializable(SemigroupK[Tuple2K[ListWrapper, ListWrapper, ?]])) + checkAll("Tuple2K[ListWrapper, ListWrapper, ?]", + SemigroupKTests[Tuple2K[ListWrapper, ListWrapper, ?]].semigroupK[Int]) + checkAll("SemigroupK[Tuple2K[ListWrapper, ListWrapper, ?]]", + SerializableTests.serializable(SemigroupK[Tuple2K[ListWrapper, ListWrapper, ?]])) } { implicit val apply = ListWrapper.applyInstance implicit val iso = SemigroupalTests.Isomorphisms.invariant[Tuple2K[ListWrapper, ListWrapper, ?]] - checkAll("Tuple2K[ListWrapper, ListWrapper, ?]", ApplyTests[Tuple2K[ListWrapper, ListWrapper, ?]].apply[Int, Int, Int]) - checkAll("Apply[Tuple2K[ListWrapper, ListWrapper, ?]]", SerializableTests.serializable(Apply[Tuple2K[ListWrapper, ListWrapper, ?]])) + checkAll("Tuple2K[ListWrapper, ListWrapper, ?]", + ApplyTests[Tuple2K[ListWrapper, ListWrapper, ?]].apply[Int, Int, Int]) + checkAll("Apply[Tuple2K[ListWrapper, ListWrapper, ?]]", + SerializableTests.serializable(Apply[Tuple2K[ListWrapper, ListWrapper, ?]])) } { implicit val optionApply = Apply[Option] implicit val validatedApply = Apply[Validated[Int, ?]] - checkAll("Tuple2K[Option, Validated[Int, ?], ?]", CommutativeApplyTests[Tuple2K[Option, Validated[Int, ?], ?]].commutativeApply[Int, Int, Int]) - checkAll("Apply[Tuple2K[Option, Validated[Int, ?], ?]]", SerializableTests.serializable(CommutativeApply[Tuple2K[Option, Validated[Int, ?], ?]])) + checkAll("Tuple2K[Option, Validated[Int, ?], ?]", + CommutativeApplyTests[Tuple2K[Option, Validated[Int, ?], ?]].commutativeApply[Int, Int, Int]) + checkAll("Apply[Tuple2K[Option, Validated[Int, ?], ?]]", + SerializableTests.serializable(CommutativeApply[Tuple2K[Option, Validated[Int, ?], ?]])) } { - checkAll("Tuple2K[Option, Validated[Int, ?], ?]", CommutativeApplicativeTests[Tuple2K[Option, Validated[Int, ?], ?]].commutativeApplicative[Int, Int, Int]) - checkAll("Applicative[Tuple2K[Option, Validated[Int, ?], ?]]", SerializableTests.serializable(CommutativeApplicative[Tuple2K[Option, Validated[Int, ?], ?]])) + checkAll("Tuple2K[Option, Validated[Int, ?], ?]", + CommutativeApplicativeTests[Tuple2K[Option, Validated[Int, ?], ?]].commutativeApplicative[Int, Int, Int]) + checkAll("Applicative[Tuple2K[Option, Validated[Int, ?], ?]]", + SerializableTests.serializable(CommutativeApplicative[Tuple2K[Option, Validated[Int, ?], ?]])) } { implicit val functor = ListWrapper.functor - checkAll("Tuple2K[ListWrapper, ListWrapper, ?]", FunctorTests[Tuple2K[ListWrapper, ListWrapper, ?]].functor[Int, Int, Int]) - checkAll("Functor[Tuple2K[ListWrapper, ListWrapper, ?]]", SerializableTests.serializable(Functor[Tuple2K[ListWrapper, ListWrapper, ?]])) + checkAll("Tuple2K[ListWrapper, ListWrapper, ?]", + FunctorTests[Tuple2K[ListWrapper, ListWrapper, ?]].functor[Int, Int, Int]) + checkAll("Functor[Tuple2K[ListWrapper, ListWrapper, ?]]", + SerializableTests.serializable(Functor[Tuple2K[ListWrapper, ListWrapper, ?]])) } { implicit val monad = ListWrapper.monad implicit val iso = SemigroupalTests.Isomorphisms.invariant[Tuple2K[ListWrapper, ListWrapper, ?]] - checkAll("Tuple2K[ListWrapper, ListWrapper, ?]", MonadTests[Tuple2K[ListWrapper, ListWrapper, ?]].monad[Int, Int, Int]) - checkAll("Monad[Tuple2K[ListWrapper, ListWrapper, ?]]", SerializableTests.serializable(Monad[Tuple2K[ListWrapper, ListWrapper, ?]])) + checkAll("Tuple2K[ListWrapper, ListWrapper, ?]", + MonadTests[Tuple2K[ListWrapper, ListWrapper, ?]].monad[Int, Int, Int]) + checkAll("Monad[Tuple2K[ListWrapper, ListWrapper, ?]]", + SerializableTests.serializable(Monad[Tuple2K[ListWrapper, ListWrapper, ?]])) } { implicit val foldable = ListWrapper.foldable - checkAll("Tuple2K[ListWrapper, ListWrapper, ?]", FoldableTests[Tuple2K[ListWrapper, ListWrapper, ?]].foldable[Int, Int]) - checkAll("Foldable[Tuple2K[ListWrapper, ListWrapper, ?]]", SerializableTests.serializable(Foldable[Tuple2K[ListWrapper, ListWrapper, ?]])) + checkAll("Tuple2K[ListWrapper, ListWrapper, ?]", + FoldableTests[Tuple2K[ListWrapper, ListWrapper, ?]].foldable[Int, Int]) + checkAll("Foldable[Tuple2K[ListWrapper, ListWrapper, ?]]", + SerializableTests.serializable(Foldable[Tuple2K[ListWrapper, ListWrapper, ?]])) } { implicit val traverse = ListWrapper.traverse - checkAll("Tuple2K[ListWrapper, ListWrapper, ?]", TraverseTests[Tuple2K[ListWrapper, ListWrapper, ?]].traverse[Int, Int, Int, Int, Option, Option]) - checkAll("Traverse[Tuple2K[ListWrapper, ListWrapper, ?]]", SerializableTests.serializable(Traverse[Tuple2K[ListWrapper, ListWrapper, ?]])) + checkAll("Tuple2K[ListWrapper, ListWrapper, ?]", + TraverseTests[Tuple2K[ListWrapper, ListWrapper, ?]].traverse[Int, Int, Int, Int, Option, Option]) + checkAll("Traverse[Tuple2K[ListWrapper, ListWrapper, ?]]", + SerializableTests.serializable(Traverse[Tuple2K[ListWrapper, ListWrapper, ?]])) } { implicit val alternative = ListWrapper.alternative implicit val iso = SemigroupalTests.Isomorphisms.invariant[Tuple2K[ListWrapper, ListWrapper, ?]] - checkAll("Tuple2K[ListWrapper, ListWrapper, ?]", AlternativeTests[Tuple2K[ListWrapper, ListWrapper, ?]].alternative[Int, Int, Int]) - checkAll("Alternative[Tuple2K[ListWrapper, ListWrapper, ?]]", SerializableTests.serializable(Alternative[Tuple2K[ListWrapper, ListWrapper, ?]])) + checkAll("Tuple2K[ListWrapper, ListWrapper, ?]", + AlternativeTests[Tuple2K[ListWrapper, ListWrapper, ?]].alternative[Int, Int, Int]) + checkAll("Alternative[Tuple2K[ListWrapper, ListWrapper, ?]]", + SerializableTests.serializable(Alternative[Tuple2K[ListWrapper, ListWrapper, ?]])) } { @@ -98,19 +124,24 @@ class Tuple2KSuite extends CatsSuite { checkAll("Tuple2K[ListWrapper, ListWrapper, Int]", EqTests[Tuple2K[ListWrapper, ListWrapper, Int]].eqv) checkAll("Tuple2K[ListWrapper, ListWrapper, Int]", OrderTests[Tuple2K[ListWrapper, ListWrapper, Int]].order) - checkAll("Tuple2K[ListWrapper, ListWrapper, Int]", PartialOrderTests[Tuple2K[ListWrapper, ListWrapper, Int]].partialOrder) + checkAll("Tuple2K[ListWrapper, ListWrapper, Int]", + PartialOrderTests[Tuple2K[ListWrapper, ListWrapper, Int]].partialOrder) } { - checkAll("Tuple2K[Function0, Function0, ?]", DistributiveTests[Tuple2K[Function0, Function0, ?]].distributive[Int, Int, Int, Option, Function0]) - checkAll("Distributive[Tuple2K[Function0, Function0, ?]]", SerializableTests.serializable(Distributive[Tuple2K[Function0, Function0, ?]])) + checkAll("Tuple2K[Function0, Function0, ?]", + DistributiveTests[Tuple2K[Function0, Function0, ?]].distributive[Int, Int, Int, Option, Function0]) + checkAll("Distributive[Tuple2K[Function0, Function0, ?]]", + SerializableTests.serializable(Distributive[Tuple2K[Function0, Function0, ?]])) } test("show") { forAll { (l1: Option[Int], l2: Option[Int]) => val tuple = Tuple2K(l1, l2) - Show[Tuple2K[Option, Option, Int]].show(tuple) should === (s"Tuple2K(${Show[Option[Int]].show(l1)}, ${Show[Option[Int]].show(l2)})") + Show[Tuple2K[Option, Option, Int]].show(tuple) should ===( + s"Tuple2K(${Show[Option[Int]].show(l1)}, ${Show[Option[Int]].show(l2)})" + ) } } @@ -118,7 +149,7 @@ class Tuple2KSuite extends CatsSuite { forAll { (l1: Option[String], l2: List[String]) => val tuple = Tuple2K(l1, l2) - tuple.swap.swap should === (tuple) + tuple.swap.swap should ===(tuple) } } diff --git a/tests/src/test/scala/cats/tests/TupleSuite.scala b/tests/src/test/scala/cats/tests/TupleSuite.scala index 2a13e82cfed..7aff44b596b 100644 --- a/tests/src/test/scala/cats/tests/TupleSuite.scala +++ b/tests/src/test/scala/cats/tests/TupleSuite.scala @@ -28,8 +28,10 @@ class TupleSuite extends CatsSuite { checkAll("Monad[(String, ?)]", MonadTests[(String, ?)].monad[Int, Int, String]) checkAll("Monad[(String, ?)] serializable", SerializableTests.serializable(Monad[(String, ?)])) - checkAll("CommutativeFlatMap[(CSemi, ?)]", CommutativeFlatMapTests[(CSemi, ?)].commutativeFlatMap[CSemi, CSemi, CSemi]) - checkAll("CommutativeFlatMap[(CSemi, ?)] serializable", SerializableTests.serializable(CommutativeFlatMap[(CSemi, ?)])) + checkAll("CommutativeFlatMap[(CSemi, ?)]", + CommutativeFlatMapTests[(CSemi, ?)].commutativeFlatMap[CSemi, CSemi, CSemi]) + checkAll("CommutativeFlatMap[(CSemi, ?)] serializable", + SerializableTests.serializable(CommutativeFlatMap[(CSemi, ?)])) checkAll("CommutativeMonad[(Int, ?)]", CommutativeMonadTests[(Int, ?)].commutativeMonad[Int, Int, Int]) checkAll("CommutativeMonad[(Int, ?)] serializable", SerializableTests.serializable(CommutativeMonad[(Int, ?)])) @@ -41,28 +43,32 @@ class TupleSuite extends CatsSuite { val cart = ContravariantSemigroupal[Eq].composeFunctor[(Int, ?)] val eq = cart.product(Eq[(Int, String)], Eq[(Int, Int)]) forAll { (a: (Int, (String, Int)), b: (Int, (String, Int))) => - (a == b) should === (eq.eqv(a, b)) + (a == b) should ===(eq.eqv(a, b)) } } 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) } + 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)) + Order[(Int, Int)].compare(t, u) should ===(scala.math.Ordering[(Int, Int)].compare(t, u)) } } test("show") { - (1, 2).show should === ("(1,2)") + (1, 2).show should ===("(1,2)") forAll { fs: (String, String) => - fs.show should === (fs.toString) + fs.show should ===(fs.toString) } // Provide some "non-standard" Show instances to make sure the tuple2 is actually use the Show instances for the @@ -78,6 +84,6 @@ class TupleSuite extends CatsSuite { val foo = Foo(1) val bar = Bar(2) - (foo, bar).show should === (s"(${fooShow.show(foo)},${barShow.show(bar)})") + (foo, bar).show should ===(s"(${fooShow.show(foo)},${barShow.show(bar)})") } } diff --git a/tests/src/test/scala/cats/tests/UnorderedFoldableSuite.scala b/tests/src/test/scala/cats/tests/UnorderedFoldableSuite.scala index a0bd683c1c3..ed70ba396f3 100644 --- a/tests/src/test/scala/cats/tests/UnorderedFoldableSuite.scala +++ b/tests/src/test/scala/cats/tests/UnorderedFoldableSuite.scala @@ -5,8 +5,9 @@ import org.scalatest.prop.PropertyChecks import org.scalacheck.Arbitrary import cats.instances.all._ -abstract class UnorderedFoldableSuite[F[_]: UnorderedFoldable](name: String)( - implicit ArbFString: Arbitrary[F[String]]) extends CatsSuite with PropertyChecks { +abstract class UnorderedFoldableSuite[F[_]: UnorderedFoldable](name: String)(implicit ArbFString: Arbitrary[F[String]]) + extends CatsSuite + with PropertyChecks { def iterator[T](fa: F[T]): Iterator[T] @@ -23,4 +24,4 @@ class UnorderedFoldableSetSuite extends UnorderedFoldableSuite[Set]("set") { class UnorderedFoldableMapSuite extends UnorderedFoldableSuite[Map[String, ?]]("map") { def iterator[T](map: Map[String, T]): Iterator[T] = map.valuesIterator -} \ No newline at end of file +} diff --git a/tests/src/test/scala/cats/tests/UnorderedTraverseSuite.scala b/tests/src/test/scala/cats/tests/UnorderedTraverseSuite.scala index f4747f4a8da..eded2048585 100644 --- a/tests/src/test/scala/cats/tests/UnorderedTraverseSuite.scala +++ b/tests/src/test/scala/cats/tests/UnorderedTraverseSuite.scala @@ -4,7 +4,7 @@ package tests class UnorderedTraverseSuite extends CatsSuite { test("UnorderedTraverse[Set[Int]].unorderedTraverse via syntax") { forAll { (ins: Set[Int]) => - ins.unorderedTraverse(in => in: Id[Int]).toList.sorted should === (ins.toList.sorted) + ins.unorderedTraverse(in => in: Id[Int]).toList.sorted should ===(ins.toList.sorted) } } } diff --git a/tests/src/test/scala/cats/tests/ValidatedSuite.scala b/tests/src/test/scala/cats/tests/ValidatedSuite.scala index d5eeec71ed6..124a887a8c3 100644 --- a/tests/src/test/scala/cats/tests/ValidatedSuite.scala +++ b/tests/src/test/scala/cats/tests/ValidatedSuite.scala @@ -7,25 +7,28 @@ import cats.laws.discipline._ import org.scalacheck.Arbitrary._ import cats.laws.discipline.SemigroupKTests import cats.laws.discipline.arbitrary._ -import cats.kernel.laws.discipline.{MonoidTests, SemigroupTests, OrderTests, PartialOrderTests, EqTests} +import cats.kernel.laws.discipline.{EqTests, MonoidTests, OrderTests, PartialOrderTests, SemigroupTests} import scala.util.Try class ValidatedSuite extends CatsSuite { implicit val iso = SemigroupalTests.Isomorphisms.invariant[Validated[String, ?]] - checkAll("Validated[String, Int]", SemigroupalTests[Validated[String,?]].semigroupal[Int, Int, Int]) - checkAll("Semigroupal[Validated[String,?]]", SerializableTests.serializable(Semigroupal[Validated[String,?]])) + checkAll("Validated[String, Int]", SemigroupalTests[Validated[String, ?]].semigroupal[Int, Int, Int]) + checkAll("Semigroupal[Validated[String,?]]", SerializableTests.serializable(Semigroupal[Validated[String, ?]])) checkAll("Validated[?, ?]", BitraverseTests[Validated].bitraverse[Option, Int, Int, Int, String, String, String]) checkAll("Bitraverse[Validated]", SerializableTests.serializable(Bitraverse[Validated])) implicit val eq0 = EitherT.catsDataEqForEitherT[Validated[String, ?], String, Int] - checkAll("Validated[String, Int]", ApplicativeErrorTests[Validated[String, ?], String].applicativeError[Int, Int, Int]) - checkAll("ApplicativeError[Validated, String]", SerializableTests.serializable(ApplicativeError[Validated[String, ?], String])) + checkAll("Validated[String, Int]", + ApplicativeErrorTests[Validated[String, ?], String].applicativeError[Int, Int, Int]) + checkAll("ApplicativeError[Validated, String]", + SerializableTests.serializable(ApplicativeError[Validated[String, ?], String])) - checkAll("Validated[String, Int] with Option", TraverseTests[Validated[String,?]].traverse[Int, Int, Int, Int, Option, Option]) - checkAll("Traverse[Validated[String, ?]]", SerializableTests.serializable(Traverse[Validated[String,?]])) + checkAll("Validated[String, Int] with Option", + TraverseTests[Validated[String, ?]].traverse[Int, Int, Int, Int, Option, Option]) + checkAll("Traverse[Validated[String, ?]]", SerializableTests.serializable(Traverse[Validated[String, ?]])) checkAll("Validated[String, Int]", OrderTests[Validated[String, Int]].order) checkAll("Order[Validated[String, Int]]", SerializableTests.serializable(Order[Validated[String, Int]])) @@ -35,77 +38,85 @@ class ValidatedSuite extends CatsSuite { checkAll("Validated[String, NonEmptyList[Int]]", SemigroupTests[Validated[String, NonEmptyList[Int]]].semigroup) checkAll("Validated[Int, Int]", CommutativeApplicativeTests[Validated[Int, ?]].commutativeApplicative[Int, Int, Int]) - checkAll("CommutativeApplicative[Validated[Int, ?]]", SerializableTests.serializable(CommutativeApplicative[Validated[Int, ?]])) + checkAll("CommutativeApplicative[Validated[Int, ?]]", + SerializableTests.serializable(CommutativeApplicative[Validated[Int, ?]])) { implicit val L = ListWrapper.semigroup[String] checkAll("Validated[ListWrapper[String], ?]", SemigroupKTests[Validated[ListWrapper[String], ?]].semigroupK[Int]) - checkAll("SemigroupK[Validated[ListWrapper[String], ?]]", SerializableTests.serializable(SemigroupK[Validated[ListWrapper[String], ?]])) + checkAll("SemigroupK[Validated[ListWrapper[String], ?]]", + SerializableTests.serializable(SemigroupK[Validated[ListWrapper[String], ?]])) } { implicit val S = ListWrapper.partialOrder[String] implicit val I = ListWrapper.partialOrder[Int] - checkAll("Validated[ListWrapper[String], ListWrapper[Int]]", PartialOrderTests[Validated[ListWrapper[String], ListWrapper[Int]]].partialOrder) - checkAll("PartialOrder[Validated[ListWrapper[String], ListWrapper[Int]]]", SerializableTests.serializable(PartialOrder[Validated[ListWrapper[String], ListWrapper[Int]]])) + checkAll("Validated[ListWrapper[String], ListWrapper[Int]]", + PartialOrderTests[Validated[ListWrapper[String], ListWrapper[Int]]].partialOrder) + checkAll( + "PartialOrder[Validated[ListWrapper[String], ListWrapper[Int]]]", + SerializableTests.serializable(PartialOrder[Validated[ListWrapper[String], ListWrapper[Int]]]) + ) } { implicit val S = ListWrapper.eqv[String] implicit val I = ListWrapper.eqv[Int] - checkAll("Validated[ListWrapper[String], ListWrapper[Int]]", EqTests[Validated[ListWrapper[String], ListWrapper[Int]]].eqv) - checkAll("Eq[Validated[ListWrapper[String], ListWrapper[Int]]]", SerializableTests.serializable(Eq[Validated[ListWrapper[String], ListWrapper[Int]]])) + checkAll("Validated[ListWrapper[String], ListWrapper[Int]]", + EqTests[Validated[ListWrapper[String], ListWrapper[Int]]].eqv) + checkAll("Eq[Validated[ListWrapper[String], ListWrapper[Int]]]", + SerializableTests.serializable(Eq[Validated[ListWrapper[String], ListWrapper[Int]]])) } test("ap2 combines failures in order") { val plus = (_: Int) + (_: Int) - Applicative[Validated[String, ?]].ap2(Valid(plus))(Invalid("1"), Invalid("2")) should === (Invalid("12")) + Applicative[Validated[String, ?]].ap2(Valid(plus))(Invalid("1"), Invalid("2")) should ===(Invalid("12")) } test("catchOnly catches matching exceptions") { - assert(Validated.catchOnly[NumberFormatException]{ "foo".toInt }.isInstanceOf[Invalid[NumberFormatException]]) + assert(Validated.catchOnly[NumberFormatException] { "foo".toInt }.isInstanceOf[Invalid[NumberFormatException]]) } test("catchOnly lets non-matching exceptions escape") { val _ = intercept[NumberFormatException] { - Validated.catchOnly[IndexOutOfBoundsException]{ "foo".toInt } + Validated.catchOnly[IndexOutOfBoundsException] { "foo".toInt } } } test("catchNonFatal catches non-fatal exceptions") { - assert(Validated.catchNonFatal{ "foo".toInt }.isInvalid) - assert(Validated.catchNonFatal{ throw new Throwable("blargh") }.isInvalid) + assert(Validated.catchNonFatal { "foo".toInt }.isInvalid) + assert(Validated.catchNonFatal { throw new Throwable("blargh") }.isInvalid) } - test("fromTry is invalid for failed try"){ + test("fromTry is invalid for failed try") { forAll { t: Try[Int] => - t.isFailure should === (Validated.fromTry(t).isInvalid) + t.isFailure should ===(Validated.fromTry(t).isInvalid) } } test("ValidatedNel") { forAll { (e: String) => val manual = Validated.invalid[NonEmptyList[String], Int](NonEmptyList.of(e)) - Validated.invalidNel[String, Int](e) should === (manual) - Validated.invalid[String, Int](e).toValidatedNel should === (manual) + Validated.invalidNel[String, Int](e) should ===(manual) + Validated.invalid[String, Int](e).toValidatedNel should ===(manual) } } test("ValidatedNec") { forAll { (e: String) ⇒ val manual = Validated.invalid[NonEmptyChain[String], Int](NonEmptyChain.one(e)) - Validated.invalidNec[String, Int](e) should === (manual) - Validated.invalid[String, Int](e).toValidatedNec should === (manual) + Validated.invalidNec[String, Int](e) should ===(manual) + Validated.invalid[String, Int](e).toValidatedNec should ===(manual) } } test("isInvalid consistent with forall and exists") { forAll { (v: Validated[String, Int], p: Int => Boolean) => if (v.isInvalid) { - v.forall(p) should === (true) - v.exists(p) should === (false) + v.forall(p) should ===(true) + v.exists(p) should ===(false) } else { - v.forall(p) should === (v.exists(p)) + v.forall(p) should ===(v.exists(p)) } } } @@ -114,111 +125,115 @@ class ValidatedSuite extends CatsSuite { forAll { (v: Validated[String, Int]) => var count = 0 v.foreach(_ => count += 1) - v.isValid should === (count == 1) - v.isInvalid should === (count == 0) + v.isValid should ===(count == 1) + v.isInvalid should ===(count == 0) } } test("getOrElse consistent with orElse") { forAll { (v: Validated[String, Int], u: Validated[String, Int], i: Int) => - v.getOrElse(u.getOrElse(i)) should === (v.orElse(u).getOrElse(i)) + v.getOrElse(u.getOrElse(i)) should ===(v.orElse(u).getOrElse(i)) } } test("findValid accumulates failures") { forAll { (v: Validated[String, Int], u: Validated[String, Int]) => - v findValid u shouldEqual { (v, u) match { - case (vv @ Valid(_), _) => vv - case (_, uu @ Valid(_)) => uu - case (Invalid(s1), Invalid(s2)) => Invalid(s1 ++ s2) - }} + v.findValid(u) shouldEqual { + (v, u) match { + case (vv @ Valid(_), _) => vv + case (_, uu @ Valid(_)) => uu + case (Invalid(s1), Invalid(s2)) => Invalid(s1 ++ s2) + } + } } } test("orElse ignores left failure") { forAll { (v: Validated[String, Int], u: Validated[String, Int]) => - v orElse u shouldEqual { (v, u) match { - case (vv @ Valid(_), _) => vv - case (_, uu) => uu - }} + v.orElse(u) shouldEqual { + (v, u) match { + case (vv @ Valid(_), _) => vv + case (_, uu) => uu + } + } } } test("valueOr consistent with swap then map then merge") { forAll { (v: Validated[String, Int], f: String => Int) => - v.valueOr(f) should === (v.swap.map(f).merge) + v.valueOr(f) should ===(v.swap.map(f).merge) } } test("toEither then fromEither is identity") { forAll { (v: Validated[String, Int]) => - Validated.fromEither(v.toEither) should === (v) + Validated.fromEither(v.toEither) should ===(v) } } test("toList and toOption are empty for invalid") { forAll { (v: Validated[String, Int]) => - v.isInvalid should === (v.toList.isEmpty) - v.isInvalid should === (v.toOption.isEmpty) + v.isInvalid should ===(v.toList.isEmpty) + v.isInvalid should ===(v.toOption.isEmpty) } } test("show isn't empty") { forAll { (v: Validated[String, Int]) => val show = implicitly[Show[Validated[String, Int]]] - show.show(v).nonEmpty should === (true) + show.show(v).nonEmpty should ===(true) } } - test("andThen consistent with Either's flatMap"){ + test("andThen consistent with Either's flatMap") { forAll { (v: Validated[String, Int], f: Int => Validated[String, Int]) => - v.andThen(f) should === (v.withEither(_.flatMap(f(_).toEither))) + v.andThen(f) should ===(v.withEither(_.flatMap(f(_).toEither))) } } - test("ad-hoc andThen tests"){ + test("ad-hoc andThen tests") { def even(i: Int): Validated[String, Int] = if (i % 2 == 0) Validated.valid(i) else Validated.invalid(s"$i is not even") - (Validated.valid(3) andThen even) should === (Validated.invalid("3 is not even")) - (Validated.valid(4) andThen even) should === (Validated.valid(4)) - (Validated.invalid("foo") andThen even) should === (Validated.invalid("foo")) + (Validated.valid(3).andThen(even)) should ===(Validated.invalid("3 is not even")) + (Validated.valid(4).andThen(even)) should ===(Validated.valid(4)) + (Validated.invalid("foo").andThen(even)) should ===(Validated.invalid("foo")) } - test("fromOption consistent with Either.fromOption"){ + test("fromOption consistent with Either.fromOption") { forAll { (o: Option[Int], s: String) => - Validated.fromOption(o, s) should === (Either.fromOption(o, s).toValidated) + Validated.fromOption(o, s) should ===(Either.fromOption(o, s).toValidated) } } - test("fromOption consistent with toOption"){ + test("fromOption consistent with toOption") { forAll { (o: Option[Int], s: String) => - Validated.fromOption(o, s).toOption should === (o) + Validated.fromOption(o, s).toOption should ===(o) } } - test("fromIor consistent with Ior.toValidated"){ + test("fromIor consistent with Ior.toValidated") { forAll { (i: Ior[String, Int]) => - Validated.fromIor(i) should === (i.toValidated) + Validated.fromIor(i) should ===(i.toValidated) } } test("toIor then fromEither is identity") { forAll { (v: Validated[String, Int]) => - Validated.fromIor(v.toIor) should === (v) + Validated.fromIor(v.toIor) should ===(v) } } test("isValid after combine, iff both are valid") { forAll { (lhs: Validated[Int, String], rhs: Validated[Int, String]) => - lhs.combine(rhs).isValid should === (lhs.isValid && rhs.isValid) + lhs.combine(rhs).isValid should ===(lhs.isValid && rhs.isValid) } } test("isInvalid consistent with isValid") { forAll { (x: Validated[String, Int]) => - x.isInvalid should !== (x.isValid) + x.isInvalid should !==(x.isValid) } } @@ -230,24 +245,24 @@ class ValidatedSuite extends CatsSuite { test("swap negates isInvalid/isValid") { forAll { (x: Validated[String, Int]) => - x.isInvalid should !== (x.swap.isInvalid) - x.isValid should !== (x.swap.isValid) + x.isInvalid should !==(x.swap.isInvalid) + x.isValid should !==(x.swap.isValid) } } - test("Unapply-based apply syntax"){ + test("Unapply-based apply syntax") { // this type has kind F[_, _], which requires `Unapply`-based syntax val x: ValidatedNel[String, Int] = Validated.invalidNel("error 1") val y: ValidatedNel[String, Boolean] = Validated.invalidNel("error 2") val z = x.map2(y)((i, b) => if (b) i + 1 else i) - z should === (NonEmptyList.of("error 1", "error 2").invalid[Int]) + z should ===(NonEmptyList.of("error 1", "error 2").invalid[Int]) } test("ensure on Invalid is identity") { - forAll { (x: Validated[Int,String], i: Int, p: String => Boolean) => + forAll { (x: Validated[Int, String], i: Int, p: String => Boolean) => if (x.isInvalid) { - x.ensure(i)(p) should === (x) + x.ensure(i)(p) should ===(x) } } } @@ -255,15 +270,15 @@ class ValidatedSuite extends CatsSuite { test("ensure should fail if predicate not satisfied") { forAll { (x: Validated[String, Int], s: String, p: Int => Boolean) => if (x.exists(!p(_))) { - x.ensure(s)(p) should === (Validated.invalid(s)) + x.ensure(s)(p) should ===(Validated.invalid(s)) } } } test("ensureOr on Invalid is identity") { - forAll { (x: Validated[Int,String], f: String => Int, p: String => Boolean) => + forAll { (x: Validated[Int, String], f: String => Int, p: String => Boolean) => if (x.isInvalid) { - x.ensureOr(f)(p) should === (x) + x.ensureOr(f)(p) should ===(x) } } } @@ -278,19 +293,19 @@ class ValidatedSuite extends CatsSuite { test("cond consistent with Either.cond + toValidated") { forAll { (cond: Boolean, s: String, i: Int) => - Validated.cond(cond, s, i) should === (Either.cond(cond, s, i).toValidated) + Validated.cond(cond, s, i) should ===(Either.cond(cond, s, i).toValidated) } } test("condNel consistent with Either.cond + toValidatedNel") { forAll { (cond: Boolean, s: String, i: Int) => - Validated.condNel(cond, s, i) should === (Either.cond(cond, s, i).toValidatedNel) + Validated.condNel(cond, s, i) should ===(Either.cond(cond, s, i).toValidatedNel) } } test("condNec consistent with Either.cond + toValidatedNec") { forAll { (cond: Boolean, s: String, i: Int) => - Validated.condNec(cond, s, i) should === (Either.cond(cond, s, i).toValidatedNec) + Validated.condNec(cond, s, i) should ===(Either.cond(cond, s, i).toValidatedNec) } } diff --git a/tests/src/test/scala/cats/tests/VectorSuite.scala b/tests/src/test/scala/cats/tests/VectorSuite.scala index 1d9562f8fa7..0f89646539a 100644 --- a/tests/src/test/scala/cats/tests/VectorSuite.scala +++ b/tests/src/test/scala/cats/tests/VectorSuite.scala @@ -2,7 +2,16 @@ package cats package tests import cats.data.{NonEmptyVector, ZipVector} -import cats.laws.discipline.{AlternativeTests, CoflatMapTests, CommutativeApplyTests, MonadTests, SemigroupalTests, SerializableTests, TraverseFilterTests, TraverseTests} +import cats.laws.discipline.{ + AlternativeTests, + CoflatMapTests, + CommutativeApplyTests, + MonadTests, + SemigroupalTests, + SerializableTests, + TraverseFilterTests, + TraverseTests +} import cats.laws.discipline.arbitrary._ class VectorSuite extends CatsSuite { @@ -27,12 +36,12 @@ class VectorSuite extends CatsSuite { checkAll("ZipVector[Int]", CommutativeApplyTests[ZipVector].commutativeApply[Int, Int, Int]) test("show") { - Vector(1, 2, 3).show should === ("Vector(1, 2, 3)") + Vector(1, 2, 3).show should ===("Vector(1, 2, 3)") - Vector.empty[Int].show should === ("Vector()") + Vector.empty[Int].show should ===("Vector()") forAll { vec: Vector[String] => - vec.show should === (vec.toString) + vec.show should ===(vec.toString) } } @@ -42,7 +51,7 @@ class VectorSuite extends CatsSuite { } ) - test("toNev on empty vector returns None"){ + test("toNev on empty vector returns None") { assert(Vector.empty[Int].toNev == None) } } diff --git a/tests/src/test/scala/cats/tests/WordCountSuite.scala b/tests/src/test/scala/cats/tests/WordCountSuite.scala index 5acf01142ee..b4e86b42d47 100644 --- a/tests/src/test/scala/cats/tests/WordCountSuite.scala +++ b/tests/src/test/scala/cats/tests/WordCountSuite.scala @@ -1,7 +1,7 @@ package cats package tests -import cats.data.{ Func, AppFunc, Const } +import cats.data.{AppFunc, Const, Func} import Func.appFunc /* @@ -10,8 +10,9 @@ import Func.appFunc */ class WordCountSuite extends CatsSuite { test("wordcount") { - import cats.data.State.{ get, set } - val text = "Faith, I must leave thee, love, and shortly too.\nMy operant powers their functions leave to do.\n".toList + import cats.data.State.{get, set} + val text = + "Faith, I must leave thee, love, and shortly too.\nMy operant powers their functions leave to do.\n".toList // A type alias to treat Int as semigroupal applicative type Count[A] = Const[Int, A] // Tye type parameter to Count is ceremonial, so hardcode it to Unit @@ -24,7 +25,9 @@ class WordCountSuite extends CatsSuite { def testIf(b: Boolean): Int = if (b) 1 else 0 // An applicative functor to count each line val countLine: AppFunc[Count, Char, Unit] = - appFunc { (c: Char) => liftInt(testIf(c == '\n')) } + appFunc { (c: Char) => + liftInt(testIf(c == '\n')) + } def isSpace(c: Char): Boolean = (c == ' ' || c == '\n') // To count words, we need to detect transitions from whitespace to non-whitespace. @@ -35,17 +38,17 @@ class WordCountSuite extends CatsSuite { y = !isSpace(c) _ <- set(y) } yield testIf(y && !x) - } andThen appFunc(liftInt) + }.andThen(appFunc(liftInt)) - val countAll = countWord product countLine product countChar + val countAll = countWord.product(countLine).product(countChar) // Run all applicative functions at once val allResults = countAll.traverse(text) val wordCountState = allResults.first.first val lineCount = allResults.first.second val charCount = allResults.second val wordCount = wordCountState.value.runA(false).value - charCount.getConst should === (96) - lineCount.getConst should === (2) - wordCount.getConst should === (17) + charCount.getConst should ===(96) + lineCount.getConst should ===(2) + wordCount.getConst should ===(17) } } diff --git a/tests/src/test/scala/cats/tests/WriterSuite.scala b/tests/src/test/scala/cats/tests/WriterSuite.scala index c0850c084f0..1c9e4a7d914 100644 --- a/tests/src/test/scala/cats/tests/WriterSuite.scala +++ b/tests/src/test/scala/cats/tests/WriterSuite.scala @@ -4,22 +4,22 @@ package tests import cats.data.Writer class WriterSuite extends CatsSuite { - test("pure syntax creates a writer with an empty log"){ + test("pure syntax creates a writer with an empty log") { forAll { (result: String) => type Logged[A] = Writer[List[Int], A] - result.pure[Logged] should === (Writer(List.empty[Int], result)) + result.pure[Logged] should ===(Writer(List.empty[Int], result)) } } - test("tell syntax creates a writer with a unit result"){ + test("tell syntax creates a writer with a unit result") { forAll { (log: List[Int]) => - log.tell should === (Writer(log, ())) + log.tell should ===(Writer(log, ())) } } test("writer syntax creates a writer with the specified result and log") { forAll { (result: String, log: List[Int]) => - result.writer(log) should === (Writer(log, result)) + result.writer(log) should ===(Writer(log, result)) } } } diff --git a/tests/src/test/scala/cats/tests/WriterTSuite.scala b/tests/src/test/scala/cats/tests/WriterTSuite.scala index 8ddf08c612a..2862c193a44 100644 --- a/tests/src/test/scala/cats/tests/WriterTSuite.scala +++ b/tests/src/test/scala/cats/tests/WriterTSuite.scala @@ -22,46 +22,47 @@ class WriterTSuite extends CatsSuite { checkAll("Eq[WriterT[List, Int, Int]]", SerializableTests.serializable(Eq[WriterT[List, Int, Int]])) checkAll("WriterT[Show, Int, Int]", ContravariantTests[WriterT[Show, Int, ?]].contravariant[Int, Int, Int]) - checkAll("Contravariant[WriterT[Show, Int, Int]]", SerializableTests.serializable(Contravariant[WriterT[Show, Int, ?]])) + checkAll("Contravariant[WriterT[Show, Int, Int]]", + SerializableTests.serializable(Contravariant[WriterT[Show, Int, ?]])) // check that this resolves Eq[Writer[Int, Int]] - test("double swap is a noop"){ + test("double swap is a noop") { forAll { w: WriterT[List, Int, Int] => - w.swap.swap should === (w) + w.swap.swap should ===(w) } } - test("reset on pure is a noop"){ + test("reset on pure is a noop") { forAll { i: Int => val w = Monad[WriterT[List, Int, ?]].pure(i) - w should === (w.reset) + w should ===(w.reset) } } - test("reset consistency"){ + test("reset consistency") { forAll { (i: Int, w1: WriterT[Id, Int, Int], w2: WriterT[Id, Int, Int]) => // if the value is the same, everything should be the same - w1.map(_ => i).reset should === (w2.map(_ => i).reset) + w1.map(_ => i).reset should ===(w2.map(_ => i).reset) } } test("tell + written is identity") { forAll { (i: Int) => - WriterT.tell[Id, Int](i).written should === (i) + WriterT.tell[Id, Int](i).written should ===(i) } } test("value + value is identity") { forAll { (i: Int) => - WriterT.value[Id, Int, Int](i).value should === (i) + WriterT.value[Id, Int, Int](i).value should ===(i) } } test("valueT + value is identity") { forAll { (i: Int) => - WriterT.valueT[Id, Int, Int](i).value should === (i) + WriterT.valueT[Id, Int, Int](i).value should ===(i) } } @@ -69,30 +70,30 @@ class WriterTSuite extends CatsSuite { forAll { (i: Int) => val writer: Writer[String, Int] = Writer.value(i) val writerT: WriterT[Option, String, Int] = WriterT.liftF(Some(i)) - writer.run.some should === (writerT.run) + writer.run.some should ===(writerT.run) } } test("show") { val writerT: WriterT[Id, List[String], String] = WriterT.put("foo")(List("Some log message")) - writerT.show should === ("(List(Some log message),foo)") + writerT.show should ===("(List(Some log message),foo)") } test("tell appends to log") { val w1: Writer[String, Int] = Writer.value(3) val w2 = w1.tell("foo") - w2 should === (Writer("foo", 3)) - w2.tell("bar") should === (Writer("foobar", 3)) + w2 should ===(Writer("foo", 3)) + w2.tell("bar") should ===(Writer("foobar", 3)) } test("tell instantiates a Writer") { - Writer.tell("foo").written should === ("foo") + Writer.tell("foo").written should ===("foo") } test("mapK consistent with f(value)+pure") { val f: List ~> Option = λ[List ~> Option](_.headOption) forAll { (writert: WriterT[List, String, Int]) => - writert.mapK(f) should === (WriterT(f(writert.run))) + writert.mapK(f) should ===(WriterT(f(writert.run))) } } @@ -100,8 +101,10 @@ class WriterTSuite extends CatsSuite { // F has a SemigroupK implicit val F: SemigroupK[ListWrapper] = ListWrapper.semigroupK - checkAll("WriterT[ListWrapper, ListWrapper[Int], ?]", SemigroupKTests[WriterT[ListWrapper, ListWrapper[Int], ?]].semigroupK[Int]) - checkAll("SemigroupK[WriterT[ListWrapper, ListWrapper[Int], ?]]", SerializableTests.serializable(SemigroupK[WriterT[ListWrapper, ListWrapper[Int], ?]])) + checkAll("WriterT[ListWrapper, ListWrapper[Int], ?]", + SemigroupKTests[WriterT[ListWrapper, ListWrapper[Int], ?]].semigroupK[Int]) + checkAll("SemigroupK[WriterT[ListWrapper, ListWrapper[Int], ?]]", + SerializableTests.serializable(SemigroupK[WriterT[ListWrapper, ListWrapper[Int], ?]])) } { @@ -110,16 +113,20 @@ class WriterTSuite extends CatsSuite { SemigroupK[WriterT[ListWrapper, ListWrapper[Int], ?]] - checkAll("WriterT[ListWrapper, ListWrapper[Int], ?]", MonoidKTests[WriterT[ListWrapper, ListWrapper[Int], ?]].monoidK[Int]) - checkAll("MonoidK[WriterT[ListWrapper, ListWrapper[Int], ?]]", SerializableTests.serializable(MonoidK[WriterT[ListWrapper, ListWrapper[Int], ?]])) + checkAll("WriterT[ListWrapper, ListWrapper[Int], ?]", + MonoidKTests[WriterT[ListWrapper, ListWrapper[Int], ?]].monoidK[Int]) + checkAll("MonoidK[WriterT[ListWrapper, ListWrapper[Int], ?]]", + SerializableTests.serializable(MonoidK[WriterT[ListWrapper, ListWrapper[Int], ?]])) } { // F has a Functor and L has no Semigroup implicit val F: Functor[ListWrapper] = ListWrapper.functor - checkAll("WriterT[ListWrapper, ListWrapper[Int], ?]", FunctorTests[WriterT[ListWrapper, ListWrapper[Int], ?]].functor[Int, Int, Int]) - checkAll("Functor[WriterT[ListWrapper, ListWrapper[Int], ?]]", SerializableTests.serializable(Functor[WriterT[ListWrapper, ListWrapper[Int], ?]])) + checkAll("WriterT[ListWrapper, ListWrapper[Int], ?]", + FunctorTests[WriterT[ListWrapper, ListWrapper[Int], ?]].functor[Int, Int, Int]) + checkAll("Functor[WriterT[ListWrapper, ListWrapper[Int], ?]]", + SerializableTests.serializable(Functor[WriterT[ListWrapper, ListWrapper[Int], ?]])) checkAll("WriterT[Listwrapper, Int, ?]", CoflatMapTests[WriterT[ListWrapper, Int, ?]].coflatMap[Int, Int, Int]) checkAll("WriterT[ListWrapper, Int, ?]", SerializableTests.serializable(CoflatMap[WriterT[ListWrapper, Int, ?]])) @@ -131,11 +138,14 @@ class WriterTSuite extends CatsSuite { Functor[Logged] - checkAll("WriterT[ListWrapper, ?, ?]", BifunctorTests[WriterT[ListWrapper, ?, ?]].bifunctor[Int, Int, Int, Int, Int, Int]) - checkAll("Bifunctor[WriterT[ListWrapper, ?, ?]]", SerializableTests.serializable(Bifunctor[WriterT[ListWrapper, ?, ?]])) + checkAll("WriterT[ListWrapper, ?, ?]", + BifunctorTests[WriterT[ListWrapper, ?, ?]].bifunctor[Int, Int, Int, Int, Int, Int]) + checkAll("Bifunctor[WriterT[ListWrapper, ?, ?]]", + SerializableTests.serializable(Bifunctor[WriterT[ListWrapper, ?, ?]])) } - implicit val iso = SemigroupalTests.Isomorphisms.invariant[WriterT[ListWrapper, ListWrapper[Int], ?]](WriterT.catsDataCoflatMapForWriterT(ListWrapper.functor)) + implicit val iso = SemigroupalTests.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`. @@ -147,8 +157,10 @@ class WriterTSuite extends CatsSuite { implicit val L: Semigroup[ListWrapper[Int]] = ListWrapper.semigroup[Int] Functor[WriterT[ListWrapper, ListWrapper[Int], ?]] - checkAll("WriterT[ListWrapper, ListWrapper[Int], ?]", ApplyTests[WriterT[ListWrapper, ListWrapper[Int], ?]].apply[Int, Int, Int]) - checkAll("Apply[WriterT[ListWrapper, ListWrapper[Int], ?]]", SerializableTests.serializable(Apply[WriterT[ListWrapper, ListWrapper[Int], ?]])) + checkAll("WriterT[ListWrapper, ListWrapper[Int], ?]", + ApplyTests[WriterT[ListWrapper, ListWrapper[Int], ?]].apply[Int, Int, Int]) + checkAll("Apply[WriterT[ListWrapper, ListWrapper[Int], ?]]", + SerializableTests.serializable(Apply[WriterT[ListWrapper, ListWrapper[Int], ?]])) Functor[WriterT[Id, ListWrapper[Int], ?]] Apply[WriterT[Id, ListWrapper[Int], ?]] @@ -171,8 +183,10 @@ class WriterTSuite extends CatsSuite { Functor[WriterT[ListWrapper, ListWrapper[Int], ?]] Apply[WriterT[ListWrapper, ListWrapper[Int], ?]] CoflatMap[WriterT[ListWrapper, ListWrapper[Int], ?]] - checkAll("WriterT[ListWrapper, ListWrapper[Int], ?] 1", FlatMapTests[WriterT[ListWrapper, ListWrapper[Int], ?]].flatMap[Int, Int, Int]) - checkAll("FlatMap[WriterT[ListWrapper, ListWrapper[Int], ?]] 1", SerializableTests.serializable(FlatMap[WriterT[ListWrapper, ListWrapper[Int], ?]])) + checkAll("WriterT[ListWrapper, ListWrapper[Int], ?] 1", + FlatMapTests[WriterT[ListWrapper, ListWrapper[Int], ?]].flatMap[Int, Int, Int]) + checkAll("FlatMap[WriterT[ListWrapper, ListWrapper[Int], ?]] 1", + SerializableTests.serializable(FlatMap[WriterT[ListWrapper, ListWrapper[Int], ?]])) Functor[WriterT[Id, ListWrapper[Int], ?]] Apply[WriterT[Id, ListWrapper[Int], ?]] @@ -197,8 +211,10 @@ class WriterTSuite extends CatsSuite { Functor[WriterT[ListWrapper, ListWrapper[Int], ?]] Apply[WriterT[ListWrapper, ListWrapper[Int], ?]] CoflatMap[WriterT[ListWrapper, ListWrapper[Int], ?]] - checkAll("WriterT[ListWrapper, ListWrapper[Int], ?] 2", FlatMapTests[WriterT[ListWrapper, ListWrapper[Int], ?]].flatMap[Int, Int, Int]) - checkAll("FlatMap[WriterT[ListWrapper, ListWrapper[Int], ?]] 2", SerializableTests.serializable(FlatMap[WriterT[ListWrapper, ListWrapper[Int], ?]])) + checkAll("WriterT[ListWrapper, ListWrapper[Int], ?] 2", + FlatMapTests[WriterT[ListWrapper, ListWrapper[Int], ?]].flatMap[Int, Int, Int]) + checkAll("FlatMap[WriterT[ListWrapper, ListWrapper[Int], ?]] 2", + SerializableTests.serializable(FlatMap[WriterT[ListWrapper, ListWrapper[Int], ?]])) Functor[WriterT[Id, ListWrapper[Int], ?]] Apply[WriterT[Id, ListWrapper[Int], ?]] @@ -224,8 +240,10 @@ class WriterTSuite extends CatsSuite { Functor[WriterT[ListWrapper, ListWrapper[Int], ?]] Apply[WriterT[ListWrapper, ListWrapper[Int], ?]] CoflatMap[WriterT[ListWrapper, ListWrapper[Int], ?]] - checkAll("WriterT[ListWrapper, ListWrapper[Int], ?]", ApplicativeTests[WriterT[ListWrapper, ListWrapper[Int], ?]].applicative[Int, Int, Int]) - checkAll("Applicative[WriterT[ListWrapper, ListWrapper[Int], ?]]", SerializableTests.serializable(Applicative[WriterT[ListWrapper, ListWrapper[Int], ?]])) + checkAll("WriterT[ListWrapper, ListWrapper[Int], ?]", + ApplicativeTests[WriterT[ListWrapper, ListWrapper[Int], ?]].applicative[Int, Int, Int]) + checkAll("Applicative[WriterT[ListWrapper, ListWrapper[Int], ?]]", + SerializableTests.serializable(Applicative[WriterT[ListWrapper, ListWrapper[Int], ?]])) Functor[WriterT[Id, ListWrapper[Int], ?]] Apply[WriterT[Id, ListWrapper[Int], ?]] @@ -253,8 +271,10 @@ class WriterTSuite extends CatsSuite { Applicative[WriterT[ListWrapper, ListWrapper[Int], ?]] FlatMap[WriterT[ListWrapper, ListWrapper[Int], ?]] CoflatMap[WriterT[ListWrapper, ListWrapper[Int], ?]] - checkAll("WriterT[ListWrapper, ListWrapper[Int], ?]", MonadTests[WriterT[ListWrapper, ListWrapper[Int], ?]].monad[Int, Int, Int]) - checkAll("Monad[WriterT[ListWrapper, ListWrapper[Int], ?], List[String]]", SerializableTests.serializable(Monad[WriterT[ListWrapper, ListWrapper[Int], ?]])) + checkAll("WriterT[ListWrapper, ListWrapper[Int], ?]", + MonadTests[WriterT[ListWrapper, ListWrapper[Int], ?]].monad[Int, Int, Int]) + checkAll("Monad[WriterT[ListWrapper, ListWrapper[Int], ?], List[String]]", + SerializableTests.serializable(Monad[WriterT[ListWrapper, ListWrapper[Int], ?]])) Functor[WriterT[Id, ListWrapper[Int], ?]] Apply[WriterT[Id, ListWrapper[Int], ?]] @@ -288,17 +308,20 @@ class WriterTSuite extends CatsSuite { Applicative[WriterT[ListWrapper, ListWrapper[Int], ?]] Alternative[WriterT[ListWrapper, ListWrapper[Int], ?]] CoflatMap[WriterT[ListWrapper, ListWrapper[Int], ?]] - checkAll("WriterT[ListWrapper, ListWrapper[Int], ?]", AlternativeTests[WriterT[ListWrapper, ListWrapper[Int], ?]].alternative[Int, Int, Int]) - checkAll("Alternative[WriterT[ListWrapper, ListWrapper[Int], ?]]", SerializableTests.serializable(Alternative[WriterT[ListWrapper, ListWrapper[Int], ?]])) + checkAll("WriterT[ListWrapper, ListWrapper[Int], ?]", + AlternativeTests[WriterT[ListWrapper, ListWrapper[Int], ?]].alternative[Int, Int, Int]) + checkAll("Alternative[WriterT[ListWrapper, ListWrapper[Int], ?]]", + SerializableTests.serializable(Alternative[WriterT[ListWrapper, ListWrapper[Int], ?]])) } { - // F[(L, V)] has a monoid + // F[(L, V)] has a monoid implicit val FLV: Monoid[ListWrapper[(Int, Int)]] = ListWrapper.monoid[(Int, Int)] Monoid[WriterT[ListWrapper, Int, Int]] checkAll("WriterT[ListWrapper, Int, Int]", MonoidTests[WriterT[ListWrapper, Int, Int]].monoid) - checkAll("Monoid[WriterT[ListWrapper, Int, Int]]", SerializableTests.serializable(Monoid[WriterT[ListWrapper, Int, Int]])) + checkAll("Monoid[WriterT[ListWrapper, Int, Int]]", + SerializableTests.serializable(Monoid[WriterT[ListWrapper, Int, Int]])) Monoid[Writer[Int, Int]] checkAll("Writer[Int, Int]", MonoidTests[Writer[Int, Int]].monoid) @@ -310,7 +333,8 @@ class WriterTSuite extends CatsSuite { Semigroup[WriterT[ListWrapper, Int, Int]] checkAll("WriterT[ListWrapper, Int, Int]", SemigroupTests[WriterT[ListWrapper, Int, Int]].semigroup) - checkAll("Semigroup[WriterT[ListWrapper, Int, Int]]", SerializableTests.serializable(Semigroup[WriterT[ListWrapper, Int, Int]])) + checkAll("Semigroup[WriterT[ListWrapper, Int, Int]]", + SerializableTests.serializable(Semigroup[WriterT[ListWrapper, Int, Int]])) Semigroup[Writer[Int, Int]] checkAll("Writer[Int, Int]", SemigroupTests[Writer[Int, Int]].semigroup) @@ -321,7 +345,7 @@ class WriterTSuite extends CatsSuite { implicit val L: Monoid[ListWrapper[Int]] = ListWrapper.monoid[Int] implicit val app = WriterT.catsDataApplicativeForWriterT[Validated[String, ?], ListWrapper[Int]] implicit val iso = SemigroupalTests.Isomorphisms.invariant[WriterT[Validated[String, ?], ListWrapper[Int], ?]] - implicit def eq1[A:Eq]: Eq[WriterT[Validated[String, ?], ListWrapper[Int], A]] = + implicit def eq1[A: Eq]: Eq[WriterT[Validated[String, ?], ListWrapper[Int], A]] = WriterT.catsDataEqForWriterT[Validated[String, ?], ListWrapper[Int], A] implicit val eq2: Eq[EitherT[WriterT[Validated[String, ?], ListWrapper[Int], ?], String, Int]] = EitherT.catsDataEqForEitherT[WriterT[Validated[String, ?], ListWrapper[Int], ?], String, Int] @@ -330,8 +354,12 @@ class WriterTSuite extends CatsSuite { Apply[WriterT[Validated[String, ?], ListWrapper[Int], ?]] Applicative[WriterT[Validated[String, ?], ListWrapper[Int], ?]] - checkAll("WriterT[Validated[String, ?], ListWrapper[Int], ?]", ApplicativeTests[WriterT[Validated[String, ?], ListWrapper[Int], ?]].applicative[Int, Int, Int]) - checkAll("Applicative[WriterT[Validated[String, ?], ListWrapper[Int], ?]]", SerializableTests.serializable(Applicative[WriterT[Validated[String, ?], ListWrapper[Int], ?]])) + checkAll("WriterT[Validated[String, ?], ListWrapper[Int], ?]", + ApplicativeTests[WriterT[Validated[String, ?], ListWrapper[Int], ?]].applicative[Int, Int, Int]) + checkAll( + "Applicative[WriterT[Validated[String, ?], ListWrapper[Int], ?]]", + SerializableTests.serializable(Applicative[WriterT[Validated[String, ?], ListWrapper[Int], ?]]) + ) } { @@ -339,16 +367,22 @@ class WriterTSuite extends CatsSuite { implicit val L: Monoid[ListWrapper[Int]] = ListWrapper.monoid[Int] implicit val appErr = WriterT.catsDataApplicativeErrorForWriterT[Validated[String, ?], ListWrapper[Int], String] implicit val iso = SemigroupalTests.Isomorphisms.invariant[WriterT[Validated[String, ?], ListWrapper[Int], ?]] - checkAll("WriterT[Validated[String, ?], ListWrapper[Int], ?]", ApplicativeErrorTests[WriterT[Validated[String, ?], ListWrapper[Int], ?], String].applicativeError[Int, Int, Int]) - checkAll("ApplicativeError[WriterT[Validated[String, ?], ListWrapper[Int], ?], Unit]", SerializableTests.serializable(ApplicativeError[WriterT[Validated[String, ?], ListWrapper[Int], ?], String])) + checkAll( + "WriterT[Validated[String, ?], ListWrapper[Int], ?]", + ApplicativeErrorTests[WriterT[Validated[String, ?], ListWrapper[Int], ?], String].applicativeError[Int, Int, Int] + ) + checkAll( + "ApplicativeError[WriterT[Validated[String, ?], ListWrapper[Int], ?], Unit]", + SerializableTests.serializable(ApplicativeError[WriterT[Validated[String, ?], ListWrapper[Int], ?], String]) + ) } { // F has a MonadError and L has a Monoid implicit val L: Monoid[ListWrapper[Int]] = ListWrapper.monoid[Int] implicit val iso = SemigroupalTests.Isomorphisms.invariant[WriterT[Option, ListWrapper[Int], ?]] - implicit val eq0: Eq[EitherT[WriterT[Option, ListWrapper[Int], ?], Unit, Int]] = EitherT.catsDataEqForEitherT[WriterT[Option, ListWrapper[Int], ?], Unit, Int] - + implicit val eq0: Eq[EitherT[WriterT[Option, ListWrapper[Int], ?], Unit, Int]] = + EitherT.catsDataEqForEitherT[WriterT[Option, ListWrapper[Int], ?], Unit, Int] Functor[WriterT[Option, ListWrapper[Int], ?]] Apply[WriterT[Option, ListWrapper[Int], ?]] @@ -358,16 +392,20 @@ class WriterTSuite extends CatsSuite { Monad[WriterT[Option, ListWrapper[Int], ?]] ApplicativeError[WriterT[Option, ListWrapper[Int], ?], Unit] - checkAll("WriterT[Option, ListWrapper[Int], ?]", MonadErrorTests[WriterT[Option, ListWrapper[Int], ?], Unit].monadError[Int, Int, Int]) - checkAll("MonadError[WriterT[Option, ListWrapper[Int], ?], Unit]", SerializableTests.serializable(MonadError[WriterT[Option, ListWrapper[Int], ?], Unit])) + checkAll("WriterT[Option, ListWrapper[Int], ?]", + MonadErrorTests[WriterT[Option, ListWrapper[Int], ?], Unit].monadError[Int, Int, Int]) + checkAll("MonadError[WriterT[Option, ListWrapper[Int], ?], Unit]", + SerializableTests.serializable(MonadError[WriterT[Option, ListWrapper[Int], ?], Unit])) } { // F has a ContravariantMonoidal ContravariantMonoidal[WriterT[Const[String, ?], Int, ?]] - checkAll("WriterT[Const[String, ?], Int, ?]", ContravariantMonoidalTests[WriterT[Const[String, ?], Int, ?]].contravariantMonoidal[Int, Int, Int]) - checkAll("ContravariantMonoidal[WriterT[Const[String, ?], Int, ?]]", SerializableTests.serializable(ContravariantMonoidal[WriterT[Const[String, ?], Int, ?]])) + checkAll("WriterT[Const[String, ?], Int, ?]", + ContravariantMonoidalTests[WriterT[Const[String, ?], Int, ?]].contravariantMonoidal[Int, Int, Int]) + checkAll("ContravariantMonoidal[WriterT[Const[String, ?], Int, ?]]", + SerializableTests.serializable(ContravariantMonoidal[WriterT[Const[String, ?], Int, ?]])) } { @@ -377,7 +415,8 @@ class WriterTSuite extends CatsSuite { Invariant[WriterT[ListWrapper, Int, ?]] checkAll("WriterT[ListWrapper, Int, ?]", InvariantTests[WriterT[ListWrapper, Int, ?]].invariant[Int, Int, Int]) - checkAll("Invariant[WriterT[ListWrapper, Int, ?]]", SerializableTests.serializable(Invariant[WriterT[ListWrapper, Int, ?]])) + checkAll("Invariant[WriterT[ListWrapper, Int, ?]]", + SerializableTests.serializable(Invariant[WriterT[ListWrapper, Int, ?]])) } { @@ -386,8 +425,10 @@ class WriterTSuite extends CatsSuite { Foldable[Const[String, ?]] Foldable[WriterT[Const[String, ?], ListWrapper[Int], ?]] - checkAll("WriterT[Const[String, ?], ListWrapper[Int], ?]", FoldableTests[WriterT[Const[String, ?], ListWrapper[Int], ?]].foldable[Int, Int]) - checkAll("Foldable[WriterT[Const[String, ?], ListWrapper[Int], ?]]", SerializableTests.serializable(Foldable[WriterT[Const[String, ?], ListWrapper[Int], ?]])) + checkAll("WriterT[Const[String, ?], ListWrapper[Int], ?]", + FoldableTests[WriterT[Const[String, ?], ListWrapper[Int], ?]].foldable[Int, Int]) + checkAll("Foldable[WriterT[Const[String, ?], ListWrapper[Int], ?]]", + SerializableTests.serializable(Foldable[WriterT[Const[String, ?], ListWrapper[Int], ?]])) Foldable[Id] Foldable[WriterT[Id, ListWrapper[Int], ?]] @@ -402,22 +443,27 @@ class WriterTSuite extends CatsSuite { Traverse[Const[String, ?]] Traverse[WriterT[Const[String, ?], ListWrapper[Int], ?]] - checkAll("WriterT[Const[String, ?], ListWrapper[Int], ?]", TraverseTests[WriterT[Const[String, ?], ListWrapper[Int], ?]].traverse[Int, Int, Int, Int, Option, Option]) - checkAll("Traverse[WriterT[Const[String, ?], ListWrapper[Int], ?]]", SerializableTests.serializable(Traverse[WriterT[Const[String, ?], ListWrapper[Int], ?]])) + checkAll("WriterT[Const[String, ?], ListWrapper[Int], ?]", + TraverseTests[WriterT[Const[String, ?], ListWrapper[Int], ?]].traverse[Int, Int, Int, Int, Option, Option]) + checkAll("Traverse[WriterT[Const[String, ?], ListWrapper[Int], ?]]", + SerializableTests.serializable(Traverse[WriterT[Const[String, ?], ListWrapper[Int], ?]])) Traverse[Id] Traverse[WriterT[Id, ListWrapper[Int], ?]] Traverse[Writer[ListWrapper[Int], ?]] - checkAll("WriterT[Id, ListWrapper[Int], ?]", TraverseTests[WriterT[Id, ListWrapper[Int], ?]].traverse[Int, Int, Int, Int, Option, Option]) + checkAll("WriterT[Id, ListWrapper[Int], ?]", + TraverseTests[WriterT[Id, ListWrapper[Int], ?]].traverse[Int, Int, Int, Int, Option, Option]) } { // F has a Comonad and L has a Monoid Comonad[WriterT[(String, ?), ListWrapper[Int], ?]] - checkAll("WriterT[(String, ?), ListWrapper[Int], ?]", ComonadTests[WriterT[(String, ?), ListWrapper[Int], ?]].comonad[Int, Int, Int]) - checkAll("Comonad[WriterT[(String, ?), ListWrapper[Int], ?]]", SerializableTests.serializable(Comonad[WriterT[(String, ?), ListWrapper[Int], ?]])) + checkAll("WriterT[(String, ?), ListWrapper[Int], ?]", + ComonadTests[WriterT[(String, ?), ListWrapper[Int], ?]].comonad[Int, Int, Int]) + checkAll("Comonad[WriterT[(String, ?), ListWrapper[Int], ?]]", + SerializableTests.serializable(Comonad[WriterT[(String, ?), ListWrapper[Int], ?]])) Comonad[Id] Comonad[WriterT[Id, ListWrapper[Int], ?]] @@ -427,5 +473,6 @@ class WriterTSuite extends CatsSuite { } checkAll("WriterT[Option, Int, ?]", CommutativeMonadTests[WriterT[Option, Int, ?]].commutativeMonad[Int, Int, Int]) - checkAll("CommutativeMonad[WriterT[Option, Int, ?]]",SerializableTests.serializable(CommutativeMonad[WriterT[Option, Int, ?]])) + checkAll("CommutativeMonad[WriterT[Option, Int, ?]]", + SerializableTests.serializable(CommutativeMonad[WriterT[Option, Int, ?]])) }