无形 HList 参数覆盖

Shapeless HList parameter override

我有一个抽象 class,它有一个接收 HList 作为参数的方法 (A)。 但是在 subclasses 中我想限制这个 HList 的确切类型 (B)

下面的代码不起作用(它没有将(Int :: String :: HNil)视为[=12=的子class]。但是如何实现类似的效果?

import shapeless.{::, HList, HNil}
import shapeless.syntax.std.tuple._

abstract class A{
  def test[H <: HList](h: H): String
}


class B extends A {
  override def test(h: (Int :: String :: HNil)): String = {
    val a = h(0)
    val b = h(1)
    s"$a -- $b"
  }
}


new B().test(25  :: "testje" ::  HNil)

即使没有 HLists,这也不是您在 Scala 中可以按原样做的事情。想象一下尝试做一些更简单的事情

trait Foo
trait Bar extends Foo

abstract class A {
  def test[T <: Foo](t: T): String
}

class B extends A {
  override def test(b: Bar): String = //...
}

这不起作用,因为 B.testA.test 的签名不同。一个有类型参数,而另一个没有。继承要求 B 应该能够充当 A,但这显然不能在这里发生。

相反,您可以将类型参数移动到 class 本身:

abstract class A[T <: Foo] {
  def test(t: T): String
}

class B extends A[Bar] {
  override def test(b: Bar): String = //...
}

这在使用 HList 时应该也能正常工作。