HList上的类型级别映射

时间:2019-02-09 05:59:53

标签: scala mapping shapeless type-level-computation hlist

我正在滚动我的数据库API,本质上是想将列族建模为列的HList,而后者则松散地是Seq[_],所以在某个地方我有一个类似{{1}的类型},所有元素都共享一个通用的类型构造函数。

从上面给出的类型中最简单地表示行类型(即内部类型)的最简单的表达方式是什么? 我目前的推理是,由于无形可以在给定Column[String]::Column[Int]::Column[Double]::HNil的情况下在String::Int::Double::HNil上绘制地图,因此,一个人应该能够(ab)使用{{1}的依赖类型HList }。

我想到的一件事就是在正确的情况下实现无用的poly,例如对所有Out的{​​{1}}然后召唤Mapper等亲爱的,我那里有我的poly,但这有点,而且我不确定它是否还能工作。 另一方面,对于依赖类型和类型递归,我还不愿意真正尝试尝试实现无形的东西。

谢谢您的输入!

1 个答案:

答案 0 :(得分:3)

尝试

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
  }
}