2017-07-04 16 views
1

抽象型メンバを型パラメータよりも受け入れ始めています。主に、型推論でうまく動作するように見えるからです。しかし、私はまだ彼らはで定義されているタイプの外からそれらを使用する方法を理解するのに苦労しています次のScalaプログラムをコンパイルはならない理由例えば、私が理解することはできません:。Scala:抽象型メンバーが型パラメータと等しい=> =等しくないのはなぜですか?

trait Thing 

trait Describer { 
    type X<:Thing 
    def describe(x:X) = println(x) 
} 

object Program extends App { 

    def print[T <: Thing, D <: Describer] 
    (describer: D, thing:T) 
    (implicit ev: D#X =:= T) 
    = describer.describe(thing) 

} 

を直感的に、私がいることを期待します要件D#X =:= Tは、2つのタイプが実際に等しいので、2のインスタンスは、交換可能に使用することができることであることを保証するだろうが、私は、このコンパイルエラーを取得:私は何を

error: type mismatch; 
found : thing.type (with underlying type T) 
required: describer.X 
    = describer.describe(thing) 

を誤解しているの?私がやりたいことをする別の方法がありますか?または、それが失敗した場合は、thingを必要なタイプ(describer.X)にキャストすることは安全ですか?

答えて

5

describer.describeのパラメータのタイプは、実際にはdescriber.Xであり、D#Xではありません。あなたが知っておかなければならないもう一つのことは、AからBへの変換としても機能しますが、(少なくとも現在では)逆の変換ではないということです。だから次のように動作するはずです。

def print[T <: Thing] 
    (describer: Describer, thing: T) 
    (implicit ev: T =:= describer.X) 
    = describer.describe(thing) 
+0

ありがとうございます。私は自分でそれを考え出したことはありませんでした。 – holbech

関連する問題