Skip to content

Commit

Permalink
Merge branch 'typelevel:main' into doctests-optiont
Browse files Browse the repository at this point in the history
  • Loading branch information
timo-schmid authored Oct 12, 2022
2 parents 3f5c32e + 3656491 commit b03caba
Show file tree
Hide file tree
Showing 14 changed files with 161 additions and 23 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/

package cats.compat
package cats

private[cats] type targetName = scala.annotation.targetName
package object compat {
private[cats] type targetName = scala.annotation.targetName
}
12 changes: 7 additions & 5 deletions core/src/main/scala/cats/data/Chain.scala
Original file line number Diff line number Diff line change
Expand Up @@ -1198,11 +1198,7 @@ object Chain extends ChainInstances with ChainCompanionCompat {
}

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 def catsDataMonoidForChain[A]: Monoid[Chain[A]] = theMonoid.asInstanceOf[Monoid[Chain[A]]]

implicit val catsDataInstancesForChain
: Traverse[Chain] with Alternative[Chain] with Monad[Chain] with CoflatMap[Chain] with Align[Chain] =
Expand Down Expand Up @@ -1373,6 +1369,12 @@ sealed abstract private[data] class ChainInstances extends ChainInstances1 {

}

private[this] val theMonoid: Monoid[Chain[Any]] = new Monoid[Chain[Any]] {
def empty: Chain[Any] = Chain.nil

def combine(c: Chain[Any], c2: Chain[Any]): Chain[Any] = Chain.concat(c, c2)
}

}

sealed abstract private[data] class ChainInstances1 extends ChainInstances2 {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,14 @@
package cats.kernel
package instances

import scala.annotation.nowarn

trait LazyListInstances extends LazyListInstances1 {
implicit def catsKernelStdOrderForLazyList[A: Order]: Order[LazyList[A]] =
new LazyListOrder[A]

implicit def catsKernelStdMonoidForLazyList[A]: Monoid[LazyList[A]] =
new LazyListMonoid[A]
LazyListMonoid[A]
}

private[instances] trait LazyListInstances1 extends LazyListInstances2 {
Expand Down Expand Up @@ -64,6 +67,7 @@ class LazyListEq[A](implicit ev: Eq[A]) extends Eq[LazyList[A]] {
else StaticMethods.iteratorEq(xs.iterator, ys.iterator)
}

@deprecated("Use LazyListMonoid.apply, which does not allocate a new instance", "2.9.0")
class LazyListMonoid[A] extends Monoid[LazyList[A]] {
def empty: LazyList[A] = LazyList.empty
def combine(x: LazyList[A], y: LazyList[A]): LazyList[A] = x ++ y
Expand All @@ -73,3 +77,9 @@ class LazyListMonoid[A] extends Monoid[LazyList[A]] {
override def combineAll(xs: IterableOnce[LazyList[A]]): LazyList[A] =
StaticMethods.combineAllIterable(LazyList.newBuilder[A], xs)
}

object LazyListMonoid {
@nowarn("msg=deprecated")
private[this] val singleton: Monoid[LazyList[Any]] = new LazyListMonoid[Any]
def apply[A]: Monoid[LazyList[A]] = singleton.asInstanceOf[Monoid[LazyList[A]]]
}
12 changes: 10 additions & 2 deletions kernel/src/main/scala/cats/kernel/instances/ListInstances.scala
Original file line number Diff line number Diff line change
Expand Up @@ -22,15 +22,16 @@
package cats.kernel
package instances

import scala.annotation.tailrec
import scala.annotation.{nowarn, tailrec}
import compat.scalaVersionSpecific._

@suppressUnusedImportWarningForScalaVersionSpecific
trait ListInstances extends ListInstances1 {
implicit def catsKernelStdOrderForList[A: Order]: Order[List[A]] =
new ListOrder[A]

implicit def catsKernelStdMonoidForList[A]: Monoid[List[A]] =
new ListMonoid[A]
ListMonoid[A]
}

private[instances] trait ListInstances1 extends ListInstances2 {
Expand Down Expand Up @@ -104,6 +105,7 @@ class ListEq[A](implicit ev: Eq[A]) extends Eq[List[A]] {
}
}

@deprecated("Use ListMonoid.apply, which does not allocate a new instance", "2.9.0")
class ListMonoid[A] extends Monoid[List[A]] { self =>
def empty: List[A] = Nil
def combine(x: List[A], y: List[A]): List[A] = x ::: y
Expand All @@ -127,3 +129,9 @@ class ListMonoid[A] extends Monoid[List[A]] { self =>
override def reverse = self
}
}

object ListMonoid {
@nowarn("msg=deprecated")
private[this] val singleton: Monoid[List[Any]] = new ListMonoid[Any]
def apply[A]: Monoid[List[A]] = singleton.asInstanceOf[Monoid[List[A]]]
}
13 changes: 11 additions & 2 deletions kernel/src/main/scala/cats/kernel/instances/QueueInstances.scala
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,13 @@ package instances
import scala.collection.immutable.Queue
import compat.scalaVersionSpecific._

import scala.annotation.nowarn

@suppressUnusedImportWarningForScalaVersionSpecific
trait QueueInstances extends QueueInstances1 {
implicit def catsKernelStdOrderForQueue[A: Order]: Order[Queue[A]] =
new QueueOrder[A]
implicit def catsKernelStdMonoidForQueue[A]: Monoid[Queue[A]] =
new QueueMonoid[A]
implicit def catsKernelStdMonoidForQueue[A]: Monoid[Queue[A]] = QueueMonoid[A]
}

private[instances] trait QueueInstances1 extends QueueInstances2 {
Expand Down Expand Up @@ -68,6 +69,7 @@ class QueueEq[A](implicit ev: Eq[A]) extends Eq[Queue[A]] {
else StaticMethods.iteratorEq(xs.iterator, ys.iterator)
}

@deprecated("Use QueueMonoid.apply, which does not allocate a new instance", "2.9.0")
class QueueMonoid[A] extends Monoid[Queue[A]] {
def empty: Queue[A] = Queue.empty[A]
def combine(x: Queue[A], y: Queue[A]): Queue[A] = x ++ y
Expand All @@ -78,3 +80,10 @@ class QueueMonoid[A] extends Monoid[Queue[A]] {
override def combineAll(xs: IterableOnce[Queue[A]]): Queue[A] =
StaticMethods.combineAllIterable(Queue.newBuilder[A], xs)
}

object QueueMonoid {
@nowarn("msg=deprecated")
private[this] val singleton: Monoid[Queue[Any]] = new QueueMonoid[Any]

def apply[A]: Monoid[Queue[A]] = singleton.asInstanceOf[Monoid[Queue[A]]]
}
11 changes: 10 additions & 1 deletion kernel/src/main/scala/cats/kernel/instances/SeqInstances.scala
Original file line number Diff line number Diff line change
Expand Up @@ -23,14 +23,16 @@ package cats.kernel
package instances

import compat.scalaVersionSpecific._

import scala.annotation.nowarn
import scala.collection.immutable.Seq

@suppressUnusedImportWarningForScalaVersionSpecific
trait SeqInstances extends SeqInstances1 {
implicit def catsKernelStdOrderForSeq[A: Order]: Order[Seq[A]] =
new SeqOrder[A]
implicit def catsKernelStdMonoidForSeq[A]: Monoid[Seq[A]] =
new SeqMonoid[A]
SeqMonoid[A]
}

private[instances] trait SeqInstances1 extends SeqInstances2 {
Expand Down Expand Up @@ -68,6 +70,7 @@ class SeqEq[A](implicit ev: Eq[A]) extends Eq[Seq[A]] {
else StaticMethods.iteratorEq(xs.iterator, ys.iterator)
}

@deprecated("Use SeqMonoid.apply, which does not allocate a new instance", "2.9.0")
class SeqMonoid[A] extends Monoid[Seq[A]] {
def empty: Seq[A] = Seq.empty
def combine(x: Seq[A], y: Seq[A]): Seq[A] = x ++ y
Expand All @@ -78,3 +81,9 @@ class SeqMonoid[A] extends Monoid[Seq[A]] {
override def combineAll(xs: IterableOnce[Seq[A]]): Seq[A] =
StaticMethods.combineAllIterable(Seq.newBuilder[A], xs)
}

object SeqMonoid {
@nowarn("msg=deprecated")
private[this] val singleton: Monoid[Seq[Any]] = new SeqMonoid[Any]
def apply[A]: SeqMonoid[A] = singleton.asInstanceOf[SeqMonoid[A]]
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,14 @@ package cats.kernel
package instances
import compat.scalaVersionSpecific._

import scala.annotation.nowarn

@suppressUnusedImportWarningForScalaVersionSpecific
trait VectorInstances extends VectorInstances1 {
implicit def catsKernelStdOrderForVector[A: Order]: Order[Vector[A]] =
new VectorOrder[A]
implicit def catsKernelStdMonoidForVector[A]: Monoid[Vector[A]] =
new VectorMonoid[A]
VectorMonoid[A]
}

private[instances] trait VectorInstances1 extends VectorInstances2 {
Expand Down Expand Up @@ -66,6 +68,7 @@ class VectorEq[A](implicit ev: Eq[A]) extends Eq[Vector[A]] {
else StaticMethods.iteratorEq(xs.iterator, ys.iterator)
}

@deprecated("Use VectorMonoid.apply, which does not allocate a new instance", "2.9.0")
class VectorMonoid[A] extends Monoid[Vector[A]] {
def empty: Vector[A] = Vector.empty
def combine(x: Vector[A], y: Vector[A]): Vector[A] = x ++ y
Expand All @@ -76,3 +79,10 @@ class VectorMonoid[A] extends Monoid[Vector[A]] {
override def combineAll(xs: IterableOnce[Vector[A]]): Vector[A] =
StaticMethods.combineAllIterable(Vector.newBuilder[A], xs)
}

object VectorMonoid {
@nowarn("msg=deprecated")
private[this] val singleton: Monoid[Vector[Any]] = new VectorMonoid[Any]

def apply[A]: Monoid[Vector[A]] = singleton.asInstanceOf[Monoid[Vector[A]]]
}
31 changes: 28 additions & 3 deletions laws/src/main/scala/cats/laws/discipline/arbitrary.scala
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,20 @@ object arbitrary extends ArbitraryInstances0 with ScalaVersionSpecific.Arbitrary
a <- A.arbitrary
} yield NonEmptyMap((k, a), fa))

implicit def cogenNonEmptyMap[K: Order: Cogen, A: Order: Cogen]: Cogen[NonEmptyMap[K, A]] =
@deprecated("Preserved for bincompat", "2.9.0")
def cogenNonEmptyMap[K, A](kOrder: Order[K],
kCogen: Cogen[K],
aOrder: Order[A],
aCogen: Cogen[A]
): Cogen[NonEmptyMap[K, A]] = {
implicit val orderingK: Order[K] = kOrder
implicit val cogenK: Cogen[K] = kCogen
implicit val cogenA: Cogen[A] = aCogen

cogenNonEmptyMap[K, A]
}

implicit def cogenNonEmptyMap[K: Order: Cogen, A: Cogen]: Cogen[NonEmptyMap[K, A]] =
Cogen[SortedMap[K, A]].contramap(_.toSortedMap)

implicit def catsLawsArbitraryForEitherT[F[_], A, B](implicit
Expand Down Expand Up @@ -286,9 +299,21 @@ object arbitrary extends ArbitraryInstances0 with ScalaVersionSpecific.Arbitrary
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))

implicit def catsLawsCogenForSortedMap[K: Order: Cogen, V: Order: Cogen]: Cogen[SortedMap[K, V]] = {
@deprecated("Preserved for bincompat", "2.9.0")
def catsLawsCogenForSortedMap[K, V](kOrder: Order[K],
kCogen: Cogen[K],
vOrder: Order[V],
vCogen: Cogen[V]
): Cogen[SortedMap[K, V]] = {
implicit val orderingK: Order[K] = kOrder
implicit val cogenK: Cogen[K] = kCogen
implicit val cogenA: Cogen[V] = vCogen

catsLawsCogenForSortedMap[K, V]
}

implicit def catsLawsCogenForSortedMap[K: Order: Cogen, V: Cogen]: Cogen[SortedMap[K, V]] = {
implicit val orderingK: Ordering[K] = Order[K].toOrdering
implicit val orderingV: Ordering[V] = Order[V].toOrdering

implicitly[Cogen[Map[K, V]]].contramap(_.toMap)
}
Expand Down
4 changes: 4 additions & 0 deletions mima.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,10 @@ ThisBuild / mimaBinaryIssueFilters ++= {
exclude[ReversedAbstractMethodProblem]("cats.free.ContravariantCoyoneda.k"),
exclude[DirectAbstractMethodProblem]("cats.free.Coyoneda.k"),
exclude[ReversedAbstractMethodProblem]("cats.free.Coyoneda.k")
) ++ // https://github.com/typelevel/cats/pull/4315
Seq(
exclude[MissingClassProblem]("cats.compat.compat$package"),
exclude[MissingClassProblem]("cats.compat.compat$package$")
)
}

Expand Down
9 changes: 9 additions & 0 deletions project/Boilerplate.scala
Original file line number Diff line number Diff line change
Expand Up @@ -341,6 +341,9 @@ object Boilerplate {
- /** @group ParMapArity */
- def parMap$arity[M[_], ${`A..N`}, Z]($fparams)(f: (${`A..N`}) => Z)(implicit p: NonEmptyParallel[M]): M[Z] =
- p.flatMap.map(${nestedExpansion.products}) { case ${nestedExpansion.`(a..n)`} => f(${`a..n`}) }
-
- def parFlatMap$arity[M[_], ${`A..N`}, Z]($fparams)(f: (${`A..N`}) => M[Z])(implicit p: NonEmptyParallel[M]): M[Z] =
- p.flatMap.flatMap(${nestedExpansion.products}) { case ${nestedExpansion.`(a..n)`} => f(${`a..n`}) }
|}
"""
}
Expand Down Expand Up @@ -464,6 +467,11 @@ object Boilerplate {
else
s"def parMapN[Z](f: (${`A..N`}) => Z)(implicit p: NonEmptyParallel[M]): M[Z] = Parallel.parMap$arity($tupleArgs)(f)"

val parFlatMap =
if (arity == 1)
s"def parFlatMap[Z](f: (${`A..N`}) => M[Z])(implicit p: NonEmptyParallel[M]): M[Z] = p.flatMap.flatMap($tupleArgs)(f)"
else
s"def parFlatMapN[Z](f: (${`A..N`}) => M[Z])(implicit p: NonEmptyParallel[M]): M[Z] = Parallel.parFlatMap$arity($tupleArgs)(f)"
val parTupled =
if (arity == 1) ""
else
Expand All @@ -482,6 +490,7 @@ object Boilerplate {
-private[syntax] final class Tuple${arity}ParallelOps[M[_], ${`A..N`}](private val $tupleTpe) extends Serializable {
- $parMap
- $parTupled
- $parFlatMap
-}
|
"""
Expand Down
2 changes: 1 addition & 1 deletion project/build.properties
Original file line number Diff line number Diff line change
@@ -1 +1 @@
sbt.version=1.7.1
sbt.version=1.7.2
2 changes: 1 addition & 1 deletion scalafix/project/build.properties
Original file line number Diff line number Diff line change
@@ -1 +1 @@
sbt.version=1.7.1
sbt.version=1.7.2
32 changes: 32 additions & 0 deletions tests/shared/src/test/scala/cats/tests/ParallelSuite.scala
Original file line number Diff line number Diff line change
Expand Up @@ -390,6 +390,38 @@ class ParallelSuite
}
}

test("ParFlatMapN over List should be consistent with parMapN flatten") {
forAll { (as: List[Int], bs: List[Int], cs: List[Int], mf: (Int, Int, Int) => List[Int]) =>
assert((as, bs, cs).parFlatMapN(mf) == (as, bs, cs).parMapN(mf).flatten)
}
}

test("ParFlatMapN over NonEmptyList should be consistent with parMapN flatten") {
forAll {
(as: NonEmptyList[Int], bs: NonEmptyList[Int], cs: NonEmptyList[Int], mf: (Int, Int, Int) => NonEmptyList[Int]) =>
assert((as, bs, cs).parFlatMapN(mf) == (as, bs, cs).parMapN(mf).flatten)
}
}

test("ParFlatMap over List should be consistent with flatmap") {
forAll { (as: List[Int], mf: Int => List[Int]) =>
assert(Tuple1(as).parFlatMap(mf) == Tuple1(as).flatMap(mf))
}
}

test("ParFlatMap over NonEmptyList should be consistent with flatmap") {
forAll { (as: NonEmptyList[Int], mf: Int => NonEmptyList[Int]) =>
assert(Tuple1(as).parFlatMap(mf) == Tuple1(as).flatMap(mf))
}
}

test("ParMapN over f should be consistent with parFlatMapN over f lifted in List") {
forAll { (as: List[Int], bs: List[Int], f: (Int, Int) => Int) =>
val mf: (Int, Int) => List[Int] = (a, b) => f(a, b).pure[List]
assert((as, bs).parMapN(f) == (as, bs).parFlatMapN(mf))
}
}

test("ParTupled of NonEmptyList should be consistent with ParMap of Tuple.apply") {
forAll { (fa: NonEmptyList[Int], fb: NonEmptyList[Int], fc: NonEmptyList[Int], fd: NonEmptyList[Int]) =>
assert((fa, fb, fc, fd).parTupled === ((fa, fb, fc, fd).parMapN(Tuple4.apply)))
Expand Down
26 changes: 22 additions & 4 deletions tests/shared/src/test/scala/cats/tests/SyntaxSuite.scala
Original file line number Diff line number Diff line change
Expand Up @@ -241,14 +241,32 @@ object SyntaxSuite {
}

def testParallelTuple[M[_]: Monad, F[_], A, B, C, Z](implicit P: NonEmptyParallel.Aux[M, F]) = {
val tfabc = mock[(M[A], M[B], M[C])]
val fa = mock[M[A]]
val fb = mock[M[B]]
val fc = mock[M[C]]
val f = mock[(A, B, C) => Z]

tfabc.parMapN(f)
(fa, fb, fc).parMapN(f)
val tfabc = mock[(M[A], M[B], M[C])]
val fthree = mock[(A, B, C) => Z]
val mfthree = mock[(A, B, C) => M[Z]]

tfabc.parMapN(fthree)
(fa, fb, fc).parMapN(fthree)
tfabc.parFlatMapN(mfthree)
(fa, fb, fc).parFlatMapN(mfthree)

val tfab = mock[(M[A], M[B])]
val ftwo = mock[(A, B) => Z]
val mftwo = mock[(A, B) => M[Z]]

tfab.parMapN(ftwo)
(fa, fb).parMapN(ftwo)
tfab.parFlatMapN(mftwo)
(fa, fb).parFlatMapN(mftwo)

val tfa = mock[Tuple1[M[A]]]
val mfone = mock[A => M[Z]]

tfa.parFlatMap(mfone)
}

def testParallelBi[M[_], F[_], T[_, _]: Bitraverse, A, B, C, D](implicit P: Parallel.Aux[M, F]): Unit = {
Expand Down

0 comments on commit b03caba

Please sign in to comment.