Это работает:
def mean[T : Numeric](xs: Iterable[T]): T = implicitly[Numeric[T]] match {
case num: Fractional[_] => import num._; xs.sum / fromInt(xs.size)
case num: Integral[_] => import num._; xs.sum / fromInt(xs.size)
case _ => sys.error("Undivisable numeric!")
}
Итак, давайте сделаем некоторые пояснения.Во-первых, Numeric
должен использоваться в шаблоне класса типов.То есть вы не говорите, что тип T
является или может быть преобразован в Numeric
.Вместо этого Numeric
предоставляет методы над типом T
.Одним из таких примеров является num.fromInt
.
Далее, Numeric
не предоставляет общего оператора деления.Вместо этого нужно выбирать между Fractional
и Integral
.Здесь я сопоставляю Numeric[T]
, чтобы различать оба.
Обратите внимание, что я не использую T
в совпадении, потому что Scala не может проверять параметры типа в совпадениях, поскольку они стираются.Вместо этого я использую _
, и Scala выводит правильный тип, если это возможно (как здесь).
После этого я импортирую num._
, где num
равно Fractional
илиIntegral
.Это приносит некоторые неявные преобразования в контекст, которые позволяют мне делать такие вещи, как прямой вызов метода /
.Если бы я не выполнял этот импорт, я был бы вынужден написать следующее:
num.div(xs.sum, num.fromInt(xs.size))
Обратите внимание, что мне не нужно передавать неявный параметр в xs.sum
, поскольку он уже неявно доступен всфера.
Наверное, все.Я что-то пропустил?