2017-08-03 22 views
0

我试图定义一个类型安全的异构列表,它对元素的类型有所限制,强制元素之间的层次结构(例如类型A不能出现在类型B之后)。尝试将我的结构转换为无定形的'HList时会发生问题。协变类型出现在不变位置在HList

下面是如何定义的特点为我喜欢的类型:

sealed trait Hierarchy { 
    type HListType <: HList 
    def toHList : HListType 

    def toCaseClass[C](implicit gen: Generic[C]{type Repr >: HListType}) = gen.from(toHList) 
} 

sealed trait <::[+H <: ElType[_], +T <: Hierarchy] extends Hierarchy { 

    override type HListType = H :: tail.HListType 

    val head: H 
    val tail: T 

    override def toHList: HListType = head :: tail.toHList 

} 

我收到以下错误:

Hierarchy.scala:26: covariant type H occurs in invariant position in type shapeless.::[H,<::.this.tail.HListType] of type HListType 

这是颇令人费解,因为shapeless.::定义定义了两种类型的参数是协变的。

我使用的是scala 2.11.11和2.3.2。有没有办法解决这个错误?

回答

0

从斯卡拉规格:

The right-hand side of a type alias is always in invariant position.

所以问题不是来自HList的定义,而是从事实,我用了一个类型别名类型参数。

我改变了定义

sealed trait <::[+H, +T <: Hierarchy] extends Hierarchy { 

    type H_ <: ElType[H] 

    override type HListType = H_ :: tail.HListType 

    val head: H_ 
    val tail: T 

    override def toHList: HListType = head :: tail.toHList 

} 

而且问题会消失。