将方法参数限制为Scala中的特定类型

问题描述 投票:1回答:1

我有一个函数,我希望它是通用的,但限制它采取某种子类型。为了简单起见,我希望我的函数只适用于Long,Int,Float和Double。所以这就是我提出的:

def covariance[A](xElems: Seq[A], yElems: Seq[A]): A = {
  val (meanX, meanY) = (mean(xElems), mean(yElems))
  val (meanDiffX, meanDiffY) = (meanDiff(meanX, xElems), meanDiff(meanY, yElems))
  ((meanDiffX zip meanDiffY).map { case (x, y) => x * y }.sum) / xElems.size - 1
}

def mean[A](elems: Seq[A]): A = {
  (elems.fold(_ + _)) / elems.length
}

def meanDiff[A](mean: A, elems: Seq[A]) = {
  elems.map(elem => elem - mean)
}

这是我将用于检查上述类型的方法:

import scala.reflect.{ClassTag, classTag}
def matchList2[A : ClassTag](list: List[A]) = list match {
  case intlist: List[Int @unchecked] if classTag[A] == classTag[Int] => println("A List of ints!")
  case longlist: List[Long @unchecked] if classTag[A] == classTag[Long] => println("A list of longs!")
}

请注意,我正在使用ClassTag。我也可以使用TypeTag,甚至可以使用Shapeless库。

我想知道这是一个好方法吗?或者我应该使用有界类型来解决我想要的问题?

编辑:根据评论和建议使用分数类型,这是我认为它可以工作!

def covariance[A: Fractional](xElems: Seq[A], yElems: Seq[A]): A = {
  val (meanX, meanY) = (mean(xElems), mean(yElems))
  val (meanDiffX, meanDiffY) = (meanDiff(meanX, xElems), meanDiff(meanY, yElems))
  ((meanDiffX zip meanDiffY).map { case (x, y) => x * y }.sum) / xElems.size - 1
}

def mean[A](elems: Seq[A]): A = {
  (elems.fold(_ + _)) / elems.length
}

def meanDiff[A](mean: A, elems: Seq[A]) = {
  elems.map(elem => elem - mean)
}
scala generics
1个回答
0
投票

根据评论和意见,这是我想出来的!

def mean[A](xs: Seq[A])(implicit A: Fractional[A]): A =
  A.div(xs.sum, A.fromInt(xs.size))

def covariance[A](xs: Seq[A], ys: Seq[A])(implicit A: Fractional[A]): A = {
  val (meanX, meanY) = (mean(xs), mean(ys))
  val (meanDiffX, meanDiffY) = (meanDiff(meanX, xs), meanDiff(meanY, ys))
  (meanDiffX zip meanDiffY).map { case (x, y) => A.div(A.times(x, y), A.fromInt(xs.size - 1)) }.sum
}

def meanDiff[A](mean: A, elems: Seq[A])(implicit A: Fractional[A]): Seq[A] = {
  elems.map(elem => A.minus(elem, mean))
}
© www.soinside.com 2019 - 2024. All rights reserved.