Scala 在编译时强制HList类型的上限

Scala 在编译时强制HList类型的上限,scala,shapeless,Scala,Shapeless,我试图为某些类型创建一个通用特征“Repo”,这些类型是特征“可识别”的子类型。我的计划是通过传递一个描述“可识别”子类型的通用类型标签[HList]来实例化“Repo”的实现者 我如何让编译器保证在HList中传递的类型是trait“identificated”的子类型? 以下是到目前为止我得到的信息: //All types in HList must extend Identifiable, how to enforce that at compile time? trai

我试图为某些类型创建一个通用特征“Repo”,这些类型是特征“可识别”的子类型。我的计划是通过传递一个描述“可识别”子类型的通用类型标签[HList]来实例化“Repo”的实现者

我如何让编译器保证在HList中传递的类型是trait“identificated”的子类型?

以下是到目前为止我得到的信息:

    //All types in HList must extend Identifiable, how to enforce that at compile time?
    trait Repo {
      implicit val ltag: TypeTag[L] forSome {type L <: HList}
      ..
    }

    trait Identifiable {
      ..
    }

    case class Person(..) extends Identifiable
    case class Address(..)

    //This should compile
    class MyRepo 
      (implicit val ltag: TypeTag[Person :: HNil])
      extends Repo {
      ..  
    }

    //This should not
    class MyRepo 
      (implicit val ltag: TypeTag[Address :: HNil])
      extends Repo {
      ..  
    }
//HList can contain an unknown number of types
//HList中的所有类型都必须扩展可识别的,如何在编译时强制执行?
特质回购{

隐式val-ltag:TypeTag[L]对于某些{typel在HList上有一整套由提供的约束

您要找的可能是
lubstraint
。引用文档:

类型类,证明
L
的每个元素都是
B
的子类型

要使用,您只需要要求提供
lubcontaint[L,可识别]
的隐式证据

例如


trait Repo[L将此证据从实现者传递给trait的语法是什么?我无法将类型参数传递给trait,因此我很难理解它。@eirirlar请参见上面的示例
trait Repo[L <: HList] {
  implicit val ltag: TypeTag[L]
  implicit val ev: LUBConstraint[L, Identifiable]
}

trait Identifiable
case class Person(name: String) extends Identifiable
case class Address(street: String)

type P = Person :: HNil
class MyPersonRepo(implicit
  val ltag: TypeTag[P],
  val ev: LUBConstraint[P, Identifiable]
) extends Repo[P]


type A = Address :: HNil
class MyAddressRepo(implicit
  val ltag: TypeTag[A],
  val ev: LUBConstraint[A, Identifiable]
) extends Repo[A]

new MyPersonRepo // this works
new MyAddressRepo // this doesn't
abstract class Repo[L <: HList](implicit
  val ltag: TypeTag[L],
  val ev: LUBConstraint[L, Identifiable]
)

trait Identifiable
case class Person(name: String) extends Identifiable
case class Address(street: String)

type P = Person :: HNil
class MyPersonRepo extends Repo[P]

type A = Address :: HNil
class MyAddressRepo extends Repo[A]