Scala:将通用案例类复制到另一个

时间:2016-07-15 22:23:49

标签: scala generics shapeless

我有以下设置,我希望将baseData的实例复制到moreData的实例:

sealed trait baseData {
  def weight: Int
  def priority: Int
} 

sealed trait moreData {
  def weight: Int
  def priority: Int
  def t: String
  def id: String
} 

case class data1(override val weight: Int, override val priority: Int) extends baseData 
case class moreData1 (override val weight:Int, override val priority: Int, override val t: String, override val id: String)extends moreData

myData复制到otherData下方:

val myData = data1(1,1) 
val otherData = moreData1 (2,2,"C","abcd") 

会产生:moreData1(1,1,"C","abcd")

为此,我想使用具有以下签名的函数,因为我将有多个案例类同时扩展baseDatamoreData

def copyOver[A <:baseData, B <:moreData](from: A, to: B) = {} 

我确定您可以使用Shapeless执行此操作,但无法弄清楚如何操作。复制案例类的示例(here)扩展了相同的特征,其他(here)通过通用表示在不同的案例类之间映射值。但我还没有想出如何将LabelledGeneric与传递给copyOver的特征有限的参数联系起来。我也不想对otherDatamyData中未出现的额外字段进行硬编码。

我正在寻找一个完全通用的实现。有什么想法吗?

1 个答案:

答案 0 :(得分:0)

您应该可以使用your first shapeless example中的UpdateRepr类型类。

您可以使用copyOver定义UpdateRepr,如下所示:

import shapeless._

// baseData, moreData, data1, moreData1
// UpdateRepr ...

def copyOver[A <: baseData, B <: moreData, R <: HList](
  from: A,
  to: B
)(implicit 
  lgen: LabelledGeneric.Aux[A, R],
  update: UpdateRepr[B, R]
): B = update(to, lgen.to(from))

您可以使用以下内容:

val myData = data1(1,1) 
val otherData = moreData1(2,2,"C","abcd") 

copyOver(myData, otherData)
// moreData1 = moreData1(1,1,C,abcd)

请注意,您可能会遇到SI-7046的问题,因为UpdateRepr的密封特征(Coproduct)类型派生,您可以在REPL中注意到或在分割UpdateRepr时以及多个文件的密封特征。