我发现了 HList / KList,它们非常酷。我有一个实际用例,其中具有保守类型信息的异构类型和可变长度容器将非常有用(有关更多信息,请参阅下面的背景)。但是,我还没有理解 H/KList 作为方法参数的用法,我被迫对参数进行完全类型注释或松散类型信息。如果完整类型当然是未知的,H/KLists 甚至可以用作参数吗?如何在不丢失类型信息的情况下引用 H/KList?
“类型列表”可以用来指代异构和可变长度类型参数的元组吗?这里它说:
... the types of the elements can be tracked separate from the actual element values. To do this we create an purely abstract type (it has no instances) which models a list of types, let's call it TList.
我玩过它,但还不明白如何将它用于 HList 的类型注释作为参数。
基本上,我想要这样的东西:
implicit def hlistToTypedLink[TL](a: HList[TL]):TypedLink[TL] = new TypedLink[TL](a.map(a:X => new TypedHandle[X]))
其中 TL 指的是类型列表,X 指的是当前元素的类型。所以这里应该将一个 HList 映射到另一个类似 Tuple 的容器 TypedLink,由类型列表 TL 参数化。每个元素都将被包装在另一个参数化容器 TypedHandle 中,使用当前类型 X 进行类型化。
这可能吗?
我看到了 Shapeless 的 HList 及其“统一”方法,但问题仍然存在:除了可变长度之外,我不知道如何在参数列表中引用它。
我的第二个希望是使用 KList。它适用于我的情况,因为 TypedHandle 是具有相同构造函数的通用容器。根据 apocalisp 的说法,使用 KList 似乎更容易键入注释:
val m = List(1, 2, 3, 4) :^: List("str1", "str2") :^: KNil
将是类型:
KCons[Int,java.lang.String :: HNil,List]
但是,问题仍然存在:在方法定义中,我不知道它是否会是
KCons[String, Int :: HNil, TH]
或一个
KCons[Foo, Bar, Baz :: HNil, TH]
所以我也不知道如何键入注释 KList 作为方法参数。
感谢您的任何提示!
背景:我正在为优秀的 OO- 和图形数据库 hypergraphdb 编写 scala 便利扩展。Hypergraphdb 的超边 HGLink 基本上是 HGHandle 的元组。HGHandle 指的是本身有类型的原子。因此 HGLink 本身将是异构类型和可变长度的。但是,到目前为止,HGLink 的实现是无类型的,并且是由 HGHandle 的无类型实现构建的。我猜 java 的类型系统的表现力不足以反映 hypergraphdb 的(非常优秀的)类型系统(例如,它也有更高种类的类型)。
基本上,我正在尝试将 scala 与 hypergraphdb 的类型系统连接起来,我学到了很多东西,直到现在这真的很有趣。除了许多其他黑客之外,TypedHandle 已经很好用了。
感谢您的任何建议。