我有一个抽象类,其方法接收HList作为参数( A )。 但是在子类中,我想限制此HList的确切类型( B )
下面的代码不起作用(它没有看到(Int :: String :: HNil)
作为HList
的子类。但是如何才能达到类似的效果呢?
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)
答案 0 :(得分:3)
即使没有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.test
与A.test
的签名不同。一个有类型参数而另一个没有。继承要求B
应该能够充当A
,但这显然不可能在此发生。
相反,您可以将类型参数移动到类本身:
abstract class A[T <: Foo] {
def test(t: T): String
}
class B extends A[Bar] {
override def test(b: Bar): String = //...
}
使用HLists时,这也可以正常工作。