scala – 无形:IsHCons,隐含未找到
发布时间:2020-12-16 18:43:05 所属栏目:安全 来源:网络整理
导读:我试图让这个相当愚蠢的例子工作,计划然后将它扩展到更有意义的东西. 但到目前为止没有运气:我找不到参数ihc的隐含值 我错过了什么? sealed trait Field[T] { def name: String }case class IntegerField(name: String) extends Field[Int]val year = Inte
我试图让这个相当愚蠢的例子工作,计划然后将它扩展到更有意义的东西.
但到目前为止没有运气:我找不到参数ihc的隐含值 我错过了什么? sealed trait Field[T] { def name: String } case class IntegerField(name: String) extends Field[Int] val year = IntegerField("year") val test = (year :: 23 :: HNil) :: (year :: 2 :: HNil) :: HNil type TypedMap = IntegerField :: Int :: HNil def get[L <: HList : <<:[TypedMap]#λ] (key: IntegerField,list: L) (implicit ihc: IsHCons.Aux[L,TypedMap,L] ): Option[Int] = { if( list == HNil ) return None val elem: TypedMap = list.head if( elem.head == key ) Some(elem.tail.head) else get(key,list.tail) } get(year,test) 解决方法
当你写IsHCons.Aux [L,L]时,你要求证明hlist L有头部TypedMap和尾部L,这意味着它是一个无限的hlist,这是不可能的,因为Scala没有允许这种任意递归类型(尝试写类似Foo = Int :: Foo的东西,例如 – 你会得到一个“非法循环引用”错误).它也可能不是你想要的.
一般来说,你不太可能在Shapeless中使用IsHCons,因为在类型中指示你想要的结构几乎总是更好.例如,以下两个定义执行相同的操作: import shapeless._,ops.hlist.IsHCons def foo[L <: HList](l: L)(implicit ev: IsHCons[L]) = ev.head(l) 和: def foo[H,T <: HList](l: H :: T) = l.head 但第二个显然是可取的(它更清楚,它不需要在编译时找到额外的类型类实例,等等),并且几乎总是可以编写你想要这样做的任何东西. 另请注意,要求IsHCons实例意味着此处的递归将无法按照所述方式工作 – 您无法调用获取HNil,因为编译器无法证明它是HCons(因为它不是). 你确定你需要一个hlist吗?如果您要求hlist的所有成员都是TypedMap类型,那么您也可以使用Shapeless的Sized(如果您希望类型捕获长度)或甚至只是一个普通的旧List. 如果你真的想在这里使用HList,我建议你写一个新的类: trait FindField[L <: HList] { def find(key: IntegerField,l: L): Option[Int] } object FindField { implicit val findFieldHNil: FindField[HNil] = new FindField[HNil] { def find(key: IntegerField,l: HNil) = None } implicit def findFieldHCons[H <: TypedMap,T <: HList](implicit fft: FindField[T] ): FindField[H :: T] = new FindField[H :: T] { def find(key: IntegerField,l: H :: T) = if (l.head.head == key) Some(l.head.tail.head) else fft.find(key,l.tail) } } def get[L <: HList](key: IntegerField,l: L)(implicit ffl: FindField[L] ): Option[Int] = ffl.find(key,l) 然后: scala> get(IntegerField("year"),test) res3: Option[Int] = Some(23) scala> get(IntegerField("foo"),test) res4: Option[Int] = None 这在Shapeless中是一种非常常见的模式 – 您可以归纳地描述如何在空的hlist上执行操作,然后在hlist上将头部预先添加到尾部,知道如何执行操作等. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |