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.