【发布时间】:2010-06-21 22:37:44
【问题描述】:
我想实现一个类C 来存储各种数字类型的值以及布尔值。此外,我希望能够在类型之间对此类的实例进行操作,在必要时转换Int --> Double 和Boolean -> Int,即能够添加Boolean + Boolean、Int + Boolean、Boolean + Int、 Int + Double、Double + Double 等,尽可能返回最小的类型(Int 或 Double)。
到目前为止,我想出了这个:
abstract class SemiGroup[A] { def add(x:A, y:A):A }
class C[A] (val n:A) (implicit val s:SemiGroup[A]) {
def +[T <% A](that:C[T]) = s.add(this.n, that.n)
}
object Test extends Application {
implicit object IntSemiGroup extends SemiGroup[Int] {
def add(x: Int, y: Int):Int = x + y
}
implicit object DoubleSemiGroup extends SemiGroup[Double] {
def add(x: Double, y: Double):Double = x + y
}
implicit object BooleanSemiGroup extends SemiGroup[Boolean] {
def add(x: Boolean, y: Boolean):Boolean = true;
}
implicit def bool2int(b:Boolean):Int = if(b) 1 else 0
val n = new C[Int](10)
val d = new C[Double](10.5)
val b = new C[Boolean](true)
println(d + n) // [1]
println(n + n) // [2]
println(n + b) // [3]
// println(n + d) [4] XXX - no implicit conversion of Double to Int exists
// println(b + n) [5] XXX - no implicit conversion of Int to Boolean exists
}
这适用于某些情况 (1, 2, 3),但不适用于 (4, 5)。原因是类型从低到高隐式扩大,但不是相反。在某种程度上,方法
def +[T <% A](that:C[T]) = s.add(this.n, that.n)
不知何故需要有一个看起来像这样的合作伙伴方法:
def +[T, A <% T](that:C[T]):T = that.s.add(this.n, that.n)
但这不能编译有两个原因,首先编译器无法将this.n 转换为类型T(即使我们指定了视图绑定A <% T),其次,即使它能够转换this.n,在类型擦除之后,两个 + 方法变得不明确。
对不起,这太长了。任何帮助将非常感激!否则,我似乎必须明确写出所有类型之间的所有操作。如果我不得不添加额外的类型,它会变得很麻烦(Complex 是菜单上的下一个......)。
也许有人有另一种方法来实现这一切?感觉好像有一些简单的东西我忽略了。
提前致谢!
【问题讨论】: