簡體   English   中英

斯卡拉高型存在型

[英]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) ,因為編譯器會嘗試查找ApplesBanana的最小上限(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.

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