在Scala中合并两个具有不同类型参数的集合

在Scala中合并两个具有不同类型参数的集合,scala,polymorphism,Scala,Polymorphism,我需要实现一个类,它基本上包含一个键和一个值对,其中值是一个元组序列。该元组包含一个对象SynthesizedMetricTag,以及一个类型参数a,该参数具有数值上下文绑定,因此实际上是一个k/v序列,其中v需要是一个数字 case class Cohort[A : Numeric](index:Any,values:Seq[(SynthesizedMetricTag,A)]) 当我必须实现一个合并这个类的两个实例的函数时,问题就来了。更具体地说,当我必须将类型a的序列与类型B的序列合并时,

我需要实现一个类,它基本上包含一个键和一个值对,其中值是一个元组序列。该元组包含一个对象
SynthesizedMetricTag
,以及一个类型参数a,该参数具有
数值
上下文绑定,因此实际上是一个k/v序列,其中v需要是一个数字

case class Cohort[A : Numeric](index:Any,values:Seq[(SynthesizedMetricTag,A)])
当我必须实现一个合并这个类的两个实例的函数时,问题就来了。更具体地说,当我必须将类型a的序列与类型B的序列合并时,问题就出现了。这两种类型都有一个
数值的
上下文范围,所以我的想法是,最后我得到一个
队列[C]
与上下文绑定并合并
A
B
类型序列的所有K/V对,而不重复任何键

case class Cohort[A : Numeric](index:Any,values:Seq[(SynthesizedMetricTag,A)]) {
  def merge[B : Numeric, C:Numeric](that:Cohort[B]):Cohort[C] =
    if(this.index != that.index) throw new Exception("Unable to merge Cohorts. Criteria is not the same")
    else {
      val b = new ArrayBuffer[(SynthesizedMetricTag,C)]()
      val seen = new mutable.HashSet[SynthesizedMetricTag]()
      for (x <- this.values; y <- that.values){
        if(!seen(x._1)){
          b+= x
          seen += x._1
        }
        if(!seen(y._1)){
          b+= y
          seen += y._1
        }
      }
      Cohort(this.index,b.toSeq)
    }
}
因此,我尝试了以下方法:

case class Cohort[A : Numeric](index:Any,values:Seq[(SynthesizedMetricTag,A)]) {
  def merge[B : Numeric, C:Numeric](that:Cohort[B]):Cohort[C] =
    if(this.index != that.index) throw new Exception("Unable to merge Cohorts. Criteria is not the same")
    else {
      val b = new ArrayBuffer[(SynthesizedMetricTag,C)]()
      val seen = new mutable.HashSet[SynthesizedMetricTag]()
      for (x <- this.values; y <- that.values){
        if(!seen(x._1)){
          b+= x.asInstanceOf[(SynthesizedMetricTag,C)]
          seen += x._1
        }
        if(!seen(y._1)){
          b+= y.asInstanceOf[(SynthesizedMetricTag,C)]
          seen += y._1
        }
      }
      Cohort(this.index,b.toSeq)
    }
}
病例组[A:数值](索引:任意,值:Seq[(综合计量表,A)]){
def merge[B:Numeric,C:Numeric](即:队列[B]):队列[C]=
如果(this.index!=that.index)抛出新异常(“无法合并队列。条件不相同”)
否则{
val b=新阵列缓冲[(合成计量表,C)]()
val seen=new mutable.HashSet[SynthesizedMetricTag]()

对于(x1),我将使用从A型和B型到C型的隐式证据来定义该方法

case class Cohort[A <: Numeric](index:Any,values:Seq[(SynthesizedMetricTag,A)]) {
 def merge[B <: Numeric, C](that:Cohort[B])(implicit ev1:A=>C, ev2:B=>C):Cohort[C] =
   if(this.index != that.index) throw new Exception("Unable to merge Cohorts. Criteria is not the same")
   else {
     val b = new ArrayBuffer[(SynthesizedMetricTag,C)]()
     val seen = new mutable.HashSet[SynthesizedMetricTag]()
     for (x <- this.values; y <- that.values){
       if(!seen(x._1)){
         b += x._1 -> ev1(x._2)
         seen += x._1
       }
       if(!seen(y._1)){
         b+= y._1 -> ev2(y._2)
         seen += y._1
       }
     }
     Cohort(this.index,b.toSeq)
   }
}
病例组群[ac]:组群[C]=
如果(this.index!=that.index)抛出新异常(“无法合并队列。条件不相同”)
否则{
val b=新阵列缓冲[(合成计量表,C)]()
val seen=new mutable.HashSet[SynthesizedMetricTag]()
对于(x ev2(y._2)
所见+=y._1
}
}
队列(本指数,b.toSeq)
}
}

如果
A
Double
B
Long
C
Byte
,你到底想怎么办?那么
C
需要作为类型参数传递,否则编译器不知道
C
是什么,所以我希望
A
B
是转换为
C
。但我真正想做的是永远不要丢失信息。因此,例如,如果
A
Int
,而
B
Float
,我想
A
转换为
Float
,并将
A
B
合并到一个集合
C
Float
)。当然这个层次结构不存在,是吗?这就是为什么我需要将结果类型抽象为C并手动确定它。
case class Cohort[A <: Numeric](index:Any,values:Seq[(SynthesizedMetricTag,A)]) {
 def merge[B <: Numeric, C](that:Cohort[B])(implicit ev1:A=>C, ev2:B=>C):Cohort[C] =
   if(this.index != that.index) throw new Exception("Unable to merge Cohorts. Criteria is not the same")
   else {
     val b = new ArrayBuffer[(SynthesizedMetricTag,C)]()
     val seen = new mutable.HashSet[SynthesizedMetricTag]()
     for (x <- this.values; y <- that.values){
       if(!seen(x._1)){
         b += x._1 -> ev1(x._2)
         seen += x._1
       }
       if(!seen(y._1)){
         b+= y._1 -> ev2(y._2)
         seen += y._1
       }
     }
     Cohort(this.index,b.toSeq)
   }
}