ตัวแยก: อาร์กิวเมนต์ประเภทอนุมาน X ไม่สอดคล้องกับขอบเขตพารามิเตอร์ประเภทของวิธีการยกเลิกการใช้

ในตัวอย่างต่อไปนี้ Scala ไม่สามารถใช้ตัวแยกข้อมูลได้ และมันทำให้ฉันคลั่งไคล้:

trait Sys[S <: Sys[S]]

object Element {
  object Foo {
    def unapply[S <: Sys[S]](foo: Foo[S]): Option[Any] = ???
  }
  trait Foo[S <: Sys[S]] extends Element[S]
}
trait Element[S <: Sys[S]]

นี่คือกรณีทดสอบ:

def test[S <: Sys[S]](elem: Element[S]) = elem match {
  case Element.Foo(_) => ???
  case _ => ???
}

ล้มเหลวด้วย

inferred type arguments [S] do not conform to method unapply's type parameter
  bounds [S <: Sys[S]]

(ทั้งใน Scala 2.9.2 และ 2.10)


ถ้าฉันลบ F-bound ออก มันก็ใช้งานได้:

trait Sys

object Element {
  object Foo {
    def unapply[S <: Sys](foo: Foo[S]): Option[Any] = ???
  }
  trait Foo[S <: Sys] extends Element[S]
}
trait Element[S <: Sys]

def test[S <: Sys](elem: Element[S]) = elem match {
  case Element.Foo(_) => ???
  case _ => ???
}

ฉันเดาว่านี่เป็นหนึ่งใน "วันแห่งความเกลียดชังสกาลา" นี่มันโง่ขนาดนี้เลยเหรอ? โดยพื้นฐานแล้วจะเหมือนกับ คำถามนี้ ซึ่งไม่มีคำตอบที่ถูกต้อง

ขอบคุณ.


person 0__    schedule 03.02.2013    source แหล่งที่มา


คำตอบ (1)


เมื่อพยายามเรียก test ด้วยอาร์กิวเมนต์ null และพารามิเตอร์ประเภท Sys[Any] มันจะบอกว่า:

type arguments [Sys[Any]] do not conform to trait Element's type parameter 
  bounds [S <: Sys[S]]

กำลังพยายามความแปรปรวน:

trait Sys[-S]

object Element {
  object Foo {
    def unapply[S <: Sys[S]](foo: Foo[S]): Option[Any] = ???
  }
  trait Foo[S <: Sys[S]] extends Element[S]
}
trait Element[S <: Sys[S]]

def test[S <: Sys[S]](elem: Element[S]) = elem match {
  case f: Element.Foo[S] => "ok"
  case _ => "smth else"
}

// test
test(new Element.Foo[Sys[Any]](){})  // "smth else"
test(new Element[Sys[Any]](){})      // "ok"
person idonnie    schedule 03.02.2013