Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

2.13.0-RC1 #2792

Merged
merged 15 commits into from
Apr 17, 2019
Merged
Show file tree
Hide file tree
Changes from 13 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ jdk:

scala_version_211: &scala_version_211 2.11.12
scala_version_212: &scala_version_212 2.12.7
scala_version_213: &scala_version_213 2.13.0-M5
scala_version_213: &scala_version_213 2.13.0-RC1

before_install:
- export PATH=${PATH}:./vendor/bundle
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package alleycats
package tests

import org.scalactic.anyvals.{PosInt, PosZDouble, PosZInt}
import org.scalatest.Matchers
import org.scalatest.prop.Configuration

trait TestSettings extends Configuration with Matchers {

lazy val checkConfiguration: PropertyCheckConfiguration =
PropertyCheckConfiguration(
minSuccessful = PosInt(5),
maxDiscardedFactor = PosZDouble(50.0),
minSize = PosZInt(0),
sizeRange = PosZInt(5),
workers = PosInt(1)
)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package alleycats
package tests

import org.scalactic.anyvals.{PosInt, PosZDouble, PosZInt}
import org.scalatest.Matchers
import org.scalatest.prop.Configuration

trait TestSettings extends Configuration with Matchers {

lazy val checkConfiguration: PropertyCheckConfiguration =
PropertyCheckConfiguration(
minSuccessful = PosInt(50),
maxDiscardedFactor = PosZDouble(5.0),
minSize = PosZInt(0),
sizeRange = PosZInt(10),
workers = PosInt(1)
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,36 +2,18 @@ package alleycats
package tests

import alleycats.std.MapInstances
import catalysts.Platform
import cats._
import cats.instances.AllInstances
import cats.syntax.{AllSyntax, EqOps}
import cats.tests.StrictCatsEquality
import org.scalactic.anyvals.{PosInt, PosZDouble, PosZInt}
import org.scalatest.{FunSuite, Matchers}
import org.scalatest.prop.{Configuration, GeneratorDrivenPropertyChecks}
import org.scalatest.prop.GeneratorDrivenPropertyChecks
import org.typelevel.discipline.scalatest.Discipline
import org.scalacheck.{Arbitrary, Gen}
import org.scalacheck.Arbitrary.arbitrary

import scala.util.{Failure, Success, Try}

trait TestSettings extends Configuration with Matchers {

lazy val checkConfiguration: PropertyCheckConfiguration =
PropertyCheckConfiguration(
minSuccessful = if (Platform.isJvm) PosInt(50) else PosInt(5),
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)
)

lazy val slowCheckConfiguration: PropertyCheckConfiguration =
if (Platform.isJvm) checkConfiguration
else PropertyCheckConfiguration(sizeRange = 1, minSuccessful = 1)
}

/**
* An opinionated stack of traits to improve consistency and reduce
* boilerplate in Alleycats tests. Derived from Cats.
Expand Down
26 changes: 11 additions & 15 deletions build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -83,13 +83,13 @@ lazy val catsSettings = Seq(
"bintray/non".at("http://dl.bintray.com/non/maven")
),
libraryDependencies ++= Seq(
"org.typelevel" %%% "machinist" % "0.6.6",
compilerPlugin("org.spire-math" %% "kind-projector" % "0.9.9")
"org.typelevel" %%% "machinist" % "0.6.7",
compilerPlugin("org.typelevel" %% "kind-projector" % "0.10.0")
) ++ macroDependencies(scalaVersion.value),
) ++ commonSettings ++ publishSettings ++ scoverageSettings ++ simulacrumSettings

lazy val simulacrumSettings = Seq(
libraryDependencies += "com.github.mpilquist" %%% "simulacrum" % "0.15.0" % Provided,
libraryDependencies += "com.github.mpilquist" %%% "simulacrum" % "0.16.0" % Provided,
pomPostProcess := { (node: xml.Node) =>
new RuleTransformer(new RewriteRule {
override def transform(node: xml.Node): Seq[xml.Node] = node match {
Expand Down Expand Up @@ -151,24 +151,19 @@ lazy val includeGeneratedSrc: Setting[_] = {
}
}

val catalystsVersion = "0.8"

def scalatestVersion(scalaVersion: String): String =
if (priorTo2_13(scalaVersion)) "3.0.5" else "3.0.6-SNAP5"
val scalatestVersion = "3.0.8-RC2"

val scalaCheckVersion = "1.14.0"

val disciplineVersion = "0.10.0"
val disciplineVersion = "0.11.1"

lazy val disciplineDependencies = Seq(
libraryDependencies += "org.scalacheck" %%% "scalacheck" % scalaCheckVersion,
libraryDependencies += "org.typelevel" %%% "discipline" % disciplineVersion
)

lazy val testingDependencies = Seq(
libraryDependencies += "org.typelevel" %%% "catalysts-platform" % catalystsVersion,
libraryDependencies += "org.typelevel" %%% "catalysts-macros" % catalystsVersion % "test",
libraryDependencies += "org.scalatest" %%% "scalatest" % scalatestVersion(scalaVersion.value) % "test"
libraryDependencies += "org.scalatest" %%% "scalatest" % scalatestVersion % "test"
)

lazy val docsMappingsAPIDir = settingKey[String]("Name of subdirectory in site target directory for api docs")
Expand Down Expand Up @@ -503,7 +498,6 @@ lazy val kernel = crossProject(JSPlatform, JVMPlatform)
.settings(libraryDependencies += "org.scalacheck" %%% "scalacheck" % scalaCheckVersion % "test")

lazy val kernelLaws = crossProject(JSPlatform, JVMPlatform)
.crossType(CrossType.Pure)
.in(file("kernel-laws"))
.settings(moduleName := "cats-kernel-laws", name := "Cats kernel laws")
.settings(commonSettings)
Expand Down Expand Up @@ -554,6 +548,7 @@ lazy val tests = crossProject(JSPlatform, JVMPlatform)
.settings(noPublishSettings)
.jsSettings(commonJsSettings)
.jvmSettings(commonJvmSettings)
.settings(scalacOptions in Test := (scalacOptions in Test).value.filter(_ != "-Xfatal-warnings"))

lazy val testkit = crossProject(JSPlatform, JVMPlatform)
.crossType(CrossType.Pure)
Expand All @@ -563,9 +558,10 @@ lazy val testkit = crossProject(JSPlatform, JVMPlatform)
.settings(moduleName := "cats-testkit")
.settings(catsSettings)
.settings(disciplineDependencies)
.settings(libraryDependencies += "org.scalatest" %%% "scalatest" % scalatestVersion(scalaVersion.value))
.settings(libraryDependencies += "org.scalatest" %%% "scalatest" % scalatestVersion)
.jsSettings(commonJsSettings)
.jvmSettings(commonJvmSettings)
.settings(scalacOptions := scalacOptions.value.filter(_ != "-Xfatal-warnings"))

lazy val alleycatsCore = crossProject(JSPlatform, JVMPlatform)
.crossType(CrossType.Pure)
Expand Down Expand Up @@ -594,14 +590,14 @@ lazy val alleycatsLaws = crossProject(JSPlatform, JVMPlatform)
.jsSettings(coverageEnabled := false)

lazy val alleycatsTests = crossProject(JSPlatform, JVMPlatform)
.crossType(CrossType.Pure)
.in(file("alleycats-tests"))
.dependsOn(alleycatsLaws, testkit % "test")
.settings(moduleName := "alleycats-tests")
.settings(catsSettings)
.settings(noPublishSettings)
.jsSettings(commonJsSettings)
.jvmSettings(commonJvmSettings)
.settings(scalacOptions in Test := (scalacOptions in Test).value.filter(_ != "-Xfatal-warnings"))

// bench is currently JVM-only

Expand Down Expand Up @@ -634,7 +630,7 @@ lazy val binCompatTest = project
else //We are not testing BC on Scala 2.13 yet.
"org.typelevel" %% "cats-core" % version.value % Provided
},
"org.scalatest" %%% "scalatest" % scalatestVersion(scalaVersion.value) % Test
"org.scalatest" %%% "scalatest" % scalatestVersion % Test
)
)
.dependsOn(core.jvm % Test)
Expand Down
2 changes: 1 addition & 1 deletion core/src/main/scala/cats/ApplicativeError.scala
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ trait ApplicativeError[F[_], E] extends Applicative[F] {
* `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.
Expand Down
2 changes: 1 addition & 1 deletion core/src/main/scala/cats/MonadError.scala
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ trait MonadError[F[_], E] extends ApplicativeError[F, E] with Monad[F] {
* ApplicativeError in Cats 2.0: see [[https://github.com/typelevel/cats/issues/2685]]
*/
def adaptError[A](fa: F[A])(pf: PartialFunction[E, E]): F[A] =
recoverWith(fa)(pf.andThen(raiseError))
recoverWith(fa)(pf.andThen(raiseError[A] _))

/**
* Inverse of `attempt`
Expand Down
3 changes: 3 additions & 0 deletions core/src/main/scala/cats/data/WriterT.scala
Original file line number Diff line number Diff line change
Expand Up @@ -357,6 +357,9 @@ sealed private[data] trait WriterTFlatMap1[F[_], L] extends WriterTApply[F, L] w
implicit override def F0: FlatMap[F]
implicit def L0: Monoid[L]

override def ap[A, B](f: WriterT[F, L, A => B])(fa: WriterT[F, L, A]): WriterT[F, L, B] =
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just curious, was this an optimization opportunity you happen to come across or was it broken on RC1?
Also would it be simpler to just call fa.ap(f)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is from @SethTisue's commit, but the issue is that 2.13 sees the ap definitions in FlatMap and WriterTApply as conflicting. I personally think picking out the appropriate implementation via super is the right thing to do in this case, but I also don't think it matters much, and am happy to change it to fa.ap(f) if you'd prefer.

super[WriterTApply].ap(f)(fa)

def flatMap[A, B](fa: WriterT[F, L, A])(f: A => WriterT[F, L, B]): WriterT[F, L, B] =
fa.flatMap(f)

Expand Down
4 changes: 2 additions & 2 deletions core/src/main/scala/cats/instances/sortedMap.scala
Original file line number Diff line number Diff line change
Expand Up @@ -134,10 +134,10 @@ class SortedMapHash[K, V](implicit V: Hash[V], O: Order[K], K: Hash[K])
var c = 1
x.foreach {
case (k, v) =>
val h = StaticMethods.product2Hash(K.hash(k), V.hash(v))
val h = StaticMethods.product2HashWithPrefix(K.hash(k), V.hash(v), "Tuple2")
a += h
b ^= h
if (h != 0) c *= h
c = StaticMethods.updateUnorderedHashC(c, h)
n += 1
}
var h = mapSeed
Expand Down
2 changes: 1 addition & 1 deletion core/src/main/scala/cats/instances/sortedSet.scala
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ class SortedSetHash[A: Order: Hash] extends Hash[SortedSet[A]] {
val h = Hash[A].hash(x)
a += h
b ^= h
if (h != 0) c *= h
c = cats.kernel.instances.StaticMethods.updateUnorderedHashC(c, h)
n += 1
}
var h = setSeed
Expand Down
2 changes: 1 addition & 1 deletion core/src/main/scala/cats/syntax/applicativeError.scala
Original file line number Diff line number Diff line change
Expand Up @@ -123,5 +123,5 @@ final class ApplicativeErrorOps[F[_], E, A](private val fa: F[A]) extends AnyVal
* to `ApplicativeError` in Cats 2.0: see [[https://github.com/typelevel/cats/issues/2685]]
*/
def adaptErr(pf: PartialFunction[E, E])(implicit F: ApplicativeError[F, E]): F[A] =
F.recoverWith(fa)(pf.andThen(F.raiseError))
F.recoverWith(fa)(pf.andThen(F.raiseError[A] _))
}
2 changes: 1 addition & 1 deletion core/src/main/scala/cats/syntax/monadError.scala
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ final class MonadErrorOps[F[_], E, A](private val fa: F[A]) extends AnyVal {
*/
def reject(pf: PartialFunction[A, E])(implicit F: MonadError[F, E]): F[A] =
F.flatMap(fa) { a =>
pf.andThen(F.raiseError[A]).applyOrElse(a, (_: A) => fa)
pf.andThen(F.raiseError[A] _).applyOrElse(a, (_: A) => fa)
}

def adaptError(pf: PartialFunction[E, E])(implicit F: MonadError[F, E]): F[A] =
Expand Down
9 changes: 9 additions & 0 deletions kernel-laws/js/src/main/scala/cats/platform/Platform.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package cats.platform

private[cats] object Platform {
// using `final val` makes compiler constant-fold any use of these values, dropping dead code automatically
// $COVERAGE-OFF$
final val isJvm = false
final val isJs = true
// $COVERAGE-ON$
}
9 changes: 9 additions & 0 deletions kernel-laws/jvm/src/main/scala/cats/platform/Platform.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package cats.platform

private[cats] object Platform {
// using `final val` makes compiler constant-fold any use of these values, dropping dead code automatically
// $COVERAGE-OFF$
final val isJvm = true
final val isJs = false
// $COVERAGE-ON$
}
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
package cats.kernel.laws

import cats.platform.Platform
import org.scalacheck.Prop
import org.scalacheck.Prop.{Exception, Proof, Result}

import catalysts.Platform

import scala.util.control.NonFatal

/**
Expand All @@ -19,14 +18,10 @@ object SerializableLaws {
// This part is a bit tricky. Basically, we only want to test
// serializability on the JVM.
//
// The Platform.isJs macro will give us a literal true or false at
// compile time, so we rely on scalac to prune away the "other"
// branch. Thus, when scala.js look at this method it won't "see"
// the branch which was removed, and will avoid an error trying to
// support java.io.*.
//
// This ends up being a lot nicer than having to split the entire
// laws project.
// `Platform.isJs` is a constant expression, so we can rely on
// scalac to prune away the "other" branch. Thus, when Scala.js
// looks at this method it won't "see" the branch which was removed,
// and will avoid an error trying to support java.io.*.

def serializable[A](a: A): Prop =
if (Platform.isJs) Prop(_ => Result(status = Proof))
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,10 @@
package cats.kernel
package laws

import catalysts.Platform
import catalysts.macros.TypeTagM
import cats.kernel.instances.all._
import cats.kernel.laws.discipline._
import cats.platform.Platform

import org.typelevel.discipline.Laws
import org.typelevel.discipline.scalatest.Discipline
import org.scalacheck.{Arbitrary, Cogen, Gen}
import Arbitrary.arbitrary
Expand Down Expand Up @@ -434,14 +432,4 @@ class Tests extends FunSuite with Discipline {
implicit def hasCogen[A: Cogen]: Cogen[HasHash[A]] =
Cogen[A].contramap(_.a)
}

case class LawChecker[L <: Laws](name: String, laws: L) {
def check(f: L => L#RuleSet): Unit = checkAll(name, f(laws))
}

private[laws] def laws[L[_] <: Laws, A](implicit lws: L[A], tag: TypeTagM[A]): LawChecker[L[A]] =
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)
}
53 changes: 53 additions & 0 deletions kernel/src/main/scala-2.12-/cats/kernel/compat/HashCompat.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
package cats
package kernel
package compat

private[kernel] class HashCompat {
// Adapted from scala.util.hashing.MurmurHash#productHash.
private[kernel] def product1HashWithPrefix(_1Hash: Int, prefix: String): Int = {
import scala.util.hashing.MurmurHash3._
var h = productSeed
h = mix(h, _1Hash)
finalizeHash(h, 1)
}

// Adapted from scala.util.hashing.MurmurHash#productHash.
private[cats] def product2HashWithPrefix(_1Hash: Int, _2Hash: Int, prefix: String): Int = {
import scala.util.hashing.MurmurHash3._
var h = productSeed
h = mix(h, _1Hash)
h = mix(h, _2Hash)
finalizeHash(h, 2)
}

private[cats] def updateUnorderedHashC(c: Int, h: Int): Int = if (h != 0) c * h else c

// adapted from [[scala.util.hashing.MurmurHash3]],
// but modified standard `Any#hashCode` to `ev.hash`.
def listHash[A](x: List[A])(implicit A: Hash[A]): Int = {
import scala.util.hashing.MurmurHash3._
var n = 0
var h = seqSeed
var elems = x
while (!elems.isEmpty) {
val head = elems.head
val tail = elems.tail
h = mix(h, A.hash(head))
n += 1
elems = tail
}
finalizeHash(h, n)
}

// adapted from scala.util.hashing.MurmurHash3
def orderedHash[A](xs: TraversableOnce[A])(implicit A: Hash[A]): Int = {
import scala.util.hashing.MurmurHash3._
var n = 0
var h = seqSeed
xs.foreach { x =>
h = mix(h, A.hash(x))
n += 1
}
finalizeHash(h, n)
}
}
Loading