Podejrzewałem, że będzie wsparcie dla tego już wbudowanego w system typu Scala, ale po przejściu przez Numeric i Fractional oraz FractionalProxy, nie byłem w stanie znaleźć sposobu.Abstrahowanie przez Float, Double i BigDecimal w Scala
Chcę zdefiniować abstrakcyjnie model liczbowy, aby mógł pracować z podwójnymi, zmiennymi i dużymi znakami, ze specjalizacjami dla Float i Double.
Wydaje mi się, że sprawdziło się to, ale przy dużym wysiłku i gotowości. Po pierwsze, czy istnieje (proszę?) Mniej kludgey, bardziej zwięzły sposób? Po drugie, czy moje użycie typów wartości skutecznie powstrzyma zawijanie specjalistycznych typów pierwotnych, pomimo niejawnych konwersji granic widoku?
Wielkie dzięki.
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
}
}
Możesz zajrzeć na https://github.com/non/spire i sprawdzić, czy pasuje do Twojego przypadku użycia. – huynhjl
wow, dzięki. iglica wygląda niesamowicie. –
@huynhjl Może powinieneś skopiować swój komentarz jako odpowiedź. Byłbym szczęśliwy, gdyby go głosowałem - Spire wygląda bardzo interesująco. –