我想要一个不同类型的通用列表,我想获得具有特定类型的对象.
我有这个结构:
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 []需要在运行时推断的元素类型.
什么是无形的方式呢?有没有办法将其转换为元组?
解决方法
你不能这样做.注意
should be infer in runtime
是一个矛盾.类型推断仅在编译时工作.
换句话说,当你写一些像
val list: A :: B :: C :: C :: HNil = ...
列表变量的类型在编译时是已知的.在运行时不可能为变量赋值,它只是没有意义.假设它是可能的,你将有一个神奇的方法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,C实例的列表:
getHlist(C() :: B() :: A() :: A() :: Nil)
它可能是Any,但是你可以随便使用List,因为它不再有HList,所以你没有得到任何额外的类型安全.
这就是为什么要列出需求类型的原因:
def getHlist(list: List[Parent]) = list.toHlist[A :: B :: C :: C :: HNil]
getHlist现在有返回类型Option [A :: B :: C :: C :: HNil],因为你指定了你想要的确切类型,toHlist将能够执行列表结构的运行时验证并返回一些如果列表确实按此顺序包含这些类型,如果不包含,则为None.