2016-10-17 45 views
3

給定一類與covariant類型的參數列表:LUB不變類的實例

scala> class G[+A] 
defined class G 

下面的列表顯示了一個最小上限的List[G[Any]]

scala> List(new G[Int], new G[String]) 
res1: List[G[Any]] = List([email protected], [email protected]) 

然後,給定與invariant類型參數的類:

scala> class F[A] 
defined class F 

我看到的List[F[_ >: String with Int]]一個最小上限(LUB)。

scala> List(new F[Int], new F[String]) 
res0: List[F[_ >: String with Int]] = List([email protected], [email protected]) 

一個簡單的例子說明了一個List[Any] LUB:

scala> List((42 : Int), "foobar") 
res2: List[Any] = List(42, foobar) 

請解釋的FList的LUB。

回答

2

Gcovariant在其類型參數A上。這意味着,給定的任何類型的AB,如果A子類型的G,然後G[A]子類型的G[B]。我們簡單地用A <:< B來表示A的子類型B,然後是G[A] <:< G[B]

這意味着,當我們有一個List(new G[Int], new G[String]),編譯器允許推斷它作爲一個List[Any],因爲List[G[Int]] <:< List[G[Any]]List[G[String]] <:< List[G[Any]](因爲List也協變在其類型參數)。

您可能已經知道,但值得爲那些尚未解決的問題做出解釋。

F不變的在其類型參數A,所以我們不能作出相同的推論。好的,那麼List(new F[Int], new F[String])的類型是什麼?因爲F不變的,所以我們不能說F[Int] <:< F[Any]F[String] <:< F[Any](因爲它不是真的!)。所以它不是List[F[Any]].

那麼編譯器可以推斷出什麼?它只是一種存在型的真正選擇,因爲它不可能是AnyString with Int,或其他任何沒有打破協方差的東西。由於它正在尋找最小上限,因此它推斷出一個存在類型,該類型由所包含類型的化合物(在F中)定界。也就是,_ >: String with Int一些無名類型,它有一個下界String with Int

或者,換句話說,我們知道我們有FList一個S,但我們不知道什麼類型包含在他們每個人。只有List中的任何給定的FF[Int]F[String],但就是這樣。