Scala通用列表添加

时间:2016-12-19 11:55:52

标签: scala implicit subtyping

我有功能:

 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))

2 个答案:

答案 0 :(得分:3)

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

  1. AnyVal是所有原始类型的超类型value classes。与AnyRef一起,它是两个类型分支之一,以Any类型为根,这是真正的超类型。
  2. Numeric类型不是covariant,这意味着Numeric[Int]的存在并不意味着Numeric[AnyVal]的存在,这是非常合乎逻辑的,如果您想一秒钟。整数是实数的子域,但知道如何乘以整数并不意味着你知道如何乘以实数。
  3. Subtyping polymorphism is not directly relatedrestricted parametric polymorphism。第一个主要是处理运行时,第二个通常是编译时。他们在scala中以非常具体的方式进行交互。
  4. 没有一个地方可以定义隐含值。 There are multiple places代表每种特定类型和地点。

答案 1 :(得分:2)

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

中定义

(假设scala 2.10.4)

Numeric[AnyVal]没有隐式定义,所以这就是你得到第一个例子的错误的原因(这是有道理的,因为在不知道基础类型的情况下无法定义数值运算)

Numeric[Boolean]也没有隐式定义,这就是为什么你得到第二个例子的错误(这也是有道理的,因为你无法定义plusminustimesnegate等对布尔运算的操作,而不对项目的特定领域做任何假设。)

如果对项目有意义,你可以自己定义隐式Numeric[Boolean],但最好避免对布尔类型使用隐式数字[T]。