Skip to content

Commit

Permalink
Use semigroup to combine results in SemigroupalK derivation (#521)
Browse files Browse the repository at this point in the history
  • Loading branch information
joroKr21 committed Apr 2, 2024
1 parent 39d1054 commit ea36c08
Show file tree
Hide file tree
Showing 6 changed files with 19 additions and 8 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ private class DeriveMacros[Q <: Quotes](using val q: Q):
val lambdaType = MethodType(x :: Nil)(_ => tpe :: Nil, _ => resultType)
val lambda = Lambda(method, lambdaType, (_, xs) => xf(tpe, xs.head.asExpr.asTerm))
val result = Select.overloaded(arg, "map", resultType :: Nil, lambda :: Nil)
val repeatedType = AppliedType(defn.RepeatedParamClass.typeRef, resultType :: Nil)
val repeatedType = defn.RepeatedParamClass.typeRef.appliedTo(resultType)
Typed(result, TypeTree.of(using repeatedType.asType))

def transformArg(method: Symbol, paramAndArg: (Definition, Tree)): Tree =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@

package cats.tagless.macros

import cats.Semigroup
import cats.tagless.*
import cats.data.Tuple2K

Expand Down Expand Up @@ -78,5 +79,9 @@ object MacroSemigroupalK:
.unique(tpe.firstK.summonLambda[SemigroupalK](f), "productK")
.appliedToTypes(List(F, G))
.appliedTo(argf, argg)
case (tpe, argf :: argg :: Nil) =>
Implicits.search(TypeRepr.of[Semigroup].appliedTo(tpe)) match
case success: ImplicitSearchSuccess => Select.unique(success.tree, "combine").appliedTo(argf, argg)
case _ => argf
}
)
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ class ApplyKSpec extends munit.FunSuite with Fixtures:
assertEquals(tryInstance.tuple, Try(instance.tuple))
}

test("DeriveMacro should not derive instance for a not simple algebra") {
test("DeriveMacro should derive instance for a not simple algebra") {
assert(typeCheckErrors("Derive.applyK[NotSimpleService]").isEmpty)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ trait Fixtures:
def paranthesless: F[Int]
def tuple: F[(Int, Long)]

def instance = new SimpleService[Id]:
object instance extends SimpleService[Id]:
def id(): Id[Int] = 42
def list(id: Int): Id[List[Int]] = List(id)
def lists(id1: Int, id2: Int): Id[List[Int]] = List(id1, id2)
Expand All @@ -42,12 +42,16 @@ trait Fixtures:
def id(): Int
def list(id: Int): F[List[Int]]

object instancens extends NotSimpleService[Id]:
def id(): Int = 42
def list(id: Int): Id[List[Int]] = List(1, 2, 3)

trait SimpleServiceC[F[_]] derives ContravariantK:
def id(id: F[Int]): Int
def ids(id1: F[Int], id2: F[Int]): Int
def foldSpecialized(init: String)(f: (Int, String) => Int): Cokleisli[F, String, Int]

def instancec = new SimpleServiceC[Id]:
object instancec extends SimpleServiceC[Id]:
def id(id: Id[Int]): Int = id
def ids(id1: Id[Int], id2: Id[Int]): Int = id1 + id2
def foldSpecialized(init: String)(f: (Int, String) => Int): Cokleisli[Id, String, Int] =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ class InvariantKSpec extends munit.FunSuite with Fixtures:
assertEquals(invariantInstance.tuple, optionalInstance.tuple)
}

test("DeriveMacro should not derive instance for a not simple algebra") {
test("DeriveMacro should derive instance for a not simple algebra") {
assert(typeCheckErrors("Derive.invariantK[NotSimpleService]").isEmpty)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@ import cats.Id
import cats.arrow.FunctionK
import cats.data.Tuple2K

import scala.compiletime.testing.*
import scala.annotation.experimental

@experimental
Expand All @@ -47,8 +46,11 @@ class SemigroupalKSpec extends munit.FunSuite with Fixtures:
assertEquals(combinedInstance.tuple, Tuple2K(instance.tuple, optionalInstance.tuple))
}

test("DeriveMacro should not derive instance for a not simple algebra") {
assert(typeCheckErrors("Derive.semigroupalK[NotSimpleService]").isEmpty)
test("DeriveMacro should derive instance for a not simple algebra") {
val semigroupalK = Derive.semigroupalK[NotSimpleService]
val combinedInstance = semigroupalK.productK(instancens, instancens)

assertEquals(combinedInstance.id(), 2 * instancens.id())
}

test("SemigroupalK derives syntax") {
Expand Down

0 comments on commit ea36c08

Please sign in to comment.