Reputation: 21
I am trying to define a type safe heterogeneous list which has restrictions on the types of its elements, enforcing an hierarchy between the elements (e.g type A cannot appear after type B). The trouble happens when attempting to convert my structure to shapeless' HList.
Below is how I define the traits for my type:
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
}
I get the following error:
Hierarchy.scala:26: covariant type H occurs in invariant position in type shapeless.::[H,<::.this.tail.HListType] of type HListType
This is quite puzzling, since the definition of shapeless.::
defines that both type parameters are covariant.
I am using scala 2.11.11 and shapeless 2.3.2. Is there a way to fix this error?
Upvotes: 1
Views: 349
Reputation: 21
From the Scala spec:
The right-hand side of a type alias is always in invariant position.
So the problem is not from the definition of HList, but from the fact that I'm using the type parameter in a type alias.
I changed the definition to
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
}
And the problem disappears.
Upvotes: 1