Skip to content

Commit

Permalink
[base] Replace Repeated and BiRepeated subclasses with apply invocations
Browse files Browse the repository at this point in the history
  • Loading branch information
rayrobdod committed May 11, 2024
1 parent 708fc23 commit ea891a1
Show file tree
Hide file tree
Showing 3 changed files with 103 additions and 120 deletions.
56 changes: 23 additions & 33 deletions Base/src/main/scala-2/typeclass/VersionSpecificRepeated.scala
Original file line number Diff line number Diff line change
Expand Up @@ -112,49 +112,39 @@ trait VersionSpecificBiRepeated {
}

implicit override def unit:BiRepeated[c.Expr, Unit, Unit] = {
new BiRepeated[c.Expr, Unit, Unit] {
type Acc = Unit
override def init():Acc = ()
override def append(acc:Acc, elem:Unit):Unit = {}
override def result(acc:Acc):Unit = ()

override def headTail:PartialExprFunction[c.Expr, Unit, (Unit, Unit)] = {
PartialExprFunction[c.Expr, Unit, (Unit, Unit)](
_ => exprTrue,
value => (value, value)
)
}
override def isEmpty(it:Unit):c.Expr[Boolean] = exprTrue
}
BiRepeated.apply[c.Expr, Unit, Unit, Unit](
() => (),
(acc, _) => acc,
(acc) => acc,
PartialExprFunction[c.Expr, Unit, (Unit, Unit)](
_ => exprTrue,
value => (value, value)
),
_ => exprTrue,
)
}

implicit override def toExprList[A](implicit typA:c.TypeTag[A]):BiRepeated[c.Expr, c.Expr[A], c.Expr[List[A]]] = {
new BiRepeated[c.Expr, c.Expr[A], c.Expr[List[A]]] {
type Acc = Builder[c.Tree, List[c.Tree]]
override def init():Acc = List.newBuilder[c.Tree]
override def append(acc:Acc, elem:c.Expr[A]):Acc = {acc += elem.tree}
override def result(acc:Acc):c.Expr[List[A]] = {
BiRepeated.apply[c.Expr, c.Expr[A], Builder[c.Tree, List[c.Tree]], c.Expr[List[A]]](
() => List.newBuilder[c.Tree],
(acc, elem) => {acc += elem.tree},
(acc) => {
c.Expr[List[A]](
c.universe.Apply(
selectTermNames[Nothing]("_root_", "scala", "collection", "immutable", "List", "apply").tree,
acc.result()
)
)
}

override def headTail:PartialExprFunction[c.Expr, c.Expr[List[A]], (c.Expr[A], c.Expr[List[A]])] = {
PartialExprFunction(
it => select[List[A], Boolean](it, "nonEmpty"),
it => (
select[List[A], A](it, "head"),
select[List[A], List[A]](it, "tail")
)
},
PartialExprFunction(
it => select[List[A], Boolean](it, "nonEmpty"),
it => (
select[List[A], A](it, "head"),
select[List[A], List[A]](it, "tail")
)
}
override def isEmpty(it:c.Expr[List[A]]):c.Expr[Boolean] = {
select[List[A], Boolean](it, "isEmpty")
}
}
),
it => select[List[A], Boolean](it, "isEmpty"),
)
}
}
}
Expand Down
50 changes: 20 additions & 30 deletions Base/src/main/scala-3/typeclass/VersionSpecificRepeated.scala
Original file line number Diff line number Diff line change
Expand Up @@ -68,39 +68,29 @@ trait VersionSpecificLowPrioContraRepeated {
private[typeclass]
trait VersionSpecificBiRepeated {
given quotedUnit(using Quotes):BiRepeated[Expr, Unit, Unit] = {
new BiRepeated[Expr, Unit, Unit] {
type Acc = Unit
override def init():Acc = ()
override def append(acc:Acc, elem:Unit):Unit = {}
override def result(acc:Acc):Unit = ()

override def headTail:PartialExprFunction[Expr, Unit, (Unit, Unit)] = {
PartialExprFunction[Expr, Unit, (Unit, Unit)](
it => Expr(true),
it => (it, it)
)
}
override def isEmpty(it:Unit):Expr[Boolean] = Expr(true)
}
BiRepeated.apply[Expr, Unit, Unit, Unit](
() => (),
(acc, _) => acc,
(acc) => acc,
PartialExprFunction[Expr, Unit, (Unit, Unit)](
_ => Expr(true),
value => (value, value),
),
_ => Expr(true),
)
}

given quotedToExprList[A](using Quotes, Type[A]):BiRepeated[Expr, Expr[A], Expr[List[A]]] = {
new BiRepeated[Expr, Expr[A], Expr[List[A]]] {
type Acc = Builder[Expr[A], List[Expr[A]]]
override def init():Acc = List.newBuilder[Expr[A]]
override def append(acc:Acc, elem:Expr[A]):Acc = {acc += elem}
override def result(acc:Acc):Expr[List[A]] = Expr.ofList(acc.result())

override def headTail:PartialExprFunction[Expr, Expr[List[A]], (Expr[A], Expr[List[A]])] = {
PartialExprFunction[Expr, Expr[List[A]], (Expr[A], Expr[List[A]])](
it => '{${it}.nonEmpty},
it => ('{${it}.head}, '{${it}.tail}),
)
}
override def isEmpty(it:Expr[List[A]]):Expr[Boolean] = {
'{${it}.isEmpty}
}
}
BiRepeated.apply[Expr, Expr[A], Builder[Expr[A], List[Expr[A]]], Expr[List[A]]](
() => List.newBuilder[Expr[A]],
(acc, elem) => {acc += elem},
(acc) => Expr.ofList(acc.result()),
PartialExprFunction[Expr, Expr[List[A]], (Expr[A], Expr[List[A]])](
it => '{${it}.nonEmpty},
it => ('{${it}.head}, '{${it}.tail}),
),
it => '{${it}.isEmpty},
)
}
}

Expand Down
117 changes: 60 additions & 57 deletions Base/src/main/scala/typeclass/Repeat.scala
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ trait BiRepeated[Expr[_], A, Z]

/** Predefined implicit implementations of Repeated */
object Repeated extends VersionSpecificRepeated with LowPrioRepeated {
private def apply[A, Acc, Z](
private[typeclass] def apply[A, Acc, Z](
initFn: () => Acc,
appendFn: (Acc, A) => Acc,
resultFn: Acc => Z,
Expand All @@ -104,39 +104,33 @@ object Repeated extends VersionSpecificRepeated with LowPrioRepeated {
* Repeated units results in a unit
*/
implicit def unit:Repeated[Unit, Unit] = {
final class RepeatedUnit extends Repeated[Unit, Unit] {
type Acc = Unit
def init():Acc = ()
def append(acc:Acc, elem:Unit):Unit = {}
def result(acc:Acc):Unit = ()
}
new RepeatedUnit()
Repeated.apply[Unit, Unit, Unit](
() => (),
(acc, _) => acc,
(acc) => acc,
)
}

/**
* Creates a String consisting of each of the input Char values in order
*/
implicit def charToString:Repeated[Char, String] = {
final class RepeatedChar extends Repeated[Char, String] {
type Acc = StringBuilder
def init():Acc = new StringBuilder
def append(acc:Acc, elem:Char):Acc = {acc += elem}
def result(acc:Acc):String = acc.toString
}
new RepeatedChar()
Repeated.apply[Char, StringBuilder, String](
() => new StringBuilder,
(acc, elem) => acc += elem,
(acc) => acc.toString,
)
}

/**
* Creates a String consisting of each of the input CodePoint values in order
*/
implicit def codepointToString:Repeated[CodePoint, String] = {
final class RepeatedCodepoint extends Repeated[CodePoint, String] {
type Acc = java.lang.StringBuilder
def init():Acc = new java.lang.StringBuilder
def append(acc:Acc, elem:CodePoint):Acc = {acc.appendCodePoint(elem.intValue)}
def result(acc:Acc):String = acc.toString
}
new RepeatedCodepoint()
Repeated.apply[CodePoint, java.lang.StringBuilder, String](
() => new java.lang.StringBuilder,
(acc, elem) => acc.appendCodePoint(elem.intValue),
(acc) => acc.toString,
)
}

/**
Expand All @@ -158,13 +152,11 @@ private[typeclass] trait LowPrioRepeated {
* creates a List containing each of the input values
*/
implicit def toList[A]:Repeated[A, List[A]] = {
final class RepeatedGenericToList extends Repeated[A, List[A]] {
type Acc = Builder[A, List[A]]
def init():Acc = List.newBuilder[A]
def append(acc:Acc, elem:A):Acc = {acc += elem}
def result(acc:Acc):List[A] = acc.result()
}
new RepeatedGenericToList()
Repeated.apply[A, Builder[A, List[A]], List[A]](
() => List.newBuilder[A],
(acc, elem) => acc += elem,
(acc) => acc.result()
)
}
}

Expand All @@ -179,39 +171,50 @@ private[typeclass] trait LowPrioContraRepeated extends VersionSpecificLowPrioCon

/** Predefined implicit implementations of BiRepeated */
object BiRepeated extends VersionSpecificBiRepeated with LowPrioBiRepeated {
implicit def idUnit:BiRepeated[Id, Unit, Unit] = {
new BiRepeated[Id, Unit, Unit] {
type Acc = Unit
def init():Acc = ()
def append(acc:Acc, elem:Unit):Unit = {}
def result(acc:Acc):Unit = ()

def headTail:PartialExprFunction[Id, Unit, (Unit, Unit)] = {
PartialExprFunction[Id, Unit, (Unit, Unit)](
_ => true,
value => (value, value)
)
}
def isEmpty(it:Unit):Id[Boolean] = true
private[typeclass] def apply[Expr[_], A, Acc, Z](
initFn: () => Acc,
appendFn: (Acc, A) => Acc,
resultFn: Acc => Z,
headtailFn: PartialExprFunction[Expr, Z, (A, Z)],
isEmptyFn: Z => Expr[Boolean],
): BiRepeated[Expr, A, Z] = {
type Acc2 = Acc
new BiRepeated[Expr, A, Z] {
type Acc = Acc2
def init():Acc = initFn()
def append(acc:Acc, elem:A):Acc = appendFn(acc, elem)
def result(acc:Acc):Z = resultFn(acc)

def headTail:PartialExprFunction[Expr, Z, (A, Z)] = headtailFn
def isEmpty(it:Z):Expr[Boolean] = isEmptyFn(it)
}
}

implicit def idUnit:BiRepeated[Id, Unit, Unit] = {
BiRepeated.apply[Id, Unit, Unit, Unit](
() => (),
(acc, _) => acc,
(acc) => acc,
PartialExprFunction[Id, Unit, (Unit, Unit)](
_ => true,
value => (value, value),
),
_ => true,
)
}
}

private[typeclass] trait LowPrioBiRepeated extends VersionSpecificLowPrioBiRepeated {
implicit def idToList[A]:BiRepeated[Id, A, List[A]] = {
new BiRepeated[Id, A, List[A]] {
type Acc = Builder[A, List[A]]
def init():Acc = List.newBuilder[A]
def append(acc:Acc, elem:A):Acc = {acc += elem}
def result(acc:Acc):List[A] = acc.result()

def headTail:PartialExprFunction[Id, List[A], (A, List[A])] = {
PartialExprFunction[Id, List[A], (A, List[A])](
it => it.nonEmpty,
it => ((it.head, it.tail))
)
}
def isEmpty(it:List[A]):Boolean = it.isEmpty
}
BiRepeated.apply[Id, A, Builder[A, List[A]], List[A]](
() => List.newBuilder[A],
(acc, elem) => {acc += elem},
(acc) => acc.result(),
PartialExprFunction[Id, List[A], (A, List[A])](
it => it.nonEmpty,
it => ((it.head, it.tail)),
),
it => it.isEmpty,
)
}
}

0 comments on commit ea891a1

Please sign in to comment.