我发现了HList / KList,它们很酷。我有一个实际的用例,在这个用例中,具有保守类型信息的异源类型和可变长度容器将非常有用(有关更多信息,请参见下面的背景)。但是,我还没有理解H/KList作为方法参数的用法,在这种情况下,我不得不完全键入-注释参数或松散的类型信息。如果完全类型当然是未知的,那么H/KList甚至可以用作参数吗?如何在不丢失类型信息的情况下引用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映射到另一个类似元组的容器,TypedLink,由类型列表TL参数化。这些元素将分别包装在另一个参数化容器TypedHandle中,当前类型为X。
这个是可能的吗?
我看到了无形的‘HList’和它的“统一”方法,但是问题仍然是一样的:除了变量长度之外,我不知道如何在参数列表中引用它。
我的第二个希望是使用KList。它适用于我的情况,因为TypedHandle是一个具有相同构造函数的公共容器。使用KList,按照apocalisp的说法,输入注释似乎更容易
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&图形数据库超图数据库编写scala方便扩展。Hypergraphdb的超边HGLink基本上是HGHandle的元组,HGHandle指的是本身是类型化的原子。因此,HGLink本身将是异类类型和可变长度。然而,到目前为止,HGLink的实现都是非类型化的,并且是由HGHandle的非类型化实现所构造的。我认为java的类型系统的表达能力不足以反映超图数据库(例如,它也具有更高的类型)的(更高级的)类型系统。
基本上,我试图将scala与超图数据库的类型系统连接起来,我学到了很多,到目前为止,这真的很有趣。TypedHandle的工作已经很棒了,除了许多其他的黑客。
谢谢你的建议。
发布于 2012-09-03 19:46:27
我不太清楚你想要什么,但是你的hlistToTypedLink看起来可以用非形状的HList和多态函数值来处理,
scala> import shapeless._ ; import TypeOperators._
import shapeless._
import TypeOperators._
scala> class TypedHandle[T]
defined class TypedHandle
scala> class TypedLink[L <: HList](l : L)
defined class TypedLink
scala> object MkTypedHandle extends (Id ~> TypedHandle) {
| def apply[T](t : T) = new TypedHandle[T]
| }
defined module MkTypedHandle
scala> def hlistToTypedLink[L <: HList, M <: HList](a: L)
| (implicit mapper: MapperAux[MkTypedHandle.type, L, M]) =
| new TypedLink[M](a map MkTypedHandle)
hlistToTypedLink: [L <: HList, M <: HList](a: L)
(implicit mapper: MapperAux[MkTypedHandle.type,L,M])TypedLink[M]
scala> hlistToTypedLink(23 :: "foo" :: true :: HNil)
res0: TypedLink[TypedHandle[Int] :: TypedHandle[String] ::
TypedHandle[Boolean] :: HNil] = TypedLink@51fb5716本质上,它看起来像是要映射您的参数HList a,将每个元素包装在TypedHandle中,然后将结果HList包装到TypedLink中。在任何情况下,包装都要根据其内容的类型进行精确的参数化。
如上所示,使用无形状的HList map是可能的。这里有两个关键的成分。首先,类似于多态函数的值MkTypedHandle的定义,它可以映射到创建HList of TypedLink-wrapped元素的HList a。第二,驱动映射操作的隐式见证mapper。
发布于 2012-09-04 10:56:05
当你提到我的博客文章时,我最好做出回应。TList只是一个没有值存储的HList,即只有列表的类型表示,没有运行时表示。一个优点是,它为不同的、可能更有效的值存储类型提供了便利,例如数组(HArray in Metascala)。TLists也可以用来建模联合类型(基本上是类型集),但是Scala的类型系统还不够强大,不能只在类型级别(我认为Haskell的类型系统是)。
https://stackoverflow.com/questions/12252366
复制相似问题