加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

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更新的元素.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读