I am trying to define typeclass instances for an inner class.
As a minimal example, I have code that looks like this:
trait Typeclass[T]
class Outer:
class Inner
I would like to define an instance of Typeclass for Inner, so that this compiles:
object Main:
import Instances.given
val outer = new Outer
val x = summon[Typeclass[outer.Inner]]
It should be possible for the instance to depend on the value of Outer.
I would prefer the instance to reside in a different file (possibly a different package) from both Typeclass and Outer. In this case, defining a given instance inside Outer is not an option.
Is it possible to achieve this in Scala 3?
Below I will outline what I have tried:
Attempt 1: Parameterisation on Outer
object Instances:
given instance(using outer: Outer): Typeclass[outer.Inner] =
new Typeclass { }
This kind of works, but unfortunately the using clause requires that the value of Outer be marked as given.
Attempt 2: Type projection
object Instances:
given instance: Typeclass[Outer#Inner] =
new Typeclass { }
This doesn't work at all. The compiler refuses to use instance. Also, even if it did work, it wouldn't allow instance to depend on the value of Outer.
Attempt 3: Extension method
object Instances:
extension (outer: Outer)
given instance: Typeclass[outer.Inner] =
new Typeclass { }
It seems extension givens aren't even syntactically valid in Scala 3. (I suspect for good reason!)