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

Popular posts from this blog

Javascript line number mapping -

c# - Is it possible to remove an existing registration from Autofac container builder? -

php - Mysql PK and FK char(36) vs int(10) -