2013-05-11 13 views
7

Scalaの型システムに既に組み込まれていることがわかっていましたが、NumericとFractionalおよびFractionalProxyを渡った後、私は方法を見つけられませんでした。ScalaのFloat、Double、およびBigDecimalを抽象化

数値モデルを抽象的に定義して、Doubles、Floats、およびBigDecimalsで動作し、FloatとDoubleの特殊化を行うことができます。

私はそれを仕事にしたようですが、多くの労力と定型文句があります。まず、そこにありますか(より)、より簡潔な方法で、より少ないkludgeyですか?次に、ビュー境界の暗黙的な変換にもかかわらず、私の値型の使用は、特殊化されたプリミティブ型のラップを防ぐ効果がありますか?

多くのありがとうございます。

object Model { 

    sealed trait Value[T] extends Any { //contains all the operations I use 
    def value : T; 
    def + (other : Value[T]) : Value[T]; 
    def/(other : Value[T]) : Value[T]; 
    def - (other : Value[T]) : Value[T]; 
    def * (other : Value[T]) : Value[T]; 
    def < (other : Value[T]) : Boolean; 

    def unary_- : Value[T]; 
    def abs : Value[T]; 
    } 

    implicit def unwrap[T](wrapped : Value[T]) : T = wrapped.value; 

    implicit class FloatValue(val value : Float) extends AnyVal with Value[Float] { 
    def + (other : Value[Float]) : Value[Float] = new FloatValue(value + other.value) 
    def/(other : Value[Float]) : Value[Float] = new FloatValue(value/other.value) 
    def - (other : Value[Float]) : Value[Float] = new FloatValue(value - other.value) 
    def * (other : Value[Float]) : Value[Float] = new FloatValue(value * other.value) 
    def < (other : Value[Float]) : Boolean = value < other.value; 

    def unary_- : Value[Float] = new FloatValue(-value); 
    def abs : Value[Float] = new FloatValue(math.abs(value)); 
    } 

    implicit class DoubleValue(val value : Double) extends AnyVal with Value[Double] { 
    // body of FloatValue repeated, but with Double replacing Float 
    } 

    implicit class BigDecimalValue(val value : BigDecimal) extends AnyVal with Value[BigDecimal] { 
    // body of FloatValue repeated, but with BigDecimal replacing Float 
    } 
} 

class GrossInterestModel[@specialized(Double,Float) T <% Value[T]](zero : T) { 
    def runModel(a : T, b : T) : T = { 
     //do math here, using the operations defined in Value above 
    } 
} 
+2

あなたはhttps://github.com/non/spireを見ていると、それはあなたのユースケースに合うかどうかを確認したい場合があります。 – huynhjl

+0

うわー、ありがとう。尖塔は驚くほどに見える。 –

+0

@huynhjlあなたは答えとしてあなたのコメントをコピーするべきでしょうか?私はそれをupvoteに満足しているだろう - スパイアは非常に興味深いですね。 –

答えて

2

スカラビルトインコレクションはすでにNumeric.scalaに類似のものが実装されています。それらを直接使用することができます。 (TraversableOnce.scalaから)のようないくつかの事は:

def sum[B >: A](implicit num: Numeric[B]): B = foldLeft(num.zero)(num.plus) 
+0

はい、私はこれらの抽象化をさまよっていますが、奇妙なことに、/のような通常の操作はそれらに定義されていません。 –