scala – 映射无形HList的类型
发布时间:2020-12-16 18:50:07 所属栏目:安全 来源:网络整理
导读:我一直在尝试从 scala的无形包中映射HList的类型,而无需访问它们的值. 以下成功映射HList的值 import shapeless._import shapeless.Poly._import ops.hlist.Mapperimport ops.hlist.Mapper._trait Person { type Value val v : Value}case class StringPerso
我一直在尝试从
scala的无形包中映射HList的类型,而无需访问它们的值.
以下成功映射HList的值 import shapeless._ import shapeless.Poly._ import ops.hlist.Mapper import ops.hlist.Mapper._ trait Person { type Value val v : Value } case class StringPerson extends Person { type Value = String val v = "I like strings" } case class IntPerson extends Person { type Value = Int val v = 42 } object what_is_going_on { object test_value_op { val stringPerson = StringPerson() val intPerson = IntPerson() trait lpvfun extends Poly1 { implicit def default[A <: Person] = at[A](_.v) } object vfun extends lpvfun {} // Use these to generate compiler errors if the mapped type is not what we'd expect: type TestListType = StringPerson :: IntPerson :: HNil type TestListExpectedMappedType = String :: Int :: HNil // Input: val testList : TestListType = stringPerson :: intPerson :: HNil // Output: val mappedList : TestListExpectedMappedType = testList map vfun // Get the actual mapped type type TestListActualMappedType = mappedList.type // This compiles...... val mappedList1 : TestListActualMappedType = mappedList // .... but weirdly this line doesn't. That isn't the point of this question,but I'd be very grateful for an answer. //implicitly[TestListActualMappedType =:= TestListExpectedMappedType] } } 凉!除了由于某种原因无法隐式使用[A =:= B]之外,HList的值已被映射,因此它们的类型也是如此. 现在,假设我们没有HList值,但我们知道它的类型.我们如何映射其类型? 我根据地图here的定义尝试了以下内容: object test_type_op { type TestListType = StringPerson :: IntPerson :: HNil type TestListExpectedMappedType = String :: Int :: HNil // Attempt 1 does not work,compiler cannot prove =:= type MappedType = Mapper[vfun.type,TestListType]#Out implicitly[MappedType =:= TestListExpectedMappedType] // Attempt 2 does not work,compiler cannot prove =:= class GetMapper { implicit val mapper : Mapper[vfun.type,TestListType] implicitly[mapper.Out =:= TestListExpectedMappedType] } } 如何在不访问其值的情况下获取映射的HList的类型?有没有办法调试为什么编译器无法证明什么?谢谢你的阅读. 解决方法
在TestListActualMappedType的情况下,您已经获得了mappedList的单例类型,这与推断的mappedList类型不同.在不涉及Shapeless的情况下,您可以看到完全相同的问题:
scala> val x = "foo" x: String = foo scala> implicitly[x.type =:= String] <console>:13: error: Cannot prove that x.type =:= String. implicitly[x.type =:= String] ^ 您可以要求证明x.type是String的子类型,或者您可以使用shapeless.test.typed,在您的情况下看起来像这样: import shapeless._,ops.hlist.Mapper trait Person { type Value val v : Value } case class StringPerson() extends Person { type Value = String val v = "I like strings" } case class IntPerson() extends Person { type Value = Int val v = 42 } trait lpvfun extends Poly1 { implicit def default[A <: Person] = at[A](_.v) } object vfun extends lpvfun {} val stringPerson = StringPerson() val intPerson = IntPerson() val testList = stringPerson :: intPerson :: HNil val mappedList = testList map vfun shapeless.test.typed[String :: Int :: HNil](mappedList) 尽管如此,这并没有明确指定类型. 您可以要求提供证据证明类型类的输出类型(如Mapper)是您对特定输入类型所期望的类型: scala> val m = Mapper[vfun.type,StringPerson :: IntPerson :: HNil] m: shapeless.ops.hlist.Mapper[vfun.type,shapeless.::[StringPerson,shapeless.::[IntPerson,shapeless.HNil]]]{type Out = shapeless.::[String,shapeless.::[Int,shapeless.HNil]]} = shapeless.ops.hlist$Mapper$$anon$5@6f3598cd scala> implicitly[m.Out =:= (String :: Int :: HNil)] res1: =:=[m.Out,shapeless.::[String,shapeless.HNil]]] = <function1> 这更有可能是有用的,但它又取决于你究竟想要说服自己的具体内容. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |