Type class derivation for generic classes

Hi! I’m trying to write a derivation for my type class. But I have a problem with derives TC definition for generic classes. I do not understand, why the type parameter is passed instead of the class’s type.

trait TC[T]

object TC {
  def derived[T]: TC[T] = ???
}

class Y derives TC
class X[A] derives TC

def test(): Unit = {
  summon[TC[Y]]
  summon[TC[X[Int]]]
  // No given instance of type TC[X[Int]] was found for parameter x of method summon in object Predef.
  // I found:
  //
  // X.derived$TC[Int](/* missing */summon[TC[Int]])
  //
  // But no implicit values were found that match type TC[Int].
}

What’s the reason of such a behaviour?

Do I have to write

given [A]: TC[X[A]] = TC.derived

for generic classes?

1 Like

Do I have to write

given [A]: TC[X[A]] = TC.derived

for generic classes?

Probably, yes. (In this case, if that derived would work when written by hand).

By convention (coming from experience), when you need to derive TC[F[A]], F[_] is somehow using A inside, and need TC[A] to handle it when constructing TC[F[A]].

So, class X[A] derives TC generates:

given [A](using TC[A]): TC[X[A]] = TC.derived

It requires given TC[A] to construct TC[X[A]] - in case of TC[X[Int]] it’s TC[Int] as indicated by the error.

If your type class derivation is somehow special: it does NOT require such an instance, or requires multiple instances for inner values (that can only be resolved when A becomes known), or a different type class is required (e.g. on Scala 2 I once needed Typeable[A] next to TC[A], so Scalaz deriving annotation was not working with that type) - then you cannot use derives and you have to write that given manually.