0

我有功能:

 def listSum[T](xs :List[T])(implicit  abc : Numeric[T]): T = {
    xs.sum
  }

  val IntList: List[Int] = List (1, 2, 3, 4)
  val DList: List[Double] = List (1.0, 2.0, 3, 4)

上面的代码示例工作正常,但是当我更改为下面的函数时,它停止工作并出现错误

找不到参数的隐式值abc: Numeric[AnyVal]

既然AnyVal是我可以添加的基本类型,不是吗?

所有隐含定义在哪里?

 def listSum(xs :List[AnyVal])(implicit  abc : Numeric[AnyVal]) = {
    xs.sum
  }

 val AList: List[AnyVal] = List (1, 2, 3, 4)

这也不起作用,我认为出于同样的原因。

  def listSum[T](xs :List[T])(implicit  abc : Numeric[T]): T = {
    xs.sum
  }

  val BList : List[Boolean] = List(true, false)
  println(listSum(BList))
4

2 回答 2

3

您的问题中有几个不正确的假设:

  1. AnyVal是所有原始类型和值类的超类型。连同AnyRef它是两个类型分支之一,根植于Any类型,这是真正的超类型。
  2. Numerictype 不是协变的,这意味着 of 的存在Numeric[Int]并不意味着 的存在Numeric[AnyVal],如果您想一想,这是非常合乎逻辑的。整数是实数的子域,但知道如何乘以整数并不意味着你知道如何乘以实数。
  3. 子类型多态性受限参数多态性没有直接关系。第一个主要是在运行时处理,而第二个通常是在编译时处理。它们在 scala 中以非常特定的方式进行交互。
  4. 没有一个地方可以定义隐式值。每个特定类型和位置在代码中有多个位置
于 2016-12-19T12:33:56.997 回答
2

Numeric[T] 的所有隐式定义都在 scala/math/Numeric.scala 中定义

(假设 Scala 2.10.4)

没有隐式定义Numeric[AnyVal],因此这就是为什么您在第一个示例中得到错误的原因(这是有道理的,因为在不了解基础类型的情况下无法定义数字运算)

也没有隐式定义Numeric[Boolean],这就是为什么您在第二个示例中得到错误的原因(这也是有道理的,因为如果不假设有关项目的特定域的任何内容,就无法在布尔值上定义plus, minus, times,negate等操作) .

如果这对您的项目有意义,您可以自己定义一个隐式Numeric[Boolean],但最好避免将隐式 Numeric[T] 用于布尔类型。

于 2016-12-19T12:30:25.893 回答