Scala parameterized type problem returning instance of same type

In the future, I will show only very small versions of my Scala code. This is enough to show the problem. Unnecessary code blocks will be reduced to ....

The part that works

I created a vector library (i.e. for modeling mathematical vectors, not vectors in the sense scala.collection.Vector). The main feature is as follows:

trait Vec[C] extends Product {
  def -(o:Vec[C]):Vec[C] = ...
  ...
}

I have created many subtypes for specific vectors, such as Vec2for two-dimensional vectors, or Vec2Intspecialized for two-dimensional vectors Int.

Subtypes narrow the return types of some operations. For example, subtracting a Vec2Intfrom another vector will not return a general Vec[Int], but more specific one Vec2Int.

, , Vec2Int final, inline.

, .

, . :

trait Shape[C, V <: Vec[C]] extends (V=>Boolean) {
  def boundingBox:Box[C,V]
}

Box Shape, n- .

,

:

trait Box[C, V <: Vec[C]] extends Shape[C,V] {
  def lowCorner:V
  def highCorner:V
  def boundingBox = this
  def diagonal:V = highCorner - lowCorner // does not compile
}

diagonal , Vec.- Vec[C], V.

, diagonal return a Vec[C], . Vec. , , , , Float (Vec2Float), , Vec2Float. .

Scala, VecLike:

trait VecLike[C, +This <: VecLike[C,This] with Vec[C]] {
  def -(o:Vec[C]):This
  ...
}

Vec :

trait Vec[C] extends Product with VecLike[C, Vec[C]] ...

( VecLike, Vec2Like Vec3Like, Vec.)

Shape Box :

trait Shape[C, V <: VecLike[C,V] with Vec[C]] ...

trait Box[C, V <: VecLike[C,V] with Vec[C]] extends Shape[C,V] {
  ...
  def diagonal:V = highCorner - lowCorner 
}

, :

Error: type mismatch;
found: Vec[C]
required: V

. VecLike This , V Box. , Vec - Vec[C], VecLike ?

?

+5
1

, , , , , , . , , . " , , , ". , : , , , , , , , . , .

. , , , , . ( "" - , .)

trait VecLike[C, +This <: VecLike[C, This] with Vec[C]] {
  def -(o: Vec[C]): This
}

trait Vec[C] extends Product with VecLike[C, Vec[C]] { }

trait Shape[C, V <: VecLike[C,V] with Vec[C]] { }

trait Box[C, V <: VecLike[C,V] with Vec[C]] extends Shape[C, V] {
  def lowCorner: V
  def highCorner: V
  def boundingBox = this
  def diagonal: V = highCorner - lowCorner 
}

% scalac281 a.scala 
%
+6

All Articles