如何代表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) 这是我们想要的. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |