I am looking for recommendations of providing a class manifest in an array instantiation. I have refactored this code (which compiles fine):
trait Ref[A]
trait Struct[A] {
val arr = new Array[Ref[A]](1)
}
to this:
trait Ref[S <: Sys[S], A]
trait Sys[Self <: Sys[Self]] {
type R[A] <: Ref[Self, A]
}
trait Struct[S <: Sys[S], A] {
val arr = new Array[S#R[A]](1)
}
This fails with message "cannot find class manifest for element type S#R[A]"
So how would I solve this?
Your problem is that
Array
being invariant in its type parameter, requires a precise type argument. Your definition oftype R
inSys
is only providing an upper bound.You can fix the problem at the definition site by replacing the upper bound on
R
with an equality,Alternatively, if you'd prefer to leave
R[A]
open inSys
you can specify the equality constraint at the use site via a refinement, like so,If you can't pin down
type R
in either of these ways, then you have no option but to provide the ClassManifest explicitly yourself,Which of these to pick depends very much on your larger context.