【问题标题】:runtime conversion of List to HListList 到 HList 的运行时转换
【发布时间】:2015-02-10 20:24:25
【问题描述】:

我想要一个不同类型的通用列表,我想要获取具有特定类型的对象。

我有这个结构:

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[] 需要在运行时推断的元素类型。 什么是无形的方式呢?有没有办法将它转换为元组?

【问题讨论】:

  • 你想达到什么目的?
  • 正如其他人回复的那样,一旦您转到List[Parent],有关列表中各个元素的所有编译时类型信息(创建 HList 所必需的)都消失了。这是一个不可逆的操作。
  • @ziggystar 我需要使用这样的东西:myHlist.filter[A] 但由于我的代码中运行时流程不同,它可能是任何东西。假设我们有一个条件,所以在一个分支中它可能是 A::B::C::C 在另一个分支中可能是完全不同的东西,所以我在编译时没有类型顺序,有什么办法可以在我定义的每个分支都不一样?或者有没有其他方法可以达到同样的目标?

标签: scala types shapeless


【解决方案1】:

你做不到。请注意

应该在运行时推断

是矛盾的。类型推断仅在编译时起作用

换句话说,当你写类似的东西时

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

现在你希望这个函数有什么返回类型?请记住,它可以使用各种列表来调用,而不仅仅是那些包含 ABCC 实例的列表:

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,如果没有。

【讨论】:

    【解决方案2】:

    以下函数可以将您的列表转换为 HList:

    def listToHList(x: List[_]): HList = {
      if(x == Nil) HNil
      else x.head :: listToHList(x.tail)
    }
    

    对于您的示例,您可以像下面这样使用它:

    listToHList(list).asInstanceOf[A :: B :: C :: HNil]

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-08-13
      • 1970-01-01
      • 1970-01-01
      • 2021-02-02
      • 1970-01-01
      相关资源
      最近更新 更多