scala - 异构树的类型级展平

标签 scala shapeless

我正在学习 Shapeless 并实现了一个简单的异构树

我希望能够提取保留类型信息的标签。我很努力,但还没有草图来展示解决方案。任何帮助表示赞赏!

object TreeTest {

  import shapeless._

  case class HTree[A, F <: HList](label: A, forest: F) {
    def withBranch[T, FF <: HList](tree: HTree[T, FF]): HTree[A, HTree[T, FF] :: F] = new HTree(label, tree :: forest)
  }

  object HTree {
    def apply[A](label: A) = new HTree[A, HNil](label, HNil)
  }

  val t1 = HTree(1)
  val t2 = HTree("1")
  val t3 = t2.withBranch(HTree(2.0))
  val t4: HTree[Int, HTree[String, HTree[Double, HNil] :: HNil] :: HNil] = t1.withBranch(t3)

  def labels[A, F <: HList](t: HTree[A, F]) = ???

  val flattened: Int :: String :: Double :: HNil = labels(t4)
}

最佳答案

我能够创建一个递归多态函数来提取您的 HTree 的标签:

import shapeless._, ops.hlist._

object getLabels extends Poly1 {
  implicit def caseHTree[A, F <: HList, M <: HList](implicit 
    fm: FlatMapper.Aux[getLabels.type, F, M],
    prepend: Prepend[A :: HNil, M]
  ) : Case.Aux[HTree[A, F], prepend.Out] = 
    at[HTree[A, F]](tree => prepend(tree.label :: HNil, fm(tree.forest)))
}

它将当前 HTree 的标签添加到它递归获取的分支的标签(在 forest 上进行平面映射)。

t4 的结果:

getLabels(t4)
// Int :: String :: Double :: HNil = 1 :: 1 :: 2.0 :: HNil

关于scala - 异构树的类型级展平,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33426077/

相关文章:

scala - Scala 中的比较

scala - 无形 : Checking of the Type Constraints of Polymorphic Functions (lifted types)

scala - 确定 Manifest[T] 的 T 是否是一个集合

Scala 向量折叠语法 (/: and :\and/:\)

inheritance - scala 中亚型多态性的替代方法是什么?

Scala 无形压缩问题

scala - 使用带有 LabelledGenerics 的无形状标签

scala - 使用ScalaTest测试Akka Actor

scala - leftReduce 泛型类型的无形状 HList

scala - 如何从 HList 创建镜头的 HList