scala – 需要比使用Shapeless方法所需的更多证据
发布时间:2020-12-16 18:33:58 所属栏目:安全 来源:网络整理
导读:我昨天和一些同事一起探索了Shapeless,我们决定编写一个玩具方法,在case参数为Int时,将一个添加到case类的第一个参数: def addOneToCaseClass[C,H : HList,E,T : HList] (c: C) (implicit gen: Generic.Aux[C,H],h: IsHCons.Aux[H,T],ev: E =:= Int,ev2: (I
我昨天和一些同事一起探索了Shapeless,我们决定编写一个玩具方法,在case参数为Int时,将一个添加到case类的第一个参数:
def addOneToCaseClass[C,H <: HList,E,T <: HList] (c: C) (implicit gen: Generic.Aux[C,H],h: IsHCons.Aux[H,T],ev: E =:= Int,ev2: (Int :: T) =:= H ): C = { val hList = gen.to(c) val elem = hList.head val tail = hList.tail val newElem = elem + 1 gen.from(newElem :: tail) } 在我看来,ev2参数是多余的 – 当然可以推断出E :: T =:= Int :: T,但是编译器无法实现这一点. 有什么特别的原因吗? 解决方法
你的直觉是合理的,但不幸的是,Scala编译器不够聪明,无法从h和ev派生出ev2.问题是h只确定H分解为E :: T,它没有建立相反的,即E和T结合为等于H.
我能提出的最简洁的表述类似于你原来的,但只有一个证人, def addOneToCaseClass[C,R <: HList,T <: HList](c: C) (implicit gen: Generic.Aux[C,R],h: IsHCons.Aux[R,Int,ev: (Int :: T) =:= R) = { val hList = gen.to(c) val elem = hList.head val tail = hList.tail gen.from(elem+1 :: tail) } 在这里,我们可以通过使用h来消除E =:= Int的证明,以证明R分解为Int :: T.但是我们仍然需要证明Int :: T等于R以回溯到gen更新的元素. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |