簡體   English   中英

對於泛型類型和它的類型參數的Scala類型推斷 - 為什么它不起作用?

[英]Scala type inference for both a generic type and it's type parameter - why doesn't it work?

如果我要說出關於scala的最令人煩惱的事情,那么對於以下代碼:

trait G[+T]
class H[+T] extends G[T]

def f[A<:G[X], X<:Int](g :A)

val g :H[Int]
f(g)

編譯器推斷最后一次調用f [H [Int],Nothing]的類型,並在我面前因為自己的愚蠢而抱怨。

然而,知道scala,它實際上比我更清楚。 它背后的原因是什么? 由於G和H對於T都是協變的,對於任何類型S, S <: G[X] with H[_] <=> S<: H[X] 。這一個缺點使我設計了一切,避免必須指定明確的類型 - 它可能在這里看起來沒什么,但是當名稱變成'真實'長度並且幾乎任何方法都是通用的,並且經常處理兩種泛型類型時,事實證明大多數代碼都是類型聲明。

編輯:上面的案例在下面由Noah解決,但是當派生類與基類不同時,如下所示?

trait G[+X]
class H[+X, Y] extends G[X]
class F extends G[Int]
def f[A<:G[X], X<:Int](g :A) = g

val h: H[Int, String] = ???
val g :F = ???
f(g)
f(h)

如果你讓A坐式paramater A[_]我認為你可以得到Scala編譯器同意你的觀點,而不是僅僅讓一切Nothing

def f[A[_] <: G[_], X <: Int](g: A[X]) 

作為旁注,我通常會在我遇到類型問題時查看scalaz源代碼,因為他們通常會遇到它並盡可能地解決它。

UPDATE

我上面提供的方法仍然適用於給出的附加約束:

  trait G[+X]

  class H[+X, Y] extends G[X]

  class F extends G[Int]

  class I extends G[String]

  def f[A[_] <: G[_], X <: Int](g: A[X]) = g

  val h: H[Int, String] = new H[Int, String]
  val g: F = new F
  val i:I = new I
  f(g) //works
  f(h) //works
  f(i) // should fail and does fail

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM