什么时候空的 HList 不是 HList?

When is an empty HList not an HList?

在学习 shapeless 的时候,我想知道为什么这不能编译:

def someHList[H <: HList]: H = HNil

既然 HNil 对象扩展了扩展 HList 的 HNil 特性?

在特征中定义方法的正确方法是什么 returns 某些 HList,仅通过扩展 class 实现?

我想做如下事情:

trait Parent {
  def someHList[H <: HList]: H
}

object Child1 extends Parent {
  def someHList[H <: HList] = HNil
}

object Child2 extends Parent {
  def someHList[H <: HList] = 1 :: "two" :: HNil
}

如有任何建议,我们将不胜感激。谢谢!

编辑

当我意识到我在最初的问题中未指定的内容时进行详细说明:

1.) 最好不必在每个实现 class 中明确指定 H,而是让它被推断(在调用站点?)。

2.) 我想使用 HNil 作为父特征中的默认实现,可以选择在 subclasses 中覆盖它。我的示例可能应该是:

trait Parent {
  def someHList[H <: HList]: H = HNil
}

object Child extends Parent {
  override def someHList[H <: HList] = 1 :: "two" :: HNill
}

HNil 对象是一个 HList。不过没必要H.

定义类似于

def someHList[H <: HList]: H = HNil

应该读作

for any type H, subtype of HList there is a way to construct it's member and it will be HNil

这显然是错误的

据我所知,您正在尝试做的事情是改写版本

there is a type H, subtype of HList and a way to construct it's member

如果是这样,您可以像这样使用类型成员:

import shapeless._

trait Parent {
  type H <: HList
  def someHList: H
}

object Child1 extends Parent {
  type H = HNil
  def someHList: H = HNil
}

object Child2 extends Parent {
  type H = Int :: String :: HNil
  def someHList: H = 1 :: "two" :: HNil
}

更新

你也可以稍微重构一下,让一些类型自动推断,比如

abstract class Parent[H <: HList](val someList: H)
object Child1 extends Parent(HNil: HNil)
object Child2 extends Parent(1 :: "two" :: HNil)

您可能会注意到 HNil 的类型是手动设置的,那是因为 object HNil 的类型是 HNilHNil.type 子类型,它可以

如果只是将 HList 用作 return 类型,则一切正常:

trait Parent {
  def someHList: HList
}

object Child1 extends Parent {
  def someHList = HNil
}

object Child2 extends Parent {
  def someHList = 1 :: "two" :: HNil
}

或问题的更新版本:

trait Parent {
  def someHList: HList = HNil
}

object Child2 extends Parent {
  override def someHList = 1 :: "two" :: HNil
}