scala – 如何在HLists上实现zipWithIndex
发布时间:2020-12-16 18:12:46 所属栏目:安全 来源:网络整理
导读:在HList上编写算法,我需要一个zipWithIndex函数.它现在不在无形图书馆,所以我决定实施它. 很明显它可能被实现为 hlist.zip(indexes) 其中索引是索引的HList(0..n),这可能是通过这种方式获得的: val indexes = Nat._0 until hlist.length 这里的问题是Nat直
在HList上编写算法,我需要一个zipWithIndex函数.它现在不在无形图书馆,所以我决定实施它.
很明显它可能被实现为 hlist.zip(indexes) 其中索引是索引的HList(0..n),这可能是通过这种方式获得的: val indexes = Nat._0 until hlist.length 这里的问题是Nat直到方法才有.我没有找到任何与HList.map一起使用的HList索引的Witness. 从Nat._0开始直到hlist.length,我可以使用什么方法来获取Nats的NList? 解决方法
向Shapeless添加这样的东西可能是有意义的:
import shapeless._,ops.hlist.Prepend trait Range[A <: Nat,B <: Nat] extends DepFn0 { type Out <: HList } object Range { type Aux[A <: Nat,B <: Nat,Out0 <: HList] = Range[A,B] { type Out = Out0 } implicit def emptyRange[A <: Nat]: Aux[A,A,HNil] = new Range[A,A] { type Out = HNil def apply(): Out = HNil } implicit def slightlyBiggerRange[A <: Nat,OutAB <: HList](implicit rangeAB: Aux[A,B,OutAB],appender: Prepend[OutAB,B :: HNil],witnessB: Witness.Aux[B] ): Aux[A,Succ[B],appender.Out] = new Range[A,Succ[B]] { type Out = appender.Out def apply(): Out = appender(rangeAB(),witnessB.value :: HNil) } } def range[A <: Nat,B <: Nat](implicit r: Range[A,B]): r.Out = r() 现在你可以非常干净地编写zipWithIndex: import ops.hlist.{ Length,Zip } def zipWithIndex[L <: HList,S <: Nat,R <: HList,Out <: HList](l: L)(implicit len: Length.Aux[L,S],range: Range.Aux[nat._0,S,R],zipper: Zip.Aux[L :: R :: HNil,Out] ): Out = l.zip(range()) 然后: import nat._ type Expected = (Int,_0) :: (Symbol,_1) :: (String,_2) :: HNil val xs: Expected = zipWithIndex(1 :: 'a :: "foo" :: HNil) 您还可以使用折叠或ZippedWithIndex [L<:HList]类型类,这两种类型可能更简洁,但不太清楚,由Range等独立有用的部分组成. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |