2011-11-13 2 views
16

java.lang.Integerとjava.lang.Doubleの最小限の上限が非循環型として推測されるのはなぜですか?

val foo = if(true) 
      new java.lang.Double(4) 
      else 
      new java.lang.Integer(4) 

fooの推定型は次のとおりです。

Number with Comparable[_ >: Double with Integer <: Number with 
    Comparable[_ >: Double with Integer <: Number]] 

したがって、コンパイラは基本的に境界をループし、3回目の再帰後に中止します。

次のような理由で十分ではありませんか?

Number with Comparable[_ >: Double with Integer <: Number] 

答えて

8

ない答えが、REPLに暗黙的を使用していくつかの手がかり。コンパイラは型が同じだとは思わない。推論されたタイプは、より具体的である:

// some type aliases to make reading easier 
type Dx = java.lang.Double 
type Ix = java.lang.Integer 

// the type the compiler came up with: 
type Inferred = Number with Comparable[ 
    _ >: Dx with Ix <: Number with Comparable[_ >: Dx with Ix <: Number]] 

// your type: 
type Soc = Number with Comparable[_ >: Dx with Ix <: Number] 

私は右のタイプの別名をしたチェック:

val d = new java.lang.Double(4) 
val i = new java.lang.Integer(4) 
val foo: Soc = if (true) d else i 
// foo: Soc = 4.0 
val foo: Inferred = if (true) d else i 
// foo: Inferred = 4.0 

種類は同じではありません。

implicitly[Soc =:= Inferred] // error 

あなたのタイプはのスーパータイプであります推定タイプ:

implicitly[Inferred <:< Soc] // ok 
implicitly[Soc <:< Inferred] // error 

コンパイラによれば、より具体的な型が出てきました。これは正しいことです。ユースケースは、次のように再作成することができることに注意してください:

class N      // like java.lang.Number 

trait C[T]     // like Comparable 

class I extends N with C[I] // like java.lang.Integer 
class D extends N with C[D] // like java.lang.Double 

type DI = N with C[_ >: D with I <: N with C[_ >: D with I <: N]] 
// DI is like the type inferred 

type DI_SOC = N with C[_ >: D with I <: N] // your type 

val foo: DI = if (true) new D else new I  // ok 
val foo: DI_SOC = if (true) new D else new I // ok 

implicitly[DI =:= DI_SOC] // error 
implicitly[DI <:< DI_SOC] // DI_SOC super type of DI 
implicitly[DI_SOC <:< DI] // error 

をだから私たちはDIDI_SOCが同じタイプではない説明ですDI_SOCではなくDIあるクラスを、作ることができるかどうかだろうとあなたのタイプは最小の上限ではありません。

[OK]をクリックしてコンピュータを少しステップしてからもう一度やり直してください。

class A extends N with C[N] 
implicitly[A <:< DI_SOC] // ok 
implicitly[A <:< DI]  // error 

元のユースケースに適用される:

class Ax extends Number with Comparable[Number] { 
    def doubleValue() = 0d 
    def floatValue() = 0f 
    def intValue() = 0 
    def longValue() = 0L 
    def compareTo(n: Number) = 0 
} 

implicitly[Ax <:< Soc]  // ok 
implicitly[Ax <:< Inferred] // error 

したがって、タイプSocInferredない同じであり、Axが証明ここでDI_SOCなくDIあるクラスがありますそのNumber with Comparable[_ >: Double with Integer <: Number]ではなく、最小上限...

つまり、Double with Integer <: ? <: Numberの間に若干の余裕がありますが、それほど多くはありませんDouble with Integer <: ? <: Number with Comparable[_ >: Double with Integer <: Number]

関連する問題