scala - 为什么 deriveHCons 的签名在 Symbol 是最终类时声明 `HK <: Symbol`

标签 scala generics subclassing generic-programming shapeless

下面是Shapeless的LabelledProductTypeClassCompanionderiveHCons的签名:

implicit def deriveHCons[HK <: Symbol, HV, TKV <: HList]
    (implicit
      ch: Lazy[C[HV]],
      key: Witness.Aux[HK],
      ct: Lazy[Wrap[TKV] { type V <: HList }]
    ): Wrap.Aux[FieldType[HK, HV] :: TKV, HV :: ct.value.V] = ...

Symbol 是最终类时,我们声明一个必须从 Symbol 派生的类型参数 HK 对我来说似乎很奇怪。除了 Symbol 之外,如何才能替换类型参数 HK?如果 HK 始终是 Symbol,那么如果它去掉 HK 并直接在类型签名中替换 Symbol,这个签名会不会那么引人注目,不是吗?

最佳答案

我将解释为什么这适用于 Int , 但对于 Symbol 实际上是一样的.

Int final 对吗?这是它的一个实例:

val n = 2

但实际上我们可以给出n比那更精确的类型。如何?用literal singleton types :

val n: Witness.`2`.T = 2

现在n类型为 Witness.`2`.T ,又名 2.type ,或者只是输入 2 . 2是它的唯一居民,例如3: Witness.`2`.T不会编译。我们有Witness.`2`.T <: Int

同样的事情也适用于符号:虽然Symbol是最终的,它的值,特别是字面值,可以被赋予更细化的类型,这些类型对应于这些值:

val s = Symbol("s")
val refined: Witness.`'s`.T = Symbol("s")

关于scala - 为什么 deriveHCons 的签名在 Symbol 是最终类时声明 `HK <: Symbol`,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28421709/

相关文章:

scala - 如何将Java api KStream转换为Scala api KStream?

java - 钻石运营商;初始化参数化泛型类

java - 了解 Java 接口(interface)原理

c# - 决定需要哪个子类的最佳方法

scala - 安装凿子

scala - 重写 final方法

scala - 为什么 Option 的 orNull 方法有这个多余的隐式参数?

c - 关于 C 和泛型函数

java - Guice 注入(inject)通用列表

c++ - Windows CE下单行EDIT控件按ENTER键时如何关闭提示音?