HList 上的类型级映射

Type level mapping over a HList

我正在处理我的数据库 API 并且基本上想将列族建模为 HList 列,后者松散地是 Seq[_],所以我在某处有一个类似 Column[String]::Column[Int]::Column[Double]::HNil 的类型,所有元素共享一个公共类型构造函数。

表达行类型的最简单方法是什么,即 String::Int::Double::HNil,从上面给出的类型,本质上展开内部类型? 我目前的推理是,由于 shapeless 可以在给定 poly 的情况下对 HList 进行映射,因此应该能够(滥用)使用 [=17= 的依赖类型 Out ] 特质。

我能想到的一件事就是在正确的情况下实现无用的 poly,例如对所有 T 执行 Case.Aux[Column[T],T],然后为所有 Mapper 调用 Mapper it et voilá,我有我的 Out,但这感觉有点老套,我不确定它是否有效。 另一方面,我对依赖类型和类型递归还不太满意,真的想尝试并实现 shapeless 显然已经实现的东西。

感谢您的任何意见!

尝试

import shapeless.PolyDefns.~>
import shapeless.ops.hlist.{Comapped, NatTRel}
import shapeless.{HList, HNil, Id}

object App {
  case class Column[A](a: A)

  def extract[L <: HList, L1 <: HList](l: L)(implicit
    comapped: Comapped.Aux[L, Column, L1],
    natTRel: NatTRel[L, Column, L1, Id],
  ): L1 = natTRel.map(new (Column ~> Id) { def apply[T](col: Column[T]) = col.a }, l)

  val result = extract(Column(1) :: Column("a") :: HNil)

  def main(args: Array[String]): Unit = {
    println(result) // 1 :: a :: HNil
  }
}

import shapeless.PolyDefns.~>
import shapeless.ops.hlist.NatTRel
import shapeless.{HList, HNil}

object App {
  case class Column[A](a: Seq[A])

  def extract[L <: HList, L1 <: HList](l: L)(implicit
    natTRel: NatTRel[L, Column, L1, Seq],
  ): L1 = natTRel.map(new (Column ~> Seq) { def apply[T](col: Column[T]): Seq[T] = col.a }, l)

  val result = extract(Column(Seq("a", "b")) :: Column(Seq(1, 2)) :: Column(Seq(10.0, 20.0)) :: HNil)

  def main(args: Array[String]): Unit = {
    println(result) // List(a, b) :: List(1, 2) :: List(10.0, 20.0) :: HNil
  }
}