Reputation: 8235
I want to write a function vaguely like:
def doubleit[A](a: A): A = {a + a}
But I want 'A' to mean any kind of Int, but not anything. Is there a way to give Scala a clue about what I want 'A' to mean?
def doubleit[A <: Int](a: A): A = {a + a}
is rejected by the compiler.
Upvotes: 1
Views: 189
Reputation: 14224
In plain Scala you can use type class Integral
:
scala> def doubleit[A : Integral](a: A): A = implicitly[Integral[A]].plus(a, a)
doubleit: [A](a: A)(implicit evidence$1: Integral[A])A
scala> doubleit(2)
res0: Int = 4
scala> doubleit(BigInt(4))
res1: scala.math.BigInt = 8
Another possible syntax:
def doubleit[A](a: A)(implicit ev: Integral[A]): A = ev.plus(a, a)
ev
is a commonly used name for those implicit parameters.
It is also possible to use normal operations like +
, -
, etc. instead of plus
and minus
:
def doubleit[A](a: A)(implicit ev: Integral[A]): A = {
import ev._
a + a
}
Or as per suggestion by @KChaloux, import from Integral.Implicits
beforehand:
import Integral.Implicits._
def doubleit[A : Integral](a: A): A = a + a
If you want the function to support not only integers, but also Double
s, BigDecimal
s, etc. you can use Numeric
instead of Integral
:
import Numeric.Implcits._
def doubleit[A : Numeric](a: A): A = a + a
Explanation:
Writing [A : Integral]
makes the function receive an implicit parameter of type Integral[A]
. The implicits for all basic integral types are already defined in Scala, so you can use it with Int
or BigInt
straightaway. It is also possible to define new Integral
types by defining a new implicit variable of type Integral[NewIntegralType]
and implementing all the necessary methods.
The call to implicitly[Integral[A]]
returns this implicit instance of Integral[A]
which has method plus
for addition, and other methods for performing other operations on integrals.
Upvotes: 6