Scala type members variance

依然范特西╮ 提交于 2019-12-12 08:33:46

问题


Consider this short snippet:

trait Table[+A] {
  type RowType = Seq[A]
}

Scala 2.11.7 compiler gives the following error:

covariant type A occurs in invariant position in type Seq[A] of type RowType

Why is A considered to be in invariant position in Seq[A] while Seq itself is defined as trait Seq[+A]?

Also, could you please provide a use case demonstrating possible issues with this type definition if we ignore the error?


回答1:


For any B <: A your Table[B]#RowType will be more concrete than Table[A]#RowType. More concrete does not mean the same, so compiler is considering parameters for type aliases as invariant positions.

How you could fix this.

Abstract member

You can define your type as abstract, that mean you should define it later and probably stuck with same problem, but on trait Table level such definition will be correct

trait Table[+A] {
  type RowType <: Seq[A]
}

Concrete higher-kinded type

You can define parameterized type member, which could lead to changing how you can use this type, but in most cases should do the job.

trait Table[+A] {
  type RowType[+X] = Seq[X]
}

On type member variance

Not the strongest my field but i try to describe my thoughts.

Suppose you have

trait Table[+A] {
  type RowType = Seq[A]
}

def mkTable[A]: Table[A]  = new Table[A] {}

then you do following

val tupleTable = mkTable[(String, String)]
val prodTable: Table[Product] = tupleTable 

So what would be prodTable.RowType?

In case of your definition it should be Seq[Product]. But wait, prodTable and tupleTable are the same object, so their members should be the same, so prodTable.RowType should be Seq[(String, String)]

But if you change to the first approach like

trait Table[+A] {
  type RowType <: Seq[A]
}

def mkTable[A]: Table[A]  = new Table[A] {
  type RowType = Seq[A]
}

Compiler would know that RowType for Table[Product] is some type <: Seq[Product] which is true for Seq[(String, String)] and all ambiguilties are gone.



来源:https://stackoverflow.com/questions/33458782/scala-type-members-variance

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!