1

我希望能够创建一个行为有点像枚举的类/特征(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]

到目前为止,我一直在使用 aHList作为底层数据结构,但事实证明,构建一个具有正确类型的数据结构很困难。我最成功的尝试是这样的:

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[_]]在需要时将容易出错/不安全的类型转换为正确的类型。

编辑

我还应该提到,这里找到的枚举示例对我来说并不是特别有帮助(尽管,如果可以调整,那就太好了)。为详尽的模式匹配添加的编译器检查很好(我最终希望这样做),但这个枚举仍然只允许枚举值的同质集合。

4

0 回答 0