繁体   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