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

如何代表Scala的案例部分更新?

发布时间:2020-12-16 19:07:56 所属栏目:安全 来源:网络整理
导读:我有以下案例类: case class PropositionContent(title:String,content:String) 我想将其部分修改为Data. 一种方式是创建案例类: case class PartialPropositionContent(title:Option[String],content:Option[String) 然后一些方法: object PropositionCo
我有以下案例类:

case class PropositionContent(title:String,content:String)

我想将其部分修改为Data.

一种方式是创建案例类:

case class PartialPropositionContent(title:Option[String],content:Option[String)

然后一些方法:

object PropositionContent {

   def append( pc  : PropositionContent,ppc : PartialPropositionContent) =
   PropositionContent ( ppc.title.getOrElse(pc.title),ppc.content.getOrElse(pc.content) )

   def append( ppc  : PartialPropositionContent,ppc2 : PartialPropositionContent ):  PartialPropositionContent = {...}

}

但它有点锅炉!

我认为一个案例类PropositionContent [M [_]](标题:M [String],内容:M [String])不会真正解决的东西,我不知道如何使用Shapeless来解决东西.

那你有什么想法?

解决方法

这是一个使用Shapeless的相对无缺陷的方法.首先我们定义一些关于Option的相关函数的多态版本:

import shapeless._

object orElser extends Poly1 {
  implicit def default[A] = at[Option[A]] {
    oa => (o: Option[A]) => oa orElse o
  }
}

object getOrElser extends Poly1 {
  implicit def default[A] = at[Option[A]] {
    oa => (a: A) => oa getOrElse a
  }
}

我们将代表一个HList的更新,其中每个元素都是一个选项,我们可以编写一个附加方法,允许我们附加两个更新:

import UnaryTCConstraint._

def append[U <: HList: *->*[Option]#λ,F <: HList](u: U,v: U)(implicit
  mapper: MapperAux[orElser.type,U,F],zipper: ZipApplyAux[F,U]
): U = v.map(orElser).zipApply(u)

最后我们可以写我们的更新方法本身:

def update[T,L <: HList,F <: HList,U <: HList](t: T,u: U)(implicit
  iso: Iso[T,L],mapped: MappedAux[L,Option,U],mapper: MapperAux[getOrElser.type,L,L]
) = iso from u.map(getOrElser).zipApply(iso to t)

现在我们只需要一点样板(在the future这不是必要的,谢谢inference-driving macros):

implicit def pcIso =
  Iso.hlist(PropositionContent.apply _,PropositionContent.unapply _)

我们还将为此特定的更新类型定义一个别名(这不是绝对必要的,但会使以下示例更简洁一些):

type PCUpdate = Option[String] :: Option[String] :: HNil

最后:

scala> val pc = PropositionContent("some title","some content")
pc: PropositionContent = PropositionContent(some title,some content)

scala> val u1: PCUpdate = Some("another title") :: None :: HNil
u1: PCUpdate = Some(another title) :: None :: HNil

scala> val u2: PCUpdate = Some("newest title") :: Some("new content") :: HNil
u2: PCUpdate = Some(newest title) :: Some(new content) :: HNil

scala> append(u1,u2)
res0: PCUpdate = Some(newest title) :: Some(new content) :: HNil

scala> update(pc,append(u1,u2))
res1: PropositionContent = PropositionContent(newest title,new content)

这是我们想要的.

(编辑:李大同)

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

    推荐文章
      热点阅读