generics - Scala parameterized type problem with returning an instance of the same type -
in following, present reduced versions of scala code. enough show problem. unnecessary blocks of code reduced ...
.
the part works
i have created vector library (that is, modeling mathematical vectors, not vectors in sense of scala.collection.vector
). basic trait looks this:
trait vec[c] extends product { def -(o:vec[c]):vec[c] = ... ... }
i have created numerous subtypes specific vectors, vec2
two-dimensional vectors, or vec2int
specialized two-dimensional int
vectors.
the subtypes narrow return types of operations. example, subtracting vec2int
vector not return generic vec[int]
, more specific vec2int
.
additionally, have declared methods in specific subtypes vec2int
final
, thereby allowing compiler elect methods inlining.
this works well, , have created fast , usable library vector calculations.
building on top of that, want create set of types model basic geometrical shapes. basic shape trait looks this:
trait shape[c, v <: vec[c]] extends (v=>boolean) { def boundingbox:box[c,v] }
where box
subtype of shape
, modeling n-dimensional box.
the part not work
now, tried define box:
trait box[c, v <: vec[c]] extends shape[c,v] { def lowcorner:v def highcorner:v def boundingbox = def diagonal:v = highcorner - lowcorner // not compile }
the diagonal
method not compile, because method vec.-
returns vec[c]
, not v
.
of course, make diagonal
return vec[c]
, unacceptable in many ways. once, lose compiler optimization specific vec
subtypes. also, when example have box described 2 two-dimensional float
vectors (vec2float
), makes lot of sense assume diagonal vec2float
. not want lose information.
my attempt fix problem
following example of scala collection hierarchy, introduced type veclike
:
trait veclike[c, +this <: veclike[c,this] vec[c]] { def -(o:vec[c]):this ... }
and made vec
extend it:
trait vec[c] extends product veclike[c, vec[c]] ...
(i go on create more specific subtypes of veclike
, vec2like
or vec3like
, accompany hierarchy of vec
types.)
now, new definition shape
, box
looks this:
trait shape[c, v <: veclike[c,v] vec[c]] ... trait box[c, v <: veclike[c,v] vec[c]] extends shape[c,v] { ... def diagonal:v = highcorner - lowcorner }
still, compiler complains:
error: type mismatch; found: vec[c] required: v
this confuses me. type veclike
returns this
in minus method, translates type parameter v
of box
type. can see minus method of vec
still returns vec[c]
, why cannot compiler @ point use return type of veclike
's minus method?
how can fix problem?
my advice work less hard on omitting code think irrelevant, , show code. it's amazing how people manage remove part matters. mantra "if don't know why doesn't work, don't know relevant." serious, genuine advice: can in 5 seconds if give me code compile except thing don't understand, or can in 5 minutes if have reconstruct pieces left out. guess 1 happens more often.
on code. compiles given, after make guesses how bits first attempt fill second attempt. (this "guessing" phase reason show code front.)
trait veclike[c, +this <: veclike[c, this] vec[c]] { def -(o: vec[c]): } trait vec[c] extends product veclike[c, vec[c]] { } trait shape[c, v <: veclike[c,v] vec[c]] { } trait box[c, v <: veclike[c,v] vec[c]] extends shape[c, v] { def lowcorner: v def highcorner: v def boundingbox = def diagonal: v = highcorner - lowcorner } % scalac281 a.scala %
Comments
Post a Comment