Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Comparisons with Scala's Numeric types?

How can one create a class which does math and comparisons on any numeric type in Scala?

One obvious approach:

import math.Numeric.Implicits._

class Ops[T : Numeric] {
    def add(a: T, b: T) = a + b
    def gt(a: T, b: T) = a > b
}

Earns me this...

Ops.scala:7: value > is not a member of type parameter T

Hmmm... we can do math with numeric types, but we can't compare them?

So let's also say that T is Ordered[T]...

class Ops[T <: Ordered[T] : Numeric] {
    def add(a: T, b: T) = a + b
    def gt(a: T, b: T) = a > b
}

That compiles. But try to use it?

new Ops[Int].gt(1, 2)

And I get...

Ops.scala:13: type arguments [Int] do not conform to class Ops's type parameter bounds [T <: Ordered[T]]

So how can I operate on some type which is both ordered and numeric?

like image 388
Tim Avatar asked Nov 17 '11 15:11

Tim


2 Answers

scala> import Ordering.Implicits._
import Ordering.Implicits._

scala> import Numeric.Implicits._
import Numeric.Implicits._

scala> class Ops[T : Numeric] {
     |   def add(a: T, b: T) = a + b
     |   def gt(a: T, b: T) = a > b
     | }
defined class Ops

scala> new Ops[Int].gt(12, 34)
res302: Boolean = false
like image 146
missingfaktor Avatar answered Sep 23 '22 06:09

missingfaktor


You have to import mkNumericOps and/or mkOrderingOps:

val num = implicitly[Numeric[T]]

or

class Ops[T](implicit num: Numeric[T]) 

then:

import num.{mkNumericOps,mkOrderingOps}

Now you can compare and calc with them. Perhaps that hels you for the first part of your question.

By the way: Ordered and Numeric works like that:

class Ops[T: Ordered: Numeric]
like image 25
Peter Schmitz Avatar answered Sep 20 '22 06:09

Peter Schmitz