Int和Char scala插值(泛型和上界)

Int和Char scala插值(泛型和上界),scala,generics,Scala,Generics,我正在使用scala中的泛型和上界,我面临以下问题: 假设我有以下函数(其中我只期望Int或Char): 我希望有一个更好的压缩表单,如: def foo2[T >: Int with Char <: AnyVal](tuple: (T, T)) = (tuple._1 to tuple._2).toArray def foo2[T>:Int with Char自己调用numeriRange.inclusive会更容易,而不是尝试整理使用to语法所需的隐式和类型约束。如果我们需要

我正在使用scala中的泛型和上界,我面临以下问题:

假设我有以下函数(其中我只期望Int或Char):

我希望有一个更好的压缩表单,如:

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

def foo2[T>:Int with Char自己调用
numeriRange.inclusive
会更容易,而不是尝试整理使用
to
语法所需的隐式和类型约束。如果我们需要隐式
积分
,我们将知道如何用一步构造范围(由
Integral
实例提供)。我们还需要
ClassTag[a]
来创建
数组

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)
其他失败(如果您希望它们使用类型约束):

scala>foo2((1升,10升))
:19:错误:找不到参数int:Integral[AnyVal]的隐式值
食物2((1升,10升))
^

下面是一个相对可怕的签名,您可以使用它来获取
(tup.\u 1到tup.\u 2)。在您的实现上排列
语法:

def foo[T 
  <% RangedProxy[T]{ type ResultWithoutStep <: TraversableOnce[T] } 
  : ClassTag
](tup: (T, T))
不幸的是,对于这个特定的问题,类型类方法有点麻烦,但是如果您关注
隐式val xFooable
,您会发现它类似于以下内容:

// unfortunately this doesn't work due to type erasure on the JVM,
// which is why we've resorted to typeclasses as above
def foo(tup: (Int, Int)) = ...
def foo(tup: (Char, Char)) = ...

我不太理解
T
的下界,称为
Int with Char
?这是什么意思?对不起,编辑过。我想你想要一个联合类型。请看@YuvalItzchakov I更新了foo2的定义。@ChrisShain我试图避免有两个大小写的冗长,而不是保证T是Int或Char(我可以假设它将只是这两种类型中的一种)将
:Int和Char
添加到我的中会将其限制为
Int
Char
,尽管没有什么实际理由强制执行它,因为
Integral
防止客户端代码使用另一种类型,否则会破坏它。有一点,最后的数组还应该包含第二个Char/Int:
foo2((1,10))
应返回
Array[Int]=Array(1,2,3,4,5,6,7,8,9,10)
@jalv1039更新为使用
numeriRange.inclusive
def foo[T 
  <% RangedProxy[T]{ type ResultWithoutStep <: TraversableOnce[T] } 
  : ClassTag
](tup: (T, T))
sealed trait Fooable[T] extends ((T, T) => Array[T])
object Fooable {
  private def impl[T](f: (T, T) => Array[T]) = 
    new Fooable[T]{ def apply(min: T, max: T): Array[T] = f(min, max) }
  implicit val intFooable = impl[Int]{ (i,j) => (i to j).toArray }
  implicit val charFooable = impl[Char]{ (a,b) => (a to b).toArray }
}
def foo[T: Fooable](tup: (T, T)) = implicitly[Fooable[T]].apply(tup._1, tup._2)
// unfortunately this doesn't work due to type erasure on the JVM,
// which is why we've resorted to typeclasses as above
def foo(tup: (Int, Int)) = ...
def foo(tup: (Char, Char)) = ...