2016-12-19 12 views
0

Я очень новичок в scala. У меня есть функцияScala Generic List adition

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

Вы не можете суммировать «anyval», так как не определено, как это сделать. Однако вы можете суммировать «числовые» вещи. Пример 'def listSum [T: Числовой] (xs: Список [T]): T = xs.sum' – Tyth

ответ

2

Все неявные определения для ввода цифр [T] определены в математике/лестницы/Numeric.scala

(предполагая, что Scala 2.10.4)

Там нет неявного определения для Numeric[AnyVal], так вот почему вы получаете ошибку для своего первого примера (это имеет смысл, потому что невозможно определить числовые операции, не зная ничего о базовом типе)

Существует также неявное определение для Numeric[Boolean], поэтому вы получаете ошибку для своего второго примера (это также имеет смысл, потому что нельзя определить операции plus, , times, negate и т. Д. Операции над булевыми объектами, не предполагая ничего о конкретном домене проекта).

вы можете определить неявный Numeric[Boolean] самостоятельно, если это имеет смысл для вашего проекта, но было бы лучше избегать использования неявного числового [T] для булевого типа.

3

Есть несколько incorrent предположений в вашем вопросе:

  1. AnyVal является супертипом всех примитивных типов и value classes. Наряду с AnyRef это одна из двух ветвей типа, корневая в стиле Any, что является истинным супертипом всего.
  2. Numeric тип не covariant, что означает, что существование Numeric[Int] не предполагает существования Numeric[AnyVal], что очень логично, если вы думаете на секунду. Целочисленные числа являются субдоменом Реальных чисел, но знание того, как умножать целые числа, не означает, что вы знаете, как умножать числа.
  3. Subtyping polymorphismis not directly related до restricted parametric polymorphism. Во-первых, в основном обрабатывается среда выполнения, а вторая - для компиляции. Они взаимодействуют очень специфически в scala.
  4. Не существует единственного места, где определены неявные значения. There are multiple places для каждого конкретного типа и места в коде.