scala - Merge non-null fields in two case classes -


i'm trying modify caseclassmerge example shapeless library merge non-null fields.

object mergesyntax {   implicit class mergesyntax[t](t: t) {     def merge[u](u: u)(implicit merge: caseclassmerge[t, u]): t = merge(t, u)   } }  trait caseclassmerge[t, u] {   def apply(t: t, u: u): t }  object caseclassmerge {   import ops.record.merger    def apply[t, u](implicit merge: caseclassmerge[t, u]): caseclassmerge[t, u] = merge    implicit def mkccmerge[t, u, rt <: hlist, ru <: hlist]     (implicit       tgen: labelledgeneric.aux[t, rt],       ugen: labelledgeneric.aux[u, ru],       merger: merger.aux[rt, ru, rt]     ): caseclassmerge[t, u] =     new caseclassmerge[t, u] {       def apply(t: t, u: u): t =         tgen.from(merger(tgen.to(t), ugen.to(u)))     } } 

how modify merging logic in way non-null fields in second argument merged first argument?

you add own implicit merger implementation current scope, overriding standard merger:

object notnullhlistmerger {   import shapeless.labelled._   import shapeless.ops.record.merger   import shapeless.ops.record.remover    implicit def notnullhlistmerger[k, v, t <: hlist, m <: hlist, mt <: hlist]   (implicit    rm: remover.aux[m, k, (v, mt)],    mt: merger[t, mt]   ): merger.aux[fieldtype[k, v] :: t, m, fieldtype[k, v] :: mt.out] =     new merger[fieldtype[k, v] :: t, m] {       type out = fieldtype[k, v] :: mt.out       def apply(l: fieldtype[k, v] :: t, m: m): out = {         val (mv, mr) = rm(m)         val = field[k](mv)         // replace if value not null         val h = option(up).getorelse(l.head)         h :: mt(l.tail, mr)       }     } }  import mergesyntax._ import notnullhlistmerger._  case class foo(i: int, s: string, b: boolean) case class bar(b: boolean, s: string)  val foo = foo(23, "foo", true) val bar = bar(false, null)  val merged = foo merge bar assert(merged == foo(23, "foo", false)) 

Comments