Skip to content

Commit

Permalink
Optimize cats-core boilerplate
Browse files Browse the repository at this point in the history
  • Loading branch information
joroKr21 committed May 8, 2021
1 parent 1671eb7 commit e4bea48
Show file tree
Hide file tree
Showing 6 changed files with 95 additions and 86 deletions.
16 changes: 4 additions & 12 deletions project/Boilerplate.scala
Original file line number Diff line number Diff line change
Expand Up @@ -74,10 +74,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))` =
Expand All @@ -87,19 +83,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 {
Expand Down
20 changes: 11 additions & 9 deletions project/TupleBifunctorInstancesBoiler.scala
Original file line number Diff line number Diff line change
Expand Up @@ -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"

Expand All @@ -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))
- }
|}"""
}
}
43 changes: 29 additions & 14 deletions project/TupleBitraverseInstancesBoiler.scala
Original file line number Diff line number Diff line change
Expand Up @@ -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"

Expand All @@ -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)
- }
- }
|}"""
}
}
40 changes: 19 additions & 21 deletions project/TupleMonadInstancesBoiler.scala
Original file line number Diff line number Diff line change
Expand Up @@ -56,49 +56,47 @@ object GenTupleMonadInstances extends Template {
|import scala.annotation.tailrec
|
|private[cats] trait NTupleMonadInstances extends NTupleMonadInstances1 {
|
| 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)))
| }
-
- 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
- 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")}
- }
- instance((fa, f) => fa.copy(_$arity = f(fa)))
|}
|private[cats] sealed trait NTupleMonadInstances1 extends NTupleMonadInstances2 {
|private[cats] sealed trait NTupleMonadInstances1 extends NTupleMonadInstances2 { this: NTupleMonadInstances =>
- implicit final def catsStdCommutativeMonadForTuple$arity${`[A0, A(N - 1)]`}${`constraints 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
- }
|}
|private[cats] sealed trait NTupleMonadInstances2 extends NTupleMonadInstances3 {
|private[cats] sealed trait NTupleMonadInstances2 extends NTupleMonadInstances3 { this: NTupleMonadInstances =>
- implicit final def catsStdCommutativeFlatMapForTuple$arity${`[A0, A(N - 1)]`}${`constraints 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 {
|private[cats] sealed trait NTupleMonadInstances3 extends NTupleMonadInstances4 { this: NTupleMonadInstances =>
- implicit def catsStdMonadForTuple$arity${`[A0, A(N - 1)]`}${`constraints 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
- }
|}
|private[cats] sealed trait NTupleMonadInstances4 extends NTupleMonadInstances5 {
|private[cats] sealed trait NTupleMonadInstances4 extends NTupleMonadInstances5 { this: NTupleMonadInstances =>
- implicit def catsStdFlatMapForTuple$arity${`[A0, A(N - 1)]`}${`constraints 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, *)`}] {
Expand All @@ -107,7 +105,7 @@ object GenTupleMonadInstances extends Template {
- override def product[A, B](fa: ${`A0, A(N - 1)&`("A")}, fb: ${`A0, A(N - 1)&`("B")}): ${`A0, A(N - 1)&`("(A, 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)")}
- fa.copy(_$arity = 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"""
- val xb = f(fa._$arity)
Expand Down
4 changes: 1 addition & 3 deletions project/TupleShowInstancesBoiler.scala
Original file line number Diff line number Diff line change
Expand Up @@ -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
- }
- f => $showMethod
|}"""
}
}
58 changes: 31 additions & 27 deletions project/TupleUnorderedFoldableInstancesBoiler.scala
Original file line number Diff line number Diff line change
Expand Up @@ -18,33 +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)))
|}"""
}
}

0 comments on commit e4bea48

Please sign in to comment.