2011-12-12 60 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

相關問題