2013-05-11 4 views
7

이미 스칼라 유형 시스템에 내장 된 지원이있을 것이라고 생각했지만 Numeric 및 Fractional 및 FractionalProxy를 통과 한 후에는 방법을 찾을 수 없었습니다.스칼라에서 Float, Double 및 BigDecimal을 추상화하는 방법

나는 Float과 Double을 전문으로하여 Doubles, Floats 및 BigDecimals와 함께 작업 할 수 있도록 추상적으로 수치 모델을 정의하려고합니다.

나는 그것을 일하게 만들었지 만, 많은 노력과 보편적 인 것으로 보인다. 첫째, 거기에 (제발?) 적은 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 기뻐할 것이다 - Spire는 매우 흥미있게 보인다. –

답변

2

스칼라 내장 수집은 이미 Numeric.scala에서 비슷한 일을 구현했습니다. 직접 사용할 수 있습니다. (TraversableOnce.scala에서) 같은 일부 것은 :

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

예, 저는 이러한 추상화를 방황했지만 이상하게도 /와 같은 일반적인 작업은 정의되지 않았습니다. –

관련 문제