diff --git a/core/src/main/scala/cats/Show.scala b/core/src/main/scala/cats/Show.scala index 163e2f2f96..e4bd142db7 100644 --- a/core/src/main/scala/cats/Show.scala +++ b/core/src/main/scala/cats/Show.scala @@ -63,18 +63,12 @@ object Show extends ScalaVersionSpecificShowInstances with ShowInstances { /** * creates an instance of [[Show]] using the provided function */ - def show[A](f: A => String): Show[A] = - new Show[A] { - def show(a: A): String = f(a) - } + def show[A](f: A => String): Show[A] = f(_) /** * creates an instance of [[Show]] using object toString */ - def fromToString[A]: Show[A] = - new Show[A] { - def show(a: A): String = a.toString - } + def fromToString[A]: Show[A] = _.toString final case class Shown(override val toString: String) extends AnyVal object Shown { diff --git a/kernel/src/main/scala/cats/kernel/Hash.scala b/kernel/src/main/scala/cats/kernel/Hash.scala index 997d47390c..02bb7252ba 100644 --- a/kernel/src/main/scala/cats/kernel/Hash.scala +++ b/kernel/src/main/scala/cats/kernel/Hash.scala @@ -74,12 +74,9 @@ object Hash extends HashFunctions[Hash] { def hash(x: A) = x.hashCode() def eqv(x: A, y: A) = x == y } - } trait HashToHashingConversion { implicit def catsKernelHashToHashing[A](implicit ev: Hash[A]): Hashing[A] = - new Hashing[A] { - override def hash(x: A): Int = ev.hash(x) - } + ev.hash(_) } diff --git a/project/AlgebraBoilerplate.scala b/project/AlgebraBoilerplate.scala index cac6c3f7ee..6f5b0528ec 100644 --- a/project/AlgebraBoilerplate.scala +++ b/project/AlgebraBoilerplate.scala @@ -44,9 +44,7 @@ object AlgebraBoilerplate { 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("(", ", ", ")") } @@ -86,32 +84,32 @@ object AlgebraBoilerplate { import tv._ def constraints(constraint: String) = - synTypes.map(tpe => s"${tpe}: ${constraint}[${tpe}]").mkString(", ") + synTypes.map(tpe => s"$tpe: $constraint[$tpe]").mkString(", ") def tuple(results: TraversableOnce[String]) = { val resultsVec = results.toVector val a = synTypes.size val r = s"${0.until(a).map(i => resultsVec(i)).mkString(", ")}" if (a == 1) "Tuple1(" ++ r ++ ")" - else s"(${r})" + else s"($r)" } def binMethod(name: String) = synTypes.zipWithIndex.iterator.map { case (tpe, i) => val j = i + 1 - s"${tpe}.${name}(x._${j}, y._${j})" + s"$tpe.$name(x._$j, y._$j)" } def binTuple(name: String) = tuple(binMethod(name)) def unaryTuple(name: String) = { - val m = synTypes.zipWithIndex.map { case (tpe, i) => s"${tpe}.${name}(x._${i + 1})" } + val m = synTypes.zipWithIndex.map { case (tpe, i) => s"$tpe.$name(x._${i + 1})" } tuple(m) } def nullaryTuple(name: String) = { - val m = synTypes.map(tpe => s"${tpe}.${name}") + val m = synTypes.map(tpe => s"$tpe.$name") tuple(m) } @@ -125,34 +123,34 @@ object AlgebraBoilerplate { - - implicit def tuple${arity}Rig[${`A..N`}](implicit ${constraints("Rig")}): Rig[${`(A..N)`}] = - new Rig[${`(A..N)`}] { - - def one: ${`(A..N)`} = ${nullaryTuple("one")} - - def plus(x: ${`(A..N)`}, y: ${`(A..N)`}): ${`(A..N)`} = ${binTuple("plus")} - - def times(x: ${`(A..N)`}, y: ${`(A..N)`}): ${`(A..N)`} = ${binTuple("times")} - - def zero: ${`(A..N)`} = ${nullaryTuple("zero")} + - def zero = ${nullaryTuple("zero")} + - def one = ${nullaryTuple("one")} + - def plus(x: ${`(A..N)`}, y: ${`(A..N)`}) = ${binTuple("plus")} + - def times(x: ${`(A..N)`}, y: ${`(A..N)`}) = ${binTuple("times")} - } - - implicit def tuple${arity}Ring[${`A..N`}](implicit ${constraints("Ring")}): Ring[${`(A..N)`}] = - new Ring[${`(A..N)`}] { - - def one: ${`(A..N)`} = ${nullaryTuple("one")} - - def plus(x: ${`(A..N)`}, y: ${`(A..N)`}): ${`(A..N)`} = ${binTuple("plus")} - - def times(x: ${`(A..N)`}, y: ${`(A..N)`}): ${`(A..N)`} = ${binTuple("times")} - - def zero: ${`(A..N)`} = ${nullaryTuple("zero")} - - def negate(x: ${`(A..N)`}): ${`(A..N)`} = ${unaryTuple("negate")} + - def zero = ${nullaryTuple("zero")} + - def one = ${nullaryTuple("one")} + - def negate(x: ${`(A..N)`}) = ${unaryTuple("negate")} + - def plus(x: ${`(A..N)`}, y: ${`(A..N)`}) = ${binTuple("plus")} + - def times(x: ${`(A..N)`}, y: ${`(A..N)`}) = ${binTuple("times")} - } - - implicit def tuple${arity}Rng[${`A..N`}](implicit ${constraints("Rng")}): Rng[${`(A..N)`}] = - new Rng[${`(A..N)`}] { - - def plus(x: ${`(A..N)`}, y: ${`(A..N)`}): ${`(A..N)`} = ${binTuple("plus")} - - def times(x: ${`(A..N)`}, y: ${`(A..N)`}): ${`(A..N)`} = ${binTuple("times")} - - def zero: ${`(A..N)`} = ${nullaryTuple("zero")} - - def negate(x: ${`(A..N)`}): ${`(A..N)`} = ${unaryTuple("negate")} + - def zero = ${nullaryTuple("zero")} + - def negate(x: ${`(A..N)`}) = ${unaryTuple("negate")} + - def plus(x: ${`(A..N)`}, y: ${`(A..N)`}) = ${binTuple("plus")} + - def times(x: ${`(A..N)`}, y: ${`(A..N)`}) = ${binTuple("times")} - } - - implicit def tuple${arity}Semiring[${`A..N`}](implicit ${constraints("Semiring")}): Semiring[${`(A..N)`}] = - new Semiring[${`(A..N)`}] { - - def plus(x: ${`(A..N)`}, y: ${`(A..N)`}): ${`(A..N)`} = ${binTuple("plus")} - - def times(x: ${`(A..N)`}, y: ${`(A..N)`}): ${`(A..N)`} = ${binTuple("times")} - - def zero: ${`(A..N)`} = ${nullaryTuple("zero")} + - def zero = ${nullaryTuple("zero")} + - def plus(x: ${`(A..N)`}, y: ${`(A..N)`}) = ${binTuple("plus")} + - def times(x: ${`(A..N)`}, y: ${`(A..N)`}) = ${binTuple("times")} - } |} """ diff --git a/project/Boilerplate.scala b/project/Boilerplate.scala index 06348ce071..655f061051 100644 --- a/project/Boilerplate.scala +++ b/project/Boilerplate.scala @@ -75,10 +75,6 @@ object Boilerplate { if (arity <= 2) "(*, *)" else `A..(N - 2)`.mkString("(", ", ", ", *, *)") val `a..(n - 1)` = (0 until (arity - 1)).map(n => s"a$n") - val `fa._1..fa._(n - 2)` = - if (arity <= 2) "" else (0 until (arity - 2)).map(n => s"fa._${n + 1}").mkString("", ", ", ", ") - val `pure(fa._1..(n - 2))` = - if (arity <= 2) "" else (0 until (arity - 2)).map(n => s"G.pure(fa._${n + 1})").mkString("", ", ", ", ") val `a0, a(n - 1)` = if (arity <= 1) "" else `a..(n - 1)`.mkString(", ") val `[A0, A(N - 1)]` = if (arity <= 1) "" else `A..(N - 1)`.mkString("[", ", ", "]") val `(A0, A(N - 1))` = @@ -88,19 +84,15 @@ object Boilerplate { val `(A..N - 1, *)` = if (arity == 1) "Tuple1" else `A..(N - 1)`.mkString("(", ", ", ", *)") - val `(fa._1..(n - 1))` = - if (arity <= 1) "Tuple1.apply" else (0 until (arity - 1)).map(n => s"fa._${n + 1}").mkString("(", ", ", ", _)") def `A0, A(N - 1)&`(a: String): String = if (arity <= 1) s"Tuple1[$a]" else `A..(N - 1)`.mkString("(", ", ", s", $a)") - - def `fa._1..(n - 1) & `(a: String): String = - if (arity <= 1) s"Tuple1($a)" else (0 until (arity - 1)).map(n => s"fa._${n + 1}").mkString("(", ", ", s", $a)") - - def `constraints A..N`(c: String): String = synTypes.map(tpe => s"$tpe: $c[$tpe]").mkString("(implicit ", ", ", ")") + def `constraints A..N`(c: String): String = + synTypes.map(tpe => s"$tpe: $c[$tpe]").mkString("(implicit ", ", ", ")") def `constraints A..(N-1)`(c: String): String = if (arity <= 1) "" else `A..(N - 1)`.map(tpe => s"$tpe: $c[$tpe]").mkString("(implicit ", ", ", ")") - def `parameters A..(N-1)`(c: String): String = `A..(N - 1)`.map(tpe => s"$tpe: $c[$tpe]").mkString(", ") + def `parameters A..(N-1)`(c: String): String = + `A..(N - 1)`.map(tpe => s"$tpe: $c[$tpe]").mkString(", ") } trait Template { diff --git a/project/KernelBoiler.scala b/project/KernelBoiler.scala index b660d72941..c12e42483e 100644 --- a/project/KernelBoiler.scala +++ b/project/KernelBoiler.scala @@ -1,4 +1,3 @@ -import KernelBoiler.TemplateVals import sbt._ /** @@ -82,40 +81,40 @@ object KernelBoiler { abstract class TemplatedBlock(tv: TemplateVals) { import tv._ - def constraints(constraint: String) = - synTypes.map(tpe => s"${tpe}: ${constraint}[${tpe}]").mkString(", ") + def constraints(constraint: String): String = + synTypes.map(tpe => s"$tpe: $constraint[$tpe]").mkString(", ") - def tuple(results: TraversableOnce[String]) = { + def tuple(results: TraversableOnce[String]): String = { val resultsVec = results.toVector val a = synTypes.size val r = s"${0.until(a).map(i => resultsVec(i)).mkString(", ")}" if (a == 1) "Tuple1(" ++ r ++ ")" - else s"(${r})" + else s"($r)" } def tupleNHeader = s"Tuple${synTypes.size}" - def binMethod(name: String) = + def binMethod(name: String): Iterator[String] = synTypes.zipWithIndex.iterator.map { case (tpe, i) => val j = i + 1 - s"${tpe}.${name}(x._${j}, y._${j})" + s"$tpe.$name(x._$j, y._$j)" } - def binTuple(name: String) = + def binTuple(name: String): String = tuple(binMethod(name)) - def unaryTuple(name: String) = { - val m = synTypes.zipWithIndex.map { case (tpe, i) => s"${tpe}.${name}(x._${i + 1})" } + def unaryTuple(name: String): String = { + val m = synTypes.zipWithIndex.map { case (tpe, i) => s"$tpe.$name(x._${i + 1})" } tuple(m) } - def unaryMethod(name: String) = + def unaryMethod(name: String): Iterator[String] = synTypes.zipWithIndex.iterator.map { case (tpe, i) => s"$tpe.$name(x._${i + 1})" } - def nullaryTuple(name: String) = { - val m = synTypes.map(tpe => s"${tpe}.${name}") + def nullaryTuple(name: String): String = { + val m = synTypes.map(tpe => s"$tpe.$name") tuple(m) } @@ -142,28 +141,19 @@ object KernelBoiler { import tv._ def content = block""" - | implicit def catsKernelStdCommutativeGroupForTuple${arity}[${`A..N`}]( + | 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")} - | def inverse(x: ${`(A..N)`}): ${`(A..N)`} = ${unaryTuple("inverse")} - | } - | implicit def catsKernelStdOrderForTuple${arity}[${`A..N`}]( + | Semigroup.catsKernelCommutativeGroupForTuple$arity[${`A..N`}] + | implicit def catsKernelStdOrderForTuple$arity[${`A..N`}]( | implicit ${constraints("Order")} | ): Order[${`(A..N)`}] = - | new Order[${`(A..N)`}] { - | def compare(x: ${`(A..N)`}, y: ${`(A..N)`}): Int = - | ${binMethod("compare").mkString("Array(", ", ", ")")}.find(_ != 0).getOrElse(0) - | } - | implicit def catsKernelStdBoundedSemilatticeForTuple${arity}[${`A..N`}]( + | Eq.catsKernelOrderForTuple$arity[${`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")} - | }""" + | Semigroup.catsKernelBoundedSemilatticeForTuple$arity[${`A..N`}] + |""" } ), InstanceDef( @@ -174,42 +164,27 @@ object KernelBoiler { import tv._ def content = block""" - | implicit def catsKernelStdSemilatticeForTuple${arity}[${`A..N`}]( + | implicit def catsKernelStdSemilatticeForTuple$arity[${`A..N`}]( | implicit ${constraints("Semilattice")} | ): Semilattice[${`(A..N)`}] = - | new Semilattice[${`(A..N)`}] { - | def combine(x: ${`(A..N)`}, y: ${`(A..N)`}): ${`(A..N)`} = ${binTuple("combine")} - | } - | implicit def catsKernelStdCommutativeMonoidForTuple${arity}[${`A..N`}]( + | Semigroup.catsKernelSemilatticeForTuple$arity[${`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")} - | } - | implicit def catsKernelStdGroupForTuple${arity}[${`A..N`}]( + | Semigroup.catsKernelCommutativeMonoidForTuple$arity[${`A..N`}] + | implicit def catsKernelStdGroupForTuple$arity[${`A..N`}]( | implicit ${constraints("Group")} | ): Group[${`(A..N)`}] = - | new Group[${`(A..N)`}] { - | def combine(x: ${`(A..N)`}, y: ${`(A..N)`}): ${`(A..N)`} = ${binTuple("combine")} - | def empty: ${`(A..N)`} = ${nullaryTuple("empty")} - | def inverse(x: ${`(A..N)`}): ${`(A..N)`} = ${unaryTuple("inverse")} - | } - | implicit def catsKernelStdHashForTuple${arity}[${`A..N`}]( + | Semigroup.catsKernelGroupForTuple$arity[${`A..N`}] + | 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 eqv(x: ${`(A..N)`}, y: ${`(A..N)`}): Boolean = ${binMethod("eqv").mkString(" && ")} - | } - | implicit def catsKernelStdPartialOrderForTuple${arity}[${`A..N`}]( + | Eq.catsKernelHashForTuple$arity[${`A..N`}] + | implicit def catsKernelStdPartialOrderForTuple$arity[${`A..N`}]( | implicit ${constraints("PartialOrder")} | ): PartialOrder[${`(A..N)`}] = - | new PartialOrder[${`(A..N)`}] { - | def partialCompare(x: ${`(A..N)`}, y: ${`(A..N)`}): Double = - | ${binMethod("partialCompare").mkString("Array(", ", ", ")")}.find(_ != 0.0).getOrElse(0.0) - | }""" + | Eq.catsKernelPartialOrderForTuple$arity[${`A..N`}] + |""" } ), InstanceDef( @@ -220,25 +195,19 @@ object KernelBoiler { import tv._ def content = block""" - | implicit def catsKernelStdBandForTuple${arity}[${`A..N`}]( + | implicit def catsKernelStdBandForTuple$arity[${`A..N`}]( | implicit ${constraints("Band")} | ): Band[${`(A..N)`}] = - | new Band[${`(A..N)`}] { - | def combine(x: ${`(A..N)`}, y: ${`(A..N)`}): ${`(A..N)`} = ${binTuple("combine")} - | } - | implicit def catsKernelStdCommutativeSemigroupForTuple${arity}[${`A..N`}]( + | Semigroup.catsKernelBandForTuple$arity[${`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")} - | } - | implicit def catsKernelStdMonoidForTuple${arity}[${`A..N`}]( + | Semigroup.catsKernelCommutativeSemigroupForTuple$arity[${`A..N`}] + | implicit def catsKernelStdMonoidForTuple$arity[${`A..N`}]( | implicit ${constraints("Monoid")} | ): Monoid[${`(A..N)`}] = - | new Monoid[${`(A..N)`}] { - | def combine(x: ${`(A..N)`}, y: ${`(A..N)`}): ${`(A..N)`} = ${binTuple("combine")} - | def empty: ${`(A..N)`} = ${nullaryTuple("empty")} - | }""" + | Semigroup.catsKernelMonoidForTuple$arity[${`A..N`}] + |""" } ), InstanceDef( @@ -249,18 +218,15 @@ object KernelBoiler { import tv._ def content = block""" - | implicit def catsKernelStdSemigroupForTuple${arity}[${`A..N`}]( + | implicit def catsKernelStdSemigroupForTuple$arity[${`A..N`}]( | implicit ${constraints("Semigroup")} | ): Semigroup[${`(A..N)`}] = - | new Semigroup[${`(A..N)`}] { - | def combine(x: ${`(A..N)`}, y: ${`(A..N)`}): ${`(A..N)`} = ${binTuple("combine")} - | } - | implicit def catsKernelStdEqForTuple${arity}[${`A..N`}]( + | Semigroup.catsKernelSemigroupForTuple$arity[${`A..N`}] + | implicit def catsKernelStdEqForTuple$arity[${`A..N`}]( | implicit ${constraints("Eq")} | ): Eq[${`(A..N)`}] = - | new Eq[${`(A..N)`}] { - | def eqv(x: ${`(A..N)`}, y: ${`(A..N)`}): Boolean = ${binMethod("eqv").mkString(" && ")} - | }""" + | Eq.catsKernelEqForTuple$arity[${`A..N`}] + |""" } ), InstanceDef( @@ -270,10 +236,10 @@ object KernelBoiler { import tv._ def content = block""" - | implicit def catsKernelBandForTuple${arity}[${`A..N`}]( + | implicit def catsKernelBandForTuple$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")} + | ): Band[${`(A..N)`}] = Band.instance { (x, y) => + | ${binTuple("combine")} | }""" } ), @@ -284,12 +250,12 @@ object KernelBoiler { import tv._ def content = block""" - | implicit def catsKernelBoundedSemilatticeForTuple${arity}[${`A..N`}]( + | implicit def catsKernelBoundedSemilatticeForTuple$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")} - | }""" + | ): BoundedSemilattice[${`(A..N)`}] = BoundedSemilattice.instance( + | ${nullaryTuple("empty")}, + | (x, y) => ${binTuple("combine")} + | )""" } ), InstanceDef( @@ -299,12 +265,12 @@ object KernelBoiler { import tv._ def content = block""" - | implicit def catsKernelCommutativeGroupForTuple${arity}[${`A..N`}]( + | implicit def catsKernelCommutativeGroupForTuple$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")} - | def inverse(x: ${`(A..N)`}): ${`(A..N)`} = ${unaryTuple("inverse")} + | def empty = ${nullaryTuple("empty")} + | def inverse(x: ${`(A..N)`}) = ${unaryTuple("inverse")} + | def combine(x: ${`(A..N)`}, y: ${`(A..N)`}) = ${binTuple("combine")} | }""" } ), @@ -315,12 +281,12 @@ object KernelBoiler { import tv._ def content = block""" - | implicit def catsKernelCommutativeMonoidForTuple${arity}[${`A..N`}]( + | implicit def catsKernelCommutativeMonoidForTuple$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")} - | }""" + | ): CommutativeMonoid[${`(A..N)`}] = CommutativeMonoid.instance( + | ${nullaryTuple("empty")}, + | (x, y) => ${binTuple("combine")} + | )""" } ), InstanceDef( @@ -330,10 +296,10 @@ object KernelBoiler { import tv._ def content = block""" - | implicit def catsKernelCommutativeSemigroupForTuple${arity}[${`A..N`}]( + | implicit def catsKernelCommutativeSemigroupForTuple$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")} + | ): CommutativeSemigroup[${`(A..N)`}] = CommutativeSemigroup.instance { (x, y) => + | ${binTuple("combine")} | }""" } ), @@ -344,10 +310,10 @@ object KernelBoiler { import tv._ def content = block""" - | implicit def catsKernelEqForTuple${arity}[${`A..N`}]( + | implicit def catsKernelEqForTuple$arity[${`A..N`}]( | implicit ${constraints("Eq")} - | ): Eq[${`(A..N)`}] = new Eq[${`(A..N)`}] { - | def eqv(x: ${`(A..N)`}, y: ${`(A..N)`}): Boolean = ${binMethod("eqv").mkString(" && ")} + | ): Eq[${`(A..N)`}] = Eq.instance { (x, y) => + | ${binMethod("eqv").mkString(" && ")} | }""" } ), @@ -358,12 +324,12 @@ object KernelBoiler { import tv._ def content = block""" - | implicit def catsKernelGroupForTuple${arity}[${`A..N`}]( + | implicit def catsKernelGroupForTuple$arity[${`A..N`}]( | implicit ${constraints("Group")} | ): Group[${`(A..N)`}] = new Group[${`(A..N)`}] { - | def combine(x: ${`(A..N)`}, y: ${`(A..N)`}): ${`(A..N)`} = ${binTuple("combine")} - | def empty: ${`(A..N)`} = ${nullaryTuple("empty")} - | def inverse(x: ${`(A..N)`}): ${`(A..N)`} = ${unaryTuple("inverse")} + | def empty = ${nullaryTuple("empty")} + | def inverse(x: ${`(A..N)`}) = ${unaryTuple("inverse")} + | def combine(x: ${`(A..N)`}, y: ${`(A..N)`}) = ${binTuple("combine")} | }""" } ), @@ -374,12 +340,13 @@ object KernelBoiler { import tv._ def content = block""" - | implicit def catsKernelHashForTuple${arity}[${`A..N`}]( + | implicit def catsKernelHashForTuple$arity[${`A..N`}]( | implicit ${constraints("Hash")} | ): Hash[${`(A..N)`}] = new Hash[${`(A..N)`}] { - | def hash(x: ${`(A..N)`}): Int = + | def hash(x: ${`(A..N)`}) = | ${unaryMethod("hash").mkString(s"$tupleNHeader(", ", ", ")")}.hashCode() - | def eqv(x: ${`(A..N)`}, y: ${`(A..N)`}): Boolean = ${binMethod("eqv").mkString(" && ")} + | def eqv(x: ${`(A..N)`}, y: ${`(A..N)`}) = + | ${binMethod("eqv").mkString(" && ")} | }""" } ), @@ -390,12 +357,12 @@ object KernelBoiler { import tv._ def content = block""" - | implicit def catsKernelMonoidForTuple${arity}[${`A..N`}]( + | implicit def catsKernelMonoidForTuple$arity[${`A..N`}]( | implicit ${constraints("Monoid")} - | ): Monoid[${`(A..N)`}] = new Monoid[${`(A..N)`}] { - | def combine(x: ${`(A..N)`}, y: ${`(A..N)`}): ${`(A..N)`} = ${binTuple("combine")} - | def empty: ${`(A..N)`} = ${nullaryTuple("empty")} - | }""" + | ): Monoid[${`(A..N)`}] = Monoid.instance( + | ${nullaryTuple("empty")}, + | (x, y) => ${binTuple("combine")} + | )""" } ), InstanceDef( @@ -405,11 +372,10 @@ object KernelBoiler { import tv._ def content = block""" - | implicit def catsKernelOrderForTuple${arity}[${`A..N`}]( + | implicit def catsKernelOrderForTuple$arity[${`A..N`}]( | implicit ${constraints("Order")} - | ): Order[${`(A..N)`}] = new Order[${`(A..N)`}] { - | def compare(x: ${`(A..N)`}, y: ${`(A..N)`}): Int = - | ${binMethod("compare").mkString("Array(", ", ", ")")}.find(_ != 0).getOrElse(0) + | ): Order[${`(A..N)`}] = Order.from { (x, y) => + | ${binMethod("compare").mkString("Array(", ", ", ")")}.find(_ != 0).getOrElse(0) | }""" } ), @@ -420,11 +386,10 @@ object KernelBoiler { import tv._ def content = block""" - | implicit def catsKernelPartialOrderForTuple${arity}[${`A..N`}]( + | implicit def catsKernelPartialOrderForTuple$arity[${`A..N`}]( | implicit ${constraints("PartialOrder")} - | ): PartialOrder[${`(A..N)`}] = new PartialOrder[${`(A..N)`}] { - | def partialCompare(x: ${`(A..N)`}, y: ${`(A..N)`}): Double = - | ${binMethod("partialCompare").mkString("Array(", ", ", ")")}.find(_ != 0.0).getOrElse(0.0) + | ): PartialOrder[${`(A..N)`}] = PartialOrder.from { (x, y) => + | ${binMethod("partialCompare").mkString("Array(", ", ", ")")}.find(_ != 0.0).getOrElse(0.0) | }""" } ), @@ -435,10 +400,10 @@ object KernelBoiler { import tv._ def content = block""" - | implicit def catsKernelSemigroupForTuple${arity}[${`A..N`}]( + | implicit def catsKernelSemigroupForTuple$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")} + | ): Semigroup[${`(A..N)`}] = Semigroup.instance { (x, y) => + | ${binTuple("combine")} | }""" } ), @@ -449,10 +414,10 @@ object KernelBoiler { import tv._ def content = block""" - | implicit def catsKernelSemilatticeForTuple${arity}[${`A..N`}]( + | implicit def catsKernelSemilatticeForTuple$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")} + | ): Semilattice[${`(A..N)`}] = Semilattice.instance { (x, y) => + | ${binTuple("combine")} | }""" } ) diff --git a/project/TupleBifunctorInstancesBoiler.scala b/project/TupleBifunctorInstancesBoiler.scala index 9968001b44..b4e151ee98 100644 --- a/project/TupleBifunctorInstancesBoiler.scala +++ b/project/TupleBifunctorInstancesBoiler.scala @@ -5,7 +5,7 @@ import Boilerplate.{Template, TemplateVals} import sbt.File object GenTupleBifunctorInstances extends Template { - override def range = 1 to 11 + override def range = 2 to 11 override def filename(root: sbt.File): File = root / "cats" / "instances" / "NTupleBifunctorInstances.scala" @@ -18,15 +18,17 @@ object GenTupleBifunctorInstances extends Template { |package instances | |private[cats] trait NTupleBifunctorInstances { -${if (arity > 1) - block""" + | + | private def instance[F[_, _]](bim: (F[Any, Any], Any => Any, Any => Any) => F[Any, Any]): Bifunctor[F] = + | new Bifunctor[F] { + | def bimap[A, B, C, D](fab: F[A, B])(f: A => C, g: B => D): F[C, D] = + | bim(fab.asInstanceOf[F[Any, Any]], f.asInstanceOf[Any => Any], g.asInstanceOf[Any => Any]).asInstanceOf[F[C, D]] + | } + - - implicit final def catsStdBifunctorForTuple$arity${`[A0, A(N - 2)]`}: Bifunctor[${`(A..N - 2, *, *)`}] = - - new Bifunctor[${`(A..N - 2, *, *)`}] { - - def bimap[A, B, C, D](fa: (${`A0, A(N - 2)`}A, B))(f: A => C, g: B => D): (${`A0, A(N - 2)`}C, D) = (${`fa._1..fa._(n - 2)`}f(fa._${arity - 1}), g(fa._$arity)) - - }""" - else - block""" - -"""} + - instance[${`(A..N - 2, *, *)`}] { (fab, f, g) => + - fab.copy(_${arity - 1} = f(fab._${arity - 1}), _$arity = g(fab._$arity)) + - } |}""" } } diff --git a/project/TupleBitraverseInstancesBoiler.scala b/project/TupleBitraverseInstancesBoiler.scala index 659b6952ba..7b13ab0aea 100644 --- a/project/TupleBitraverseInstancesBoiler.scala +++ b/project/TupleBitraverseInstancesBoiler.scala @@ -5,7 +5,7 @@ import Boilerplate.{Template, TemplateVals} import sbt.File object GenTupleBitraverseInstances extends Template { - override def range = 1 to 11 + override def range = 2 to 11 override def filename(root: sbt.File): File = root / "cats" / "instances" / "NTupleBitraverseInstances.scala" @@ -18,20 +18,35 @@ object GenTupleBitraverseInstances extends Template { |package instances | |private[cats] trait NTupleBitraverseInstances { -${if (arity > 1) - block""" + | protected type γ[_] + | + | private def instance[F[_, _] <: Product]( + | bitrav: (F[Any, Any], Applicative[γ], Any => γ[Any], Any => γ[Any]) => γ[F[Any, Any]] + | ): Bitraverse[F] = new Bitraverse[F] { + | def bitraverse[G[_], A, B, C, D](fab: F[A, B])(f: A => G[C], g: B => G[D])(implicit G: Applicative[G]): G[F[C, D]] = + | bitrav( + | fab.asInstanceOf[F[Any, Any]], + | G.asInstanceOf[Applicative[γ]], + | f.asInstanceOf[Any => γ[Any]], + | g.asInstanceOf[Any => γ[Any]] + | ).asInstanceOf[G[F[C, D]]] + | + | @inline private def last1[A, B](fab: F[A, B]): A = + | fab.productElement(fab.productArity - 2).asInstanceOf[A] + | @inline private def last2[A, B](fab: F[A, B]): B = + | fab.productElement(fab.productArity - 1).asInstanceOf[B] + | def bifoldLeft[A, B, C](fab: F[A, B], c: C)(f: (C, A) => C, g: (C, B) => C): C = + | g(f(c, last1(fab)), last2(fab)) + | def bifoldRight[A, B, C](fab: F[A, B], c: Eval[C])(f: (A, Eval[C]) => Eval[C], g: (B, Eval[C]) => Eval[C]): Eval[C] = + | g(last2(fab), f(last1(fab), c)) + | } + - - implicit final def catsStdBitraverseForTuple$arity${`[A0, A(N - 2)]`}: Bitraverse[${`(A..N - 2, *, *)`}] = - - new Bitraverse[${`(A..N - 2, *, *)`}] { - - def bitraverse[G[_], A, B, C, D](fa: (${`A0, A(N - 2)`}A, B))(f: A => G[C], g: B => G[D])(implicit G: Applicative[G]): G[(${`A0, A(N - 2)`}C, D)] = - - G.tuple$arity(${`pure(fa._1..(n - 2))`}f(fa._${arity - 1}), g(fa._$arity)) - - def bifoldLeft[A, B, C](fa: (${`A0, A(N - 2)`}A, B), c: C)(f: (C, A) => C, g: (C, B) => C): C = - - g(f(c, fa._${arity - 1}), fa._$arity) - - def bifoldRight[A, B, C](fa: (${`A0, A(N - 2)`}A, B), c: Eval[C])(f: (A, Eval[C]) => Eval[C], g: (B, Eval[C]) => Eval[C]): Eval[C] = - - g(fa._$arity, f(fa._${arity - 1}, c)) - - }""" - else - block""" - -"""} + - instance { (fab, G, f, g) => + - G.map2(f(fab._${arity - 1}), g(fab._$arity)) { (x, y) => + - fab.copy(_${arity - 1} = x, _$arity = y) + - } + - } |}""" } } diff --git a/project/TupleMonadInstancesBoiler.scala b/project/TupleMonadInstancesBoiler.scala index 9eaad8abc1..46f66d7440 100644 --- a/project/TupleMonadInstancesBoiler.scala +++ b/project/TupleMonadInstancesBoiler.scala @@ -12,6 +12,9 @@ object GenTupleMonadInstances extends Template { override def content(tv: TemplateVals): String = { import tv._ + val `b..(n - 1)` = for (n <- 0 until arity - 1) yield s"b$n" + val `b:A..(n - 1):(N - 1)` = (for ((v, t) <- `b..(n - 1)`.zip(`A..(N - 1)`)) yield s"$v: $t").mkString(", ") + /** * This special case for N = 2 is needed because * of the deprecated versions in TupleInstances. @@ -21,31 +24,51 @@ object GenTupleMonadInstances extends Template { val flatMapTupleClass = if (arity == 2) "FlatMapNTuple2" else s"FlatMapTuple$arity" def `combine A..(N - 1)`(a: String, b: String, last: String): String = - if (arity <= 1) s"Tuple1($last)" + if (arity <= 1) + s"Tuple1($last)" else - `A..(N - 1)`.zipWithIndex.iterator - .map { case (an, i) => - s"$an.combine($a._${i + 1}, $b._${i + 1})" - } + `A..(N - 1)`.iterator.zipWithIndex + .map { case (an, i) => s"$an.combine($a._${i + 1}, $b._${i + 1})" } .mkString("(", ", ", s", $last)") - val coflattenReturn = - if (arity <= 1) "Tuple1[Tuple1[A]]" - else - s"${`A0, A(N - 1)&`(`A0, A(N - 1)&`("A"))}" - val monadPureMethod: String = if (arity <= 1) "Tuple1(a)" else `A..(N - 1)`.map(n => s"$n.empty").mkString("(", ", ", ", a)") val tailRecMCombine = - if (arity == 2) s"A0.combine(x, a0)" + `A..(N - 1)`.iterator.zipWithIndex + .map { case (an, i) => s"$an.combine(b$i, a$i)" } + .mkString(", ") + + val tailRecMMethod = + if (arity == 1) + block""" + - @tailrec + - def loop(a: A): Tuple1[B] = + - f(a) match { + - case Tuple1(Right(b)) => Tuple1(b) + - case Tuple1(Left(nextA)) => loop(nextA) + - } + - loop(a) + """ else - `A..(N - 1)`.zipWithIndex.iterator - .map { case (an, i) => - s"$an.combine(x._${i + 1}, a$i)" - } - .mkString(", ") + block""" + - @tailrec + - def loop(${`b:A..(n - 1):(N - 1)`}, a: A): ${`A0, A(N - 1)&`("B")} = + - f(a) match { + - case (${`a0, a(n - 1)`}, Right(b)) => ($tailRecMCombine, b) + - case (${`a0, a(n - 1)`}, Left(nextA)) => loop($tailRecMCombine, nextA) + - } + - f(a) match { + - case (${`a0, a(n - 1)`}, Right(b)) => (${`a0, a(n - 1)`}, b) + - case (${`a0, a(n - 1)`}, Left(nextA)) => loop(${`a0, a(n - 1)`}, nextA) + - } + """ + + val `:CommutativeMonoid` = `constraints A..(N-1)`("CommutativeMonoid") + val `:CommutativeSemigroup` = `constraints A..(N-1)`("CommutativeSemigroup") + val `:Monoid` = `constraints A..(N-1)`("Monoid") + val `:Semigroup` = `constraints A..(N-1)`("Semigroup") block""" | @@ -56,110 +79,67 @@ object GenTupleMonadInstances extends Template { |import scala.annotation.tailrec | |private[cats] trait NTupleMonadInstances extends NTupleMonadInstances1 { - - implicit final def catsStdInstancesForTuple$arity${`[A0, A(N - 1)]`}: Comonad[${`(A..N - 1, *)`}] = - - new Comonad[${`(A..N - 1, *)`}] { - - def coflatMap[A, B](fa: ${`A0, A(N - 1)&`("A")})( - - f: (${`A0, A(N - 1)&`("A")}) => B - - ): ${`A0, A(N - 1)&`("B")} = - - ${`fa._1..(n - 1) & `("f(fa)")} - - - - def extract[A](fa: ${`A0, A(N - 1)&`("A")}): A = fa._$arity + | + | private def instance[F[_] <: Product](cofMap: (F[Any], F[Any] => Any) => F[Any]): Comonad[F] = + | new Comonad[F] { + | def coflatMap[A, B](fa: F[A])(f: F[A] => B) = + | cofMap(fa.asInstanceOf[F[Any]], f.asInstanceOf[F[Any] => Any]).asInstanceOf[F[B]] + | def extract[A](fa: F[A]) = + | fa.productElement(fa.productArity - 1).asInstanceOf[A] + | def map[A, B](fa: F[A])(f: A => B) = + | coflatMap(fa)(fa => f(extract(fa))) + | } - - - override def map[A, B](fa: ${`A0, A(N - 1)&`("A")})(f: A => B): ${`A0, A(N - 1)&`("B")} = - - ${`fa._1..(n - 1) & `(s"f(fa._$arity)")} - - override def coflatten[A](fa: ${`A0, A(N - 1)&`("A")}): $coflattenReturn = - - ${`fa._1..(n - 1) & `("fa")} - - } + - implicit final def catsStdInstancesForTuple$arity${`[A0, A(N - 1)]`}: Comonad[${`(A..N - 1, *)`}] = + - instance((fa, f) => fa.copy(_$arity = f(fa))) |} - |private[cats] sealed trait NTupleMonadInstances1 extends NTupleMonadInstances2 { - - implicit final def catsStdCommutativeMonadForTuple$arity${`[A0, A(N - 1)]`}${`constraints A..(N-1)`( - "CommutativeMonoid" - )} - - : CommutativeMonad[${`(A..N - 1, *)`}] = + |private[cats] sealed trait NTupleMonadInstances1 extends NTupleMonadInstances2 { this: NTupleMonadInstances => + - implicit final def catsStdCommutativeMonadForTuple$arity${`[A0, A(N - 1)]`}${`:CommutativeMonoid`}: CommutativeMonad[${`(A..N - 1, *)`}] = - new FlatMapTuple$arity${`[A0, A(N - 1)]`}(${`A0, A(N - 1)`}) with CommutativeMonad[${`(A..N - 1, *)`}] { - - def pure[A](a: A): ${`A0, A(N - 1)&`("A")} = $monadPureMethod + - def pure[A](a: A) = $monadPureMethod - } |} - |private[cats] sealed trait NTupleMonadInstances2 extends NTupleMonadInstances3 { - - implicit final def catsStdCommutativeFlatMapForTuple$arity${`[A0, A(N - 1)]`}${`constraints A..(N-1)`( - "CommutativeSemigroup" - )} - - : CommutativeFlatMap[${`(A..N - 1, *)`}] = + |private[cats] sealed trait NTupleMonadInstances2 extends NTupleMonadInstances3 { this: NTupleMonadInstances => + - implicit final def catsStdCommutativeFlatMapForTuple$arity${`[A0, A(N - 1)]`}${`:CommutativeSemigroup`}: CommutativeFlatMap[${`(A..N - 1, *)`}] = - new FlatMapTuple$arity${`[A0, A(N - 1)]`}(${`A0, A(N - 1)`}) with CommutativeFlatMap[${`(A..N - 1, *)`}] |} - |private[cats] sealed trait NTupleMonadInstances3 extends NTupleMonadInstances4 { - - implicit def catsStdMonadForTuple$arity${`[A0, A(N - 1)]`}${`constraints A..(N-1)`("Monoid")} - - : Monad[${`(A..N - 1, *)`}] = + |private[cats] sealed trait NTupleMonadInstances3 extends NTupleMonadInstances4 { this: NTupleMonadInstances => + - implicit def catsStdMonadForTuple$arity${`[A0, A(N - 1)]`}${`:Monoid`}: Monad[${`(A..N - 1, *)`}] = - new FlatMapTuple$arity${`[A0, A(N - 1)]`}(${`A0, A(N - 1)`}) with Monad[${`(A..N - 1, *)`}] { - - def pure[A](a: A): ${`A0, A(N - 1)&`("A")} = $monadPureMethod + - def pure[A](a: A) = $monadPureMethod - } |} - |private[cats] sealed trait NTupleMonadInstances4 extends NTupleMonadInstances5 { - - implicit def catsStdFlatMapForTuple$arity${`[A0, A(N - 1)]`}${`constraints A..(N-1)`("Semigroup")} - - : FlatMap[${`(A..N - 1, *)`}] = + |private[cats] sealed trait NTupleMonadInstances4 extends NTupleMonadInstances5 { this: NTupleMonadInstances => + - implicit def catsStdFlatMapForTuple$arity${`[A0, A(N - 1)]`}${`:Semigroup`}: FlatMap[${`(A..N - 1, *)`}] = - new FlatMapTuple$arity${`[A0, A(N - 1)]`}(${`A0, A(N - 1)`}) |} - |private[cats] sealed trait NTupleMonadInstances5 { + |private[cats] sealed trait NTupleMonadInstances5 { this: NTupleMonadInstances => - implicit def catsStdInvariantForTuple$arity${`[A0, A(N - 1)]`}: Invariant[${`(A..N - 1, *)`}] = - - new Invariant[${`(A..N - 1, *)`}] { - - def imap[A, B](fa: ${`A0, A(N - 1)&`("A")})(f: A => B)(g: B => A): ${`A0, A(N - 1)&`("B")} = - - ${`fa._1..(n - 1) & `(s"f(fa._$arity)")} - - } + - catsStdInstancesForTuple$arity |} - -private[instances] class $flatMapTupleClass${`[A0, A(N - 1)]`}(${`parameters A..(N-1)`("Semigroup")}) - extends FlatMap[${`(A..N - 1, *)`}] { - - override def ap[A, B](ff: ${`A0, A(N - 1)&`("A => B")})(fa: ${`A0, A(N - 1)&`("A")}): ${`A0, A(N - 1)&`("B")} = + - override def ap[A, B](ff: ${`A0, A(N - 1)&`("A => B")})(fa: ${`A0, A(N - 1)&`("A")}) = - ${`combine A..(N - 1)`("ff", "fa", s"ff._$arity(fa._$arity)")} - - override def product[A, B]( - - fa: ${`A0, A(N - 1)&`("A")}, - - fb: ${`A0, A(N - 1)&`("B")} - - ): ${`A0, A(N - 1)&`("(A, B)")} = + - override def product[A, B](fa: ${`A0, A(N - 1)&`("A")}, fb: ${`A0, A(N - 1)&`("B")}) = - ${`combine A..(N - 1)`("fa", "fb", s"(fa._$arity, fb._$arity)")} - - override def map[A, B](fa: ${`A0, A(N - 1)&`("A")})(f: A => B): ${`A0, A(N - 1)&`("B")} = - - ${`fa._1..(n - 1) & `(s"f(fa._$arity)")} - - def flatMap[A, B](fa: ${`A0, A(N - 1)&`("A")})(f: A => ${`A0, A(N - 1)&`("B")}): ${`A0, A(N - 1)&`("B")} = { - ${if (arity > 1) block""" + - override def map[A, B](fa: ${`A0, A(N - 1)&`("A")})(f: A => B) = + - fa.copy(_$arity = f(fa._$arity)) + - def flatMap[A, B](fa: ${`A0, A(N - 1)&`("A")})(f: A => ${`A0, A(N - 1)&`("B")}) = { - val xb = f(fa._$arity) - ${`combine A..(N - 1)`("fa", "xb", s"xb._$arity")} - """ - else block""" - - f(fa._1) - """} - } - - override def productR[A, B](a: ${`A0, A(N - 1)&`("A")})(b: ${`A0, A(N - 1)&`("B")}): ${`A0, A(N - 1)&`("B")} = + - override def productR[A, B](a: ${`A0, A(N - 1)&`("A")})(b: ${`A0, A(N - 1)&`("B")}) = - ${`combine A..(N - 1)`("a", "b", s"b._$arity")} - - override def productL[A, B](a: ${`A0, A(N - 1)&`("A")})(b: ${`A0, A(N - 1)&`("B")}): ${`A0, A(N - 1)&`("A")} = + - override def productL[A, B](a: ${`A0, A(N - 1)&`("A")})(b: ${`A0, A(N - 1)&`("B")}) = - ${`combine A..(N - 1)`("a", "b", s"a._$arity")} - - override def mproduct[A, B](fa: ${`A0, A(N - 1)&`("A")})( - - f: A => ${`A0, A(N - 1)&`("B")} - - ): ${`A0, A(N - 1)&`("(A, B)")} = { + - override def mproduct[A, B](fa: ${`A0, A(N - 1)&`("A")})(f: A => ${`A0, A(N - 1)&`("B")}) = { - val xb = f(fa._$arity) - ${`combine A..(N - 1)`("fa", "xb", s"(fa._$arity, xb._$arity)")} - } - - def tailRecM[A, B](a: A)(f: A => ${`A0, A(N - 1)&`("Either[A, B]")}): ${`A0, A(N - 1)&`("B")} = { - - @tailrec - ${if (arity > 1) block""" - - def loop(x: ${`(A0, A(N - 1))`}, aa: A): ${`A0, A(N - 1)&`("B")} = - - f(aa) match { - - case (${`a0, a(n - 1)`}, Right(b)) => ($tailRecMCombine, b) - - case (${`a0, a(n - 1)`}, Left(nextA)) => loop(($tailRecMCombine), nextA) - - } - - f(a) match { - - case (${`a0, a(n - 1)`}, Right(b)) => (${`a0, a(n - 1)`}, b) - - case (${`a0, a(n - 1)`}, Left(nextA)) => loop((${`a0, a(n - 1)`}), nextA) - """ - else block""" - - def loop(aa: A): Tuple1[B] = - - f(aa) match { - - case Tuple1(Right(b)) => Tuple1(b) - - case Tuple1(Left(nextA)) => loop(nextA) - - } - - f(a) match { - - case Tuple1(Right(b)) => Tuple1(b) - - case Tuple1(Left(nextA)) => loop(nextA) - """} - - } + - def tailRecM[A, B](a: A)(f: A => ${`A0, A(N - 1)&`("Either[A, B]")}) = { + - $tailRecMMethod - } -}""" } diff --git a/project/TupleShowInstancesBoiler.scala b/project/TupleShowInstancesBoiler.scala index f3273683d8..d590d26e3c 100644 --- a/project/TupleShowInstancesBoiler.scala +++ b/project/TupleShowInstancesBoiler.scala @@ -26,9 +26,7 @@ object GenTupleShowInstances extends Template { | |private[cats] trait NTupleShowInstances { - implicit final def catsStdShowForTuple$arity[${`A..N`}]${`constraints A..N`("Show")}: Show[${`(A..N)`}] = - - new Show[${`(A..N)`}] { - - def show(f: ${`(A..N)`}): String = $showMethod - - } + - Show.show(f => $showMethod) |}""" } } diff --git a/project/TupleUnorderedFoldableInstancesBoiler.scala b/project/TupleUnorderedFoldableInstancesBoiler.scala index ff16c2eff7..224e277f73 100644 --- a/project/TupleUnorderedFoldableInstancesBoiler.scala +++ b/project/TupleUnorderedFoldableInstancesBoiler.scala @@ -18,42 +18,37 @@ object GenTupleUnorderedFoldableInstances extends Template { |package instances | |private[cats] trait NTupleUnorderedFoldableInstances { -- implicit final def catsUnorderedFoldableInstancesForTuple$arity${`[A0, A(N - 1)]`} -- : Traverse[${`(A..N - 1, *)`}] with Reducible[${`(A..N - 1, *)`}] = -- new Traverse[${`(A..N - 1, *)`}] with Reducible[${`(A..N - 1, *)`}] { -- def traverse[G[_], A, B](fa: ${`A0, A(N - 1)&`("A")})(f: A => G[B])( -- implicit G: Applicative[G] -- ): G[${`A0, A(N - 1)&`("B")}] = -- G.map(f(fa._$arity))(${`(fa._1..(n - 1))`}) -- def foldLeft[A, B](fa: ${`A0, A(N - 1)&`("A")}, b: B)(f: (B, A) => B): B = f(b, fa._$arity) -- def foldRight[A, B](fa: ${`A0, A(N - 1)&`("A")}, lb: Eval[B])( -- f: (A, Eval[B]) => Eval[B] -- ): Eval[B] = f(fa._$arity, lb) -- override def map[A, B](fa: ${`A0, A(N - 1)&`("A")})(f: A => B): ${`A0, A(N - 1)&`("B")} = -- ${`fa._1..(n - 1) & `(s"f(fa._$arity)")} -- override def foldMap[A, B](fa: ${`A0, A(N - 1)&`("A")})(f: A => B)(implicit B: Monoid[B]): B = f(fa._$arity) -- override def reduce[A](fa: ${`A0, A(N - 1)&`("A")})(implicit A: Semigroup[A]): A = fa._$arity -- def reduceLeftTo[A, B](fa: ${`A0, A(N - 1)&`("A")})(f: A => B)(g: (B, A) => B): B = f(fa._$arity) -- override def reduceLeft[A](fa: ${`A0, A(N - 1)&`("A")})(f: (A, A) => A): A = fa._$arity -- override def reduceLeftToOption[A, B](fa: ${`A0, A(N - 1)&`("A")})(f: A => B)( -- g: (B, A) => B -- ): Option[B] = Some(f(fa._$arity)) -- override def reduceRight[A](fa: ${`A0, A(N - 1)&`("A")})(f: (A, Eval[A]) => Eval[A]): Eval[A] = Now(fa._$arity) -- def reduceRightTo[A, B](fa: ${`A0, A(N - 1)&`("A")})(f: A => B)( -- g: (A, Eval[B]) => Eval[B] -- ): Eval[B] = Now(f(fa._$arity)) -- override def reduceRightToOption[A, B](fa: ${`A0, A(N - 1)&`("A")})(f: A => B)( -- g: (A, Eval[B]) => Eval[B] -- ): Eval[Option[B]] = Now(Some(f(fa._$arity))) -- override def reduceMap[A, B](fa: ${`A0, A(N - 1)&`("A")})(f: A => B)(implicit B: Semigroup[B]): B = f(fa._$arity) -- override def size[A](fa: ${`A0, A(N - 1)&`("A")}): Long = 1L -- override def get[A](fa: ${`A0, A(N - 1)&`("A")})( -- idx: Long -- ): Option[A] = if (idx == 0L) Some(fa._$arity) else None -- override def exists[A](fa: ${`A0, A(N - 1)&`("A")})(p: A => Boolean): Boolean = p(fa._$arity) -- override def forall[A](fa: ${`A0, A(N - 1)&`("A")})(p: A => Boolean): Boolean = p(fa._$arity) -- override def isEmpty[A](fa: ${`A0, A(N - 1)&`("A")}): Boolean = false -- } + | protected type γ[_] + | + | private def instance[F[_] <: Product]( + | trav: (F[Any], Applicative[γ], Any => γ[Any]) => γ[F[Any]] + | ): Traverse[F] with Reducible[F] = + | new Traverse[F] with Reducible[F] { + | def traverse[G[_], A, B](fa: F[A])(f: A => G[B])(implicit G: Applicative[G]) = + | trav(fa.asInstanceOf[F[Any]], G.asInstanceOf[Applicative[γ]], f.asInstanceOf[Any => γ[Any]]).asInstanceOf[G[F[B]]] + | @inline private def last[A](fa: F[A]): A = + | fa.productElement(fa.productArity - 1).asInstanceOf[A] + | def foldLeft[A, B](fa: F[A], b: B)(f: (B, A) => B): B = f(b, last(fa)) + | def foldRight[A, B](fa: F[A], lb: Eval[B])(f: (A, Eval[B]) => Eval[B]): Eval[B] = f(last(fa), lb) + | override def foldMap[A, B](fa: F[A])(f: A => B)(implicit B: Monoid[B]): B = f(last(fa)) + | override def reduce[A](fa: F[A])(implicit A: Semigroup[A]): A = last(fa) + | def reduceLeftTo[A, B](fa: F[A])(f: A => B)(g: (B, A) => B): B = f(last(fa)) + | override def reduceLeft[A](fa: F[A])(f: (A, A) => A): A = last(fa) + | override def reduceLeftToOption[A, B](fa: F[A])(f: A => B)(g: (B, A) => B): Option[B] = Some(f(last(fa))) + | override def reduceRight[A](fa: F[A])(f: (A, Eval[A]) => Eval[A]): Eval[A] = Now(last(fa)) + | def reduceRightTo[A, B](fa: F[A])(f: A => B)(g: (A, Eval[B]) => Eval[B]): Eval[B] = Now(f(last(fa))) + | override def reduceRightToOption[A, B](fa: F[A])(f: A => B)(g: (A, Eval[B]) => Eval[B]): Eval[Option[B]] = Now(Some(f(last(fa)))) + | override def reduceMap[A, B](fa: F[A])(f: A => B)(implicit B: Semigroup[B]): B = f(last(fa)) + | override def size[A](fa: F[A]): Long = 1L + | override def get[A](fa: F[A])(idx: Long): Option[A] = if (idx == 0L) Some(last(fa)) else None + | override def exists[A](fa: F[A])(p: A => Boolean): Boolean = p(last(fa)) + | override def forall[A](fa: F[A])(p: A => Boolean): Boolean = p(last(fa)) + | override def isEmpty[A](fa: F[A]): Boolean = false + | } + - + - implicit final def catsUnorderedFoldableInstancesForTuple$arity${`[A0, A(N - 1)]`} + - : Traverse[${`(A..N - 1, *)`}] with Reducible[${`(A..N - 1, *)`}] + - = instance((fa, G, f) => G.map(f(fa._$arity))(x => fa.copy(_$arity = x))) |}""" } }