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.