来自类值的HList / KList

时间:2015-12-14 23:45:23

标签: scala shapeless hlist

我希望能够创建一个类似于枚举的类/特征(下面第一个片段中的HEnum)。我不能使用普通枚举,因为每个枚举值可以有不同的类型(虽然容器类将是相同的):Key[A]。我希望能够像这样构建枚举:

class Key[A](val name: String)

object A extends HEnum {
  val a = new Key[String]("a")
  val b = new Key[Int]("b")
  val c = new Key[Float]("c")
}

然后我希望能够执行或多或少的基本HList操作,例如:

A.find[String] // returns the first element with type Key[String]
A.find("b") // returns the first element with name "b", type should (hopefully) be Key[Int]

到目前为止,我一直在使用HList作为基础数据结构,但是使用正确的类型构建一个已经证明是困难的。我最成功的尝试是这样的:

class Key[A](val name: String)
object Key {
  def apply[A, L <: HList](name: String, l: L): (Key[A], Key[A] :: L) = {
    val key = new Key[A](name)
    (key, key :: l)
  }
}

object A {
  val (a, akeys) = Key[String, HNil]("a", HNil)
  val (b, bkeys) = Key[Int, Key[String] :: HList]("b", akeys)
  val (c, ckeys) = Key[Float, Key[Int] :: HList]("c", bkeys)

  val values = ckeys // use this for lookups, etc

  def find[A]: Key[A] = values.select[A]
  def find[A](name: String): Key[A] = ...
}

这里的问题是界面很笨重。在值列表末尾的任何位置添加新值都是容易出错的,无论如何,只要引入新值,就必须手动更新values。没有HList的解决方案在需要时会将List[Key[_]]和容易出错/不安全的转换为正确类型。

修改

我还应该提一下,发现here的枚举示例对我没有特别的帮助(尽管如果可以调整,那么很好)。添加的编译器检查穷举模式匹配是很好的(我最终会想要),但这个枚举仍然只允许枚举值的同类集合。

0 个答案:

没有答案