Here is the minimal reproduction of my problem:
trait Superclass[T]
class A(val key: Any) extends Superclass[key.type]
val x: Superclass["123"] = A("123")
As you can see, I'm trying to encode the statically known type of Key into the type parameter.
It's not like I can put the type of key
as a type parameter of A, since in my real example, it's more like class A(using g: blablah)(val key: g.Key) extends SuperClass[g.Mapping[key.type]]
but that's not relevant for the problem above.
Is it just that we can't use dependent types inside the arguments of the super class?
Update
The encoding with type members yields the same error:
trait Superclass {
type T
}
class A(val key: Any) extends Superclass {
type T = key.type
}
val x: Superclass & {type T = "123"} = A("123")
I still get
[error] 14 | val x: Superclass & {type T = "123"} = A("123")
[error] | ^^^^^^^^
[error] | Found: Main.A
[error] | Required: Main.Superclass & Object{T = ("123" : String)}
I could not work around your given example, but this may work for your actual use case.
And you can use it like this:
In
Foo
,Key
is used to bound what keys can be given toMapping
. TheK
parameter on classA
iskey
's type's upper bound, whileKT
is the actual type of the key.M
representsMapping
. I used a type refinement because type projections are unsound and have been dropped in Scala 3.For convenience, you can add an
apply
method toA
's companion and makeA
's own constructor private.See it run in Scastie.
As for dependent types in constructors, see this issue. It looks like you can't use them the same way you can in methods.