2011-01-23 19 views
0

これはthis questionのフォローアップです。scala self-type:valueはメンバエラーではありません

Iは、自己のタイプを使用して、一般的なスーパークラスとScalaの中のベクトルを実装しようとしています:

trait Vec[V] { self:V => 
    def /(d:Double):Vec[V] 
    def dot(v:V):Double 

    def norm:Double = math.sqrt(this dot this) 
    def normalize = self/norm 
} 

はここ3次元ベクトルの実装です:

class Vec3(val x:Double, val y:Double, val z:Double) extends Vec[Vec3] 
{ 
    def /(d:Double) = new Vec3(x/d, y/d, z/d) 
    def dot(v:Vec3) = x * v.x + y * v.y + z * v.z 
    def cross(v:Vec3):Vec3 = 
    { 
     val (a, b, c) = (v.x, v.y, v.z) 
     new Vec3(c * y - b * z, a * z - c * x, b * x - a * y) 
    } 

    def perpTo(v:Vec3) = (this.normalize).cross(v.normalize) 
} 

残念ながら、これにはありませんコンパイル:

Vec3.scala:10: error: value cross is not a member of Vec[Vec3] 
    def perpTo(v:Vec3) = (this.normalize).cross(v.normalize) 
             ^

どうしたらいいですか?どうすれば修正できますか?

さらに、自己のタイプに関する参考文献は、これらのエラーが私の理解の欠如から切り取っていると思うので、高く評価されます。

答えて

8

メソッドのクロス(Vまたは他の言葉で)Vec3に存在する

trait Vec[V] { self:V => 
    def /(d:Double): V 
    def dot(v:V):Double 

    def norm:Double = math.sqrt(this dot this) 
    def normalize = self/norm 
} 
ではなく、を取り除くためにすべての不気味さの中で、型パラメータ VVecのサブクラスであることを指定する必要があります。 Vはすべてがすべて Vec[V]のメソッドを継承していることがわかっているので、どこでも Vを使用できます。

trait Vec[V <: Vec[V]] { self: V => 
    def -(v:V): V 
    def /(d:Double): V 
    def dot(v:V): Double 

    def norm:Double = math.sqrt(this dot this) 
    def normalize: V = self/norm 
    def dist(v: V) = (self - v).norm 
    def nasty(v: V) = (self/norm).norm 
} 

Easy Angel’s approachとコンパイルされません方法nasty

+0

ありがとうございます。私はこれが私の元の質問に対する適切な答えだと信じています:http://stackoverflow.com/questions/4773611/proper-class-hierarchy-for-2d-and-3d-vectors。私はあなたにポイントを与えることができるので、そこに投稿してもらえますか? – dsg

3

私が思うに、その方法Vec/Vec[V]の代わりにVを返す必要があります:Vec[V]

+0

「Vec [V]」と「V」を使用する際の経験則は何ですか?参照された質問(http://stackoverflow.com/questions/4774743/scala-self-type-member-of-type-parameter-error)への答えは正反対で、戻り値の型 'V'を' Vec [ V]となる。 – dsg

+1

この問題はsef-typesとは関係がないと思います。 'normalize'は' Vec [V] 'を返し、' cross'メソッドはそこに定義されていませんが、以前の問題では '(this -v)'は 'V'を返し、このコンテキストでは' V'は'Vec [V]'はコンパイラによって宣言されています(コメントで言及されているように)。 – tenshi

関連する問題