我想要一个不同类型的通用列表,我想获得具有特定类型的对象。
我有这个结构:
trait Parent
case class A() extends Parent
case class B() extends Parent
case class C() extends Parent
我可以定义不同大小的不同列表:
val list:List[Parent] = A() :: B() :: C() :: C() ::Nil //or any size or ordering
我想在运行时将其转换为A,B,C,C的Hlist。 .toHlist []需要在运行时推断的元素类型。 什么是无形的方式呢?有没有办法将其转换为元组?
答案 0 :(得分:3)
你不能这样做。注意
应该在运行时推断
是一个矛盾。类型推断仅在编译时 。
换句话说,当你写一些像
这样的东西val list: A :: B :: C :: C :: HNil = ...
编译时知道list
变量的类型。在运行时不可能为变量赋值,它只是没有意义。假设它是可能的,你会有一个神奇的方法toHlistMagical
:
val list: List[Parent] = A() :: B() :: C() :: C() :: Nil
val hlist = list.toHlistMagical // infers to A :: B :: C :: C :: HNil
现在让我们改变一下:
def getHlist(list: List[Parent]) = list.toHlistMagical
现在你期望这个函数有什么返回类型?请记住,可以使用各种列表调用它,而不仅仅是按以下顺序包含A
,B
,C
,C
实例的列表:
getHlist(C() :: B() :: A() :: A() :: Nil)
可能是Any
,但是你可以随时使用List
,因为不再有HList
,所以你没有获得任何额外的类型安全。
这就是toHlist
需要类型的原因:
def getHlist(list: List[Parent]) = list.toHlist[A :: B :: C :: C :: HNil]
getHlist
现在有返回类型Option[A :: B :: C :: C :: HNil]
,因为您指定了所需的确切类型,toHlist
将能够执行list
结构的运行时验证并返回Some
如果列表确实按此顺序包含这些类型,或None
如果不包含这些类型。
答案 1 :(得分:0)
以下功能可以将您的列表转换为HList:
def listToHList(x: List[_]): HList = {
if(x == Nil) HNil
else x.head :: listToHList(x.tail)
}
对于您的示例,您可以按以下方式使用它:
listToHList(list).asInstanceOf[A :: B :: C :: HNil]