1

我正在尝试定义一个类型安全的异构列表,它对其元素的类型有限制,在元素之间强制执行层次结构(例如,类型 A 不能出现在类型 B 之后)。尝试将我的结构转换为无形的 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 和 shapeless 2.3.2。有没有办法解决这个错误?

4

1 回答 1

1

来自 Scala 规范:

类型别名的右侧始终处于不变位置。

所以问题不在于 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

}

问题消失了。

于 2017-08-07T12:34:39.427 回答