2011-12-12 61 views
4

下面,所述第一壳体成功并且第二失败。为什么我需要明确的证据类型/为什么这个Scala类型绑定失败?在解决A问题时,类型推理器的特殊限制是什么?为什么我需要明确的证据类型/为什么这个Scala类型绑定失败?

scala> implicit def view[A, C](xs: C)(implicit ev: C <:< Iterable[A]) = new { def bar = 0 } 
view: [A, C](xs: C)(implicit ev: <:<[C,scala.collection.immutable.Iterable[A]])java.lang.Object{def bar: Int} 

scala> view(List(1)) bar 
res37: Int = 0 

scala> implicit def view[A, C <: Seq[A]](xs: C) = new { def bar = 0 } 
view: [A, C <: scala.collection.immutable.Seq[A]](xs: C)java.lang.Object{def bar: Int} 

scala> view(List(1)) bar 
<console>:149: error: inferred type arguments [Nothing,List[Int]] do not conform to method view's type parameter bounds [A,C <: scala.collection.immutable.Seq[A]] 
       view(List(1)) bar 
      ^

回答

9

类型推断遗憾的是不与由(包含类型),在同类型的参数列表(在这里,A),其他类型的参数限制类型参数(如C)处理好。

编码使用隐式自变量由于由implicits施加的约束是从由类型参数界限施加的约束分别解决不不受此限制遭受约束版本。

您也能避免受XS的类型分裂成抽象在集合(CC)类型构造周期和(适当的)类型(A)抽象了它的元素,像这样:

scala> implicit def view[A, CC[x] <: Seq[x]](xs: CC[A]) = new { def bar = 0 } 
view: [A, CC[x] <: Seq[x]](xs: CC[A])Object{def bar: Int} 

scala> view(List(1)) bar 
res0: Int = 0 

有关类型,如CC的详细信息,请参阅What is a higher kinded type in Scala?

+0

谢谢,但我其实知道'C [A] <:序号[A]'工作 - 它只是限制了我一元型构造。我*想*一个'C <:Seq [A]'。无论如何,你说的推理不符合类型参数引用对方处理好回答我的问题,所以我将其标记为接受,但会爱更多详情! – Yang

1

我真的不知道为什么会这样,但我的预感是它与Seq的类型参数的变化有关。我能得到下面的工作,虽然:

implicit def view[A, C[~] <: Seq[~] forSome { type ~ }](xs: C[A]) = 
    new { def bar = 0 } 

是否有一个原因,你想C —我的意思是,你打算使用C方法里面?因为如果没有,为什么不只是

implicit def view[A](xs: Seq[A]) = new { def bar = 0 } 

+0

是的,不然我也不会需要'xs'可言。这是一个需要知道'A'和'C'的皮条客。至于更高端的解决方案,请参阅我的其他评论。 – Yang

相关问题