Writing a generic mean function in Scala

前端 未结 4 1492
轮回少年
轮回少年 2020-12-14 22:41

I\'m trying to write a generic mean function that operates on an Iterable that contains numeric types. It would operate, say, on arrays, as so:

val rand = n         


        
4条回答
  •  别那么骄傲
    2020-12-14 23:27

    This works:

    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!")
    }
    

    So, let's make some explanations. First, Numeric must be used in type class pattern. That is, you don't say a type T is, or can be converted into, Numeric. Instead, Numeric provides methods over a type T. One such example is num.fromInt.

    Next, Numeric does not provide a common division operator. Instead, one must choose between Fractional and Integral. Here, I'm matching on Numeric[T] to distinguish between both.

    Note that I don't use T on the match, because Scala cannot check for type parameters on matches, as they are erased. Instead, I use _, and Scala infers the correct type if possible (as it is here).

    After that, I'm importing num._, where num is either Fractional or Integral. This brings some implicit conversions into context that let me do stuff like calling the method / directly. If I did not do that import, I'd be forced to write this:

    num.div(xs.sum, num.fromInt(xs.size))
    

    Note that I do not have to pass the implicit parameter to xs.sum, since it is already implicitly available in the scope.

    I guess that's it. Did I miss anything?

提交回复
热议问题