Scala - 在AnyVal上使用数学运算

时间:2015-06-11 15:59:23

标签: scala apache-spark

我正在编写适用于数值的Spark RDD的通用数学运算函数。

对于乘法,我有一些看起来像这样的东西:

def mult(rdd1: RDD[AnyVal], rdd2: RDD[AnyVal]): RDD[AnyVal] = {
    rdd1.zip(rdd2).map(row => row._1 * row._2)
}

*不是AnyVal的成员,所以这不会编译。我能做些什么来使这项工作?

1 个答案:

答案 0 :(得分:2)

如何将<TR>用于数字类型?

这应该有效:

Numeric

如果你想能够将任何东西与任何东西相乘,那么你需要告诉编译器如何做到这一点。

为此,让我们声明一个描述功能的特征:

  def mult[X:Numeric](rdd1: RDD[X], rdd2: RDD[X]): RDD[X] = {
    import Numeric.Implicits._
    rdd1.zip(rdd2).map(row => row._1 * row._2)
  }

现在你可以定义一个泛型函数乘法,将乘法提升到其他类型(我将使用trait Multiplier[A, B, C] { def multiply(a: A, b: B): C } 你可以使用Seq):

RDD

现在让我们告诉编译器如何将def multiply[A,B,C](as:Seq[A],bs:Seq[B])(implicit multiplier: Multiplier[A,B,C]): Seq[C] = as zip bs map ( p => multiplier.multiply(p._1, p._2)) Int相乘(Scala可以将StringString相乘,而不是另一个Int因此,让我们定义乘数:

implicit object IntStringMultipler extends Multiplier[Int, String, Seq[String]] {
  override def multiply(a: Int, b: String): Seq[String] = (1 to a) map (_ => b)
}

为了让它更有趣,2 * "x"Seq("x", "x")而不是"xx",就像Scala自己的"x" * 2一样。

现在我们可以致电multiply(Seq(2, 3), Seq("a", "b"))来获取List(Vector("a", "a"), Vector("b", "b", "b"))