В Scala я хотел бы иметь возможность писать универсальные классы, использующие такие операторы, как >, /, * и т. д., но я не вижу, как ограничить T так, чтобы это работало.
Я изучал ограничение T с помощью Ordered[T], но это, похоже, не работает, поскольку его расширяет только RichXXX (например, RichInt), а не Int и т. д. Я также видел Numeric[T], это доступно только в Scala 2.8?
Вот конкретный пример:
class MaxOfList[T](list: List[T] ) {
def max = {
val seed: Option[T] = None
list
.map( t => Some(t))
// Get the max
.foldLeft(seed)((i,m) => getMax(i,m) )
}
private def getMax(x: Option[T], y: Option[T]) = {
if ( x.isDefined && y.isDefined )
if ( x > y ) x else y
else if ( x.isDefined )
x
else
y
}
}
Этот класс не будет компилироваться, потому что многие T не поддерживают > и т.д.
Мысли?
На данный момент я использовал трейт MixIn, чтобы обойти это:
/** Defines a trait that can get the max of two generic values
*/
trait MaxFunction[T] {
def getMax(x:T, y:T): T
}
/** An implementation of MaxFunction for Int
*/
trait IntMaxFunction extends MaxFunction[Int] {
def getMax(x: Int, y: Int) = x.max(y)
}
/** An implementation of MaxFunction for Double
*/
trait DoubleMaxFunction extends MaxFunction[Double] {
def getMax(x: Double, y: Double) = x.max(y)
}
Что, если мы изменим исходный класс, может быть смешано во время создания экземпляра.
P.S. Митч, вдохновленный вашим переписыванием getMax, вот еще:
private def getMax(xOption: Option[T], yOption: Option[T]): Option[T] = (xOption,yOption) match {
case (Some(x),Some(y)) => if ( x > y ) xOption else yOption
case (Some(x), _) => xOption
case _ => yOption
}