jalv1039 jalv1039 - 24 days ago 8
Scala Question

Int and Char scala interpolation (generics and upper bounds)

I am playing with generics and upper bounds in scala and I am facing the following problem:

Let's say I have the following function (where I only expect either Int or Char):

def foo[T](tuple: Tuple2[T, T]) = tuple match {
case Tuple2(x: Int, y: Int) => (x to y).toArray
case Tuple2(x: Char, y: Char) => (x to y).toArray
}


I would expect to have a better and compressed form like:

def foo2[T >: Int with Char <: AnyVal](tuple: (T, T)) = (tuple._1 to tuple._2).toArray


But this is definitely not working.

Any ideas?

Answer

It would be easier to simply call NumericRange.inclusive yourself, rather than try to sort out the implicits and type constraints that would be needed to use the to syntax. If we require an implicit Integral, we'll know how to construct the range with a step of one (provided by the Integral instance). We'll also need a ClassTag[A] to create the Array generically:

import scala.reflect.ClassTag
import scala.collection.immutable.NumericRange

def foo2[A >: Int with Char : ClassTag](tuple: (A, A))(implicit int: Integral[A]) = 
   NumericRange.inclusive(tuple._1, tuple._2, int.one).toArray

scala> foo2(('a', 'z'))
res13: Array[Char] = Array(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z)

scala> foo2((1, 10))
res14: Array[Int] = Array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)

Others fail (if you want them to with the type constraint):

scala> foo2((1L, 10L))
<console>:19: error: could not find implicit value for parameter int: Integral[AnyVal]
       foo2((1L, 10L))
           ^
Comments