A Numeric[A]
, как правило, один экземпляр, который дает доступ к арифметическим операциям по типу A
. Он будет содержит def plus(x: A, y: A): A
, а не def add(x: A): A
, которая будет иметь некоторый this
типа А.
Это сродни в Java Comparator
(или в Scala Ordering
), который имеет Compare(T o1, T o2)
, а не Java Comparable
(Скала Ordered
), который имеет CompareTo(T other)
. Такие типы с неявно доступными реализациями singleton обычно называются степенными классами после тесно связанной функции на языке Haskell.
Поэтому вы не хотите конвертировать A
в Numeric[A]
, вы просто хотите получить Numeric[A]
. Ваша подпись должна быть
def foo[A](x: A, y: A)(implicit numeric: Numeric[A])
Существует ярлык для того, что
def foo[A: Numeric](x: A, y: A)
В методе foo
, вы можете сделать numeric.plus(x,y)
, но если вы import scala.math.Numeric._
, вы получаете некоторые магии и многое другое удобный x + y
.
Что касается вопроса в комментарии: еще не было изменение языка программирования, так как в Скале (который находится на против 2.8)?
Синтаксис [A: Numeric]
, названный context bound
, был введен на позднем языке, я не уверен на 100%, но я считаю, что он не был доступен в 2.8. Но это всего лишь ярлык для аргумента implicit Numeric[A]
, который был возможен в 2,8 (Numeric
был доступен, только что введенный в 2.8) и должен был использоваться, как показано выше в то время. Кроме того, не было языкового изменения.
Однако в ранние времена Скале, это было более распространено использование «представления», то есть неявные преобразования, а не классы типов, то есть использовать такие типы, как Comparable
/Ordered
, а не Comparator
/Ordering
/Numeric
.
Для таких типов вы обычно используете верхнюю границу A <: Ordered[A]
. Однако это может быть чересчур слишком ограничительным, поскольку оно будет работать только в том случае, если разработчику было предвидение для реализации Ordered
. Вы можете обойти это, но требуя, чтобы A
мог быть преобразован в Упорядоченный [A], поэтому implicit A => Ordered[A]
.
Раньше был ярлык для этого, [A <% Ordered[A]]
, называемый вид связан. Тем не менее, он устарел, и в то время как представления все еще возможны (implicit A => Ordered[A]
), классные категории очень предпочтительны. Есть много причин для этого, например .:
- , имеющие функции преобразования в неявной области будет действовать как неявные слепки и довольно опасны
- классов типов являются более мощными. Например, вы можете иметь экземпляр
Numeric[A]
, даже если у вас нет экземпляров A
, и поэтому получите zero
типа A
. если вы вызываете sum
в список, и список пуст, Numeric
по-прежнему доступен, и вы можете получить zero
. если Numeric
было что-то реализовано A
, даже если оно было сделано zero
, у вас не было бы экземпляра, чтобы позвонить ему. Еще один пример: typeclass может использоваться как завод, опять же, когда у вас нет экземпляра построенного типа (пока), как показано в this answer.
Цитирую Одерски (discussing deprecation):
контекста оценки, по существу, замена зрения границ. Это Что мы должны были сделать с самого начала, но мы не знали лучше тогда
Спасибо. Have Typesafe изменил синтаксис для implicits, когда я передрабил фрагмент кода из книги Programming in Scala, в которой была определена функция, как я сделал в своем сообщении. –
ответил в ответе выше –