什么时候空HList不是HList?

时间:2016-12-07 06:36:22

标签: scala shapeless

在学习无形的同时,我想知道,为什么这不能编译:

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

因为HNil对象扩展了扩展HList的HNil特性?

在trait中定义一个方法的正确方法是什么,它返回一些HList,它只在扩展类中实现?

我想做以下事情:

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。)不希望在每个实现类中明确指定H,而是推断它(在调用站点?)。

2。)我想在父特征中使用HNil作为默认实现,可以选择在子类中重写。我的例子应该是:

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

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

2 个答案:

答案 0 :(得分:8)

HNil对象是HList。但没有必要H

定义如

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

应该被理解为

  

对于任何type HHList的子类型,有一种方法可以构建它的成员,它将是HNil

这显然是错误的

你正试图做的事情,正如我所认为的,是

的改写版本
  

type HHList的子类型以及构建其成员的方法

如果是这样,你可以使用这样的类型成员:

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的类型是HNil.type的{​​{1}}子类型,可以lead the compiler wrong way sometimes

答案 1 :(得分:4)

如果只使用HList作为返回类型,那么一切正常:

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
}