Scala HList/KList来自类值

Scala HList/KList来自类值,scala,shapeless,hlist,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") }

我希望能够创建一个行为有点像枚举的类/特征(
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")
}
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] = ...
}
然后我希望能够执行或多或少的基本
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 A extends HEnum {
  val a = new Key[String]("a")
  val b = new Key[Int]("b")
  val c = new Key[Float]("c")
}
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] = ...
}
类键[A](val name:String)
对象键{

def apply[A,L你用
A
上的
find
操作来说明你想要的行为,但这并不是你最好的尝试,从评论中我也不清楚它的语义应该是什么。它几乎暗示了一种类似于记录的结构(在这种情况下,你有没有看过不成形的记录?)但是有点难说……你能详细说明一下吗?@MilesSabin
find[a]
基本上是
值的别名。我会尽最大努力选择[a]
(尽管我还没有尝试过)。如果find使用
字符串
,则只需遍历列表,查找带有
name==str
键。我怀疑在这种情况下,如果没有某种字符串->类型映射,或者至少没有显式的类型参数来传递给
值,那么获得正确的类型将更加困难。filter[a]
在查找特定的
键[A]之前
。我没有查看过不成形的记录。等我有时间的时候,我会对这些记录做一些研究。@MilesSabin我已经更新了我的问题,以便我的最佳尝试能够更清楚地说明它与我指定的内容之间的关系。你可以通过对
a
执行
find
操作来说明你想要的行为,但这并不适用我不清楚它的语义应该是什么。它几乎暗示了一种类似于记录的结构(在这种情况下,你看过不成形的记录吗?),但这有点难说……你能详细说明一下吗?@milessbin
find[a]
基本上是
值的别名。选择[a]
在我的最佳尝试中(尽管我还没有真正尝试过)。如果find使用
字符串
,则只需遍历列表,查找带有
name==str
键。我怀疑在这种情况下,如果没有某种字符串->类型映射,或者至少没有显式的类型参数来传递给
值,那么获得正确的类型将更加困难。filter[a]
在查找特定的
键[A]
之前。我没有查看过不成形的记录。等我有时间的时候,我会对这些记录进行一些研究。@milessbin我已经更新了我的问题,以便我的最佳尝试更清楚地说明它与我指定的内容之间的关系。