私は C++ から来て、scala の型システムに頭を悩ませようとしています。
次の C++ テンプレート クラスを検討してください。
template<class T>
class Point2
{
Point2( T x, T y ) :
x(x),
y(y)
{}
T x;
T y;
Point2<T> operator+( Point<T> const& other ) const
{
return Point<T>(x+other.x, y+other.y);
}
T sumComponents() const { return x+y; }
}
Point2<Double> p0(12.3, 45.6)
Point2<Double> p1(12.3, 45.6)
Point2<Double> p = p1+p2
Double d = p1.sumComponents()
私はこのようなものを書きたいと思っています:
case class Point2[ T ] (x:T, y:T) {
def +() Point2[T]: = x+y
def sumComponents() T: = x+y
}
または、(コンパイルに問題があるため)、
trait Addable[T] { // Require T supports the + operatory
def +( that:T ):T
}
case class Point2[ T<:Addable[T] ] (x:T, y:T) {
def +() Point2[T]: = x+y
def sumComponents() T: = x+y
}
Addable を拡張するために Double を要求できないため、これも同様に問題があります。
一般的に、scala の型システムは、私がよく理解していない一連の制約で機能することがわかっています。
上記をscalaで実装する慣用的な方法は何ですか?
また、C++ テンプレート プログラマーが scala のジェネリックの制限を理解する正しい方法は何ですか? (なぜscalaでこれを行うことができないのですか?例えば、インスタンス化される前にジェネリックがコンパイルされるからですか?)