[英]Scala higher-kinded existential type
我具有以下層次結構,我想定義任何Description
的列表,但無法確定其參數類型。
abstract class Context
class Local extends Context
class Browsing extends Context
abstract class Fruit[C <: Context]
class Apple[C <: Context](id: Int) extends Fruit[C]
class Banana[C <: Context](id: Int) extends Fruit[C]
abstract class Description[U[X <: Context] <: Fruit[X]] // U can't be covariant
class Apples extends Description[Apple]
class Bananas extends Description[Banana]
基本上,我想要這樣的東西(它不能按原樣編譯):
val l: List[Description[_]] = List(
new Apples,
new Bananas
)
有什么辦法可以做到這一點?
您需要做的是:
abstract class Description[+U[X <: Context] <: Fruit[X]]
然后它將起作用:
scala> List(new Apples, new Bananas)
res40: List[Description[Fruit]] = List(Apples@6a808ae5, Bananas@4f4d77e8)
您的案例失敗的原因是:當您執行List(new Apples, new Bananas)
,因為編譯器會嘗試查找Apples
和Banana
的最小上限(LUB)。 即LUB用於Description[Apple]
和Description[Banana]
。 因此,您需要的是Description[_ >: Banana with Apple <: Fruit]
。
正如編譯器錯誤正確地指出的那樣: Apple <: Fruit
(當然還有Apple>:Banana with Apple)。 但是,如果Description
在其type參數中是協變的,則Description[Apple]
將僅是Description[_ >: Banana with Apple <: Fruit]
的子類型。
PS:協方差使我們具有以下能力:如果A <: B
,然后對於M[+T]
,則M[A] <: M[B]
。
對於逆方差M[-T]
, M[A] >: M[B]
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.