Skip to content

Commit

Permalink
Optimize AlgebraBoilerplate by using instance constructors
Browse files Browse the repository at this point in the history
  • Loading branch information
joroKr21 committed Aug 26, 2021
1 parent 5f4a965 commit 50a4dec
Show file tree
Hide file tree
Showing 5 changed files with 61 additions and 31 deletions.
8 changes: 8 additions & 0 deletions algebra-core/src/main/scala/algebra/ring/Rig.scala
Original file line number Diff line number Diff line change
Expand Up @@ -19,4 +19,12 @@ trait Rig[@sp(Int, Long, Float, Double) A] extends Any with Semiring[A] with Mul

object Rig extends AdditiveMonoidFunctions[Rig] with MultiplicativeMonoidFunctions[Rig] {
@inline final def apply[A](implicit ev: Rig[A]): Rig[A] = ev

private[algebra] def instance[A](z: A, o: A, add: (A, A) => A, mul: (A, A) => A): Rig[A] =
new Rig[A] {
val zero: A = z
val one: A = o
def plus(x: A, y: A): A = add(x, y)
def times(x: A, y: A): A = mul(x, y)
}
}
9 changes: 9 additions & 0 deletions algebra-core/src/main/scala/algebra/ring/Ring.scala
Original file line number Diff line number Diff line change
Expand Up @@ -115,4 +115,13 @@ trait RingFunctions[R[T] <: Ring[T]] extends AdditiveGroupFunctions[R] with Mult

object Ring extends RingFunctions[Ring] {
@inline final def apply[A](implicit ev: Ring[A]): Ring[A] = ev

private[algebra] def instance[A](z: A, o: A, neg: A => A, add: (A, A) => A, mul: (A, A) => A): Ring[A] =
new Ring[A] {
val zero: A = z
val one: A = o
def negate(x: A): A = neg(x)
def plus(x: A, y: A): A = add(x, y)
def times(x: A, y: A): A = mul(x, y)
}
}
8 changes: 8 additions & 0 deletions algebra-core/src/main/scala/algebra/ring/Rng.scala
Original file line number Diff line number Diff line change
Expand Up @@ -19,4 +19,12 @@ trait Rng[@sp(Int, Long, Float, Double) A] extends Any with Semiring[A] with Add

object Rng extends AdditiveGroupFunctions[Rng] with MultiplicativeSemigroupFunctions[Rng] {
@inline final def apply[A](implicit ev: Rng[A]): Rng[A] = ev

private[algebra] def instance[A](z: A, neg: A => A, add: (A, A) => A, mul: (A, A) => A): Rng[A] =
new Rng[A] {
val zero: A = z
def negate(x: A): A = neg(x)
def plus(x: A, y: A): A = add(x, y)
def times(x: A, y: A): A = mul(x, y)
}
}
7 changes: 7 additions & 0 deletions algebra-core/src/main/scala/algebra/ring/Semiring.scala
Original file line number Diff line number Diff line change
Expand Up @@ -23,4 +23,11 @@ trait Semiring[@sp(Int, Long, Float, Double) A]

object Semiring extends AdditiveMonoidFunctions[Semiring] with MultiplicativeSemigroupFunctions[Semiring] {
@inline final def apply[A](implicit ev: Semiring[A]): Semiring[A] = ev

private[algebra] def instance[A](z: A, add: (A, A) => A, mul: (A, A) => A): Semiring[A] =
new Semiring[A] {
val zero: A = z
def plus(x: A, y: A): A = add(x, y)
def times(x: A, y: A): A = mul(x, y)
}
}
60 changes: 29 additions & 31 deletions project/AlgebraBoilerplate.scala
Original file line number Diff line number Diff line change
Expand Up @@ -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("(", ", ", ")")
}

Expand Down Expand Up @@ -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)
}

Expand All @@ -124,36 +122,36 @@ object AlgebraBoilerplate {
|trait TupleInstances extends cats.kernel.instances.TupleInstances {
-
- 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")}
- }
- Rig.instance(
- ${nullaryTuple("zero")},
- ${nullaryTuple("one")},
- (x, y) => ${binTuple("plus")},
- (x, y) => ${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")}
- }
- Ring.instance(
- ${nullaryTuple("zero")},
- ${nullaryTuple("one")},
- x => ${unaryTuple("negate")},
- (x, y) => ${binTuple("plus")},
- (x, y) => ${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")}
- }
- Rng.instance(
- ${nullaryTuple("zero")},
- x => ${unaryTuple("negate")},
- (x, y) => ${binTuple("plus")},
- (x, y) => ${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")}
- }
- Semiring.instance(
- ${nullaryTuple("zero")},
- (x, y) => ${binTuple("plus")},
- (x, y) => ${binTuple("times")}
- )
|}
"""
}
Expand Down

0 comments on commit 50a4dec

Please sign in to comment.