提取器:推断类型参数X不符合方法unapply的类型参数边界

时间:2013-02-03 12:28:03

标签: scala pattern-matching type-bounds

在下面的示例中,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 _ => ???
}

我想这是“讨厌斯卡拉日”之一。这真是太愚蠢了吗?基本上它与this question相同,但没有正确答案。

感谢。

1 个答案:

答案 0 :(得分:-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"