我希望能够创建一个行为有点像枚举的类/特征(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[_]]
在需要时将容易出错/不安全的类型转换为正确的类型。
编辑
我还应该提到,这里找到的枚举示例对我来说并不是特别有帮助(尽管,如果可以调整,那就太好了)。为详尽的模式匹配添加的编译器检查很好(我最终希望这样做),但这个枚举仍然只允许枚举值的同质集合。