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)
しかし、これは 2 つの理由でコンパイルされません。1 つ目は、コンパイラがthis.n
型に変換できないことT
(ビュー バウンドを指定A <% T
しても)、2 つ目は、変換できたとしても、this.n
型消去後に 2 つの+
メソッドがあいまいになることです。
すみません、これはとても長いです。どんな助けでも大歓迎です!それ以外の場合は、すべてのタイプ間のすべての操作を明示的に書き出す必要があるようです。そして、私が余分なタイプを追加しなければならなかった場合、それは毛むくじゃらになります(Complex
メニューの次の...)。
たぶん、誰かがこれらすべてを完全に達成する別の方法を持っているのでしょうか? 私が見落としている単純なものがあるように感じます。
前もって感謝します!