Scalaでは、>、/、*などの演算子を使用するジェネリッククラスを記述できるようにしたいと思いますが、これが機能するようにTを制約する方法がわかりません。
Ordered [T]で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)
}
元のクラスを変更すると、インスタンス化時にミックスインできます。
getMaxの書き直しに触発されたPSMitchは、次のとおりです。
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
}