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

埃里拉尔

我正在尝试为属于“可识别”特征子类型的某些类型创建通用特征“回购”。我的计划是通过传递描述“可识别”子类型的通用TypeTag [HList]实例化“ Repo”的实现者。

如何使编译器保证在HList中传递的类型是特征“可识别”的子类型?

到目前为止,这是我得到的:

    //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的内容的类型推断差异是我没有HList的实现可使用,因此不确定如何仅计算类型的上限。

加布里埃·彼得罗内拉(Gabriele Petronella)

HList上有一整套约束,由https://github.com/milessabin/shapeless/blob/master/core/src/main/scala/shapeless/hlistconstraints.scala提供

您所追求的可能是LUBConstraint引用文档:

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

要使用它,您只需要提供的隐式证据即可LUBContraint[L, Identifiable]

例如

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]

现在,在扩展类时,您将立即得到错误。

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

F#强制转换为在编译时未知的类型

来自分类Dev

如何在编译时强制执行非泛型类型

来自分类Dev

在编译时遍历函数参数类型

来自分类Dev

Haskell:在编译时引用值的类型

来自分类Dev

异构映射,在编译时依赖类型

来自分类Dev

C ++在编译时比较模板类型

来自分类Dev

在编译时获取std :: variant类型

来自分类Dev

在编译时如何未知对象类型?

来自分类Dev

在编译时强制执行静态存储

来自分类Dev

在编译时打印类型名称而不中断编译?

来自分类Dev

与强制执行可比较类型的集合相比,在编译时检查时抛出运行时异常有什么好处?

来自分类Dev

在编译时为类型生成唯一的ID

来自分类Dev

在编译时生成类型列表-没有C ++ 11

来自分类Dev

如果类型是多态的,如何在编译时检查

来自分类Dev

在编译时检查是模板类型还是向量

来自分类Dev

Delphi在编译时复制基类型未知的通用对象

来自分类Dev

在编译时在const结构类型之间进行转换

来自分类Dev

在编译时检测std :: tuple中的类型包含

来自分类Dev

在编译时获取Opencv Mat_ <T>的类型

来自分类Dev

如果类型是多态的,如何在编译时检查

来自分类Dev

序列化在编译时类型未知的对象

来自分类Dev

在编译时定义了不同类型的向量

来自分类Dev

模板函数在编译时返回类型没有参数

来自分类Dev

链式应用返回类型似乎是在编译时确定的

来自分类Dev

在编译时推导出未知类型的函数重载

来自分类Dev

常量和重新解释强制转换是否在编译时发生?

来自分类Dev

我可以强制我的PHP C扩展在编译时链接pthread吗?

来自分类Dev

是否可以在编译时将Foo强制转换为ubyte [size]?

来自分类Dev

如何强制Visual Studio在编译时检查损坏的文件引用

Related 相关文章

  1. 1

    F#强制转换为在编译时未知的类型

  2. 2

    如何在编译时强制执行非泛型类型

  3. 3

    在编译时遍历函数参数类型

  4. 4

    Haskell:在编译时引用值的类型

  5. 5

    异构映射,在编译时依赖类型

  6. 6

    C ++在编译时比较模板类型

  7. 7

    在编译时获取std :: variant类型

  8. 8

    在编译时如何未知对象类型?

  9. 9

    在编译时强制执行静态存储

  10. 10

    在编译时打印类型名称而不中断编译?

  11. 11

    与强制执行可比较类型的集合相比,在编译时检查时抛出运行时异常有什么好处?

  12. 12

    在编译时为类型生成唯一的ID

  13. 13

    在编译时生成类型列表-没有C ++ 11

  14. 14

    如果类型是多态的,如何在编译时检查

  15. 15

    在编译时检查是模板类型还是向量

  16. 16

    Delphi在编译时复制基类型未知的通用对象

  17. 17

    在编译时在const结构类型之间进行转换

  18. 18

    在编译时检测std :: tuple中的类型包含

  19. 19

    在编译时获取Opencv Mat_ <T>的类型

  20. 20

    如果类型是多态的,如何在编译时检查

  21. 21

    序列化在编译时类型未知的对象

  22. 22

    在编译时定义了不同类型的向量

  23. 23

    模板函数在编译时返回类型没有参数

  24. 24

    链式应用返回类型似乎是在编译时确定的

  25. 25

    在编译时推导出未知类型的函数重载

  26. 26

    常量和重新解释强制转换是否在编译时发生?

  27. 27

    我可以强制我的PHP C扩展在编译时链接pthread吗?

  28. 28

    是否可以在编译时将Foo强制转换为ubyte [size]?

  29. 29

    如何强制Visual Studio在编译时检查损坏的文件引用

热门标签

归档