Scala:如何使用算术元素在可排序集合上编写泛型函数

时间:2016-12-18 20:29:50

标签: scala generics

我有以下Scala函数,

def isValid(xs: Array[Int]): Boolean = {
  val List(x, y, z) = xs.sorted.toList
  x + y > z
}

当我将输入类型更改为List[Double]时,这仍然有效。我想要的是使用泛型集合,以及可以比较和添加的任何元素。

编辑:这是我目前更通用的。不幸的是,它要求我指定通用参数。

def isValid[N, S <% Seq[N]](xs: S)(implicit n: Numeric[N]): Boolean = {
  val Seq(x, y, z) = xs.sorted
  n.gt(n.plus(x, y), z)
}

// Ideally, I wouldn't have to specify the generic parameters.
listOfArray.filter(isValid[Int, Array[Int]])
listOfList.filter(isValid[Double, List[Double]])

2 个答案:

答案 0 :(得分:0)

{p} sorted已在SeqLike中声明,因此您只需要Seq

  import Numeric.Implicits._
  import Ordering.Implicits._

  def isValid[N: Numeric](xs: Seq[N]): Boolean = {
    val Seq(x, y, z) = xs.sorted
    x + y > z
  }

答案 1 :(得分:0)

您可以使用Numeric s:

  • 扩展了Ordering,因此您可以在您的收藏中调用.sorted
  • 它实现了.plus.gt运算符

用法:

scala> def isValid[N](xs: Seq[N])(implicit ev: Numeric[N]): Boolean = {
         val x::y::z::Nil = xs.sorted.toList
         ev.gt(ev.plus(x, y), z)  // same as 'x + y > z'
       }
isValid: [N](xs: Seq[N])(implicit ev: Numeric[N])Boolean

然后:

scala> isValid(List(1, 2, 3))
res0: Boolean = false

scala> isValid(List(1d, 2d, 3d))
res1: Boolean = false

scala> isValid(List(1L, 2L, 2L))
res2: Boolean = true