2012-06-22 21 views
6

MathUtil adlı bir yardımcı program sınıfım var.Scala Sabit 0 ile sayısal başlat

ve buna benzer.

abstract class MathUtil(T:Numeric){ 
    def nextNumber(value:T) 
    def result():T 
} 

Ben herhangi bir sayısal tahmin ediyorum 0'a Özetle başlatmak zorunda, ben

private var sum:T = 0 

Şimdi deyimi ile ilgili bir sorun bu şekilde

class SumUtil[T:Numeric] extends MathUtil[T]{ 
    private var sum:T = 0 
    override def nextNumber(value:T){ 
    sum = sum + value 
    } 
    override def result():T = sum 
} 

alt sınıf Lets 0 temsil etmek için bir yol var. Bu sorunu nasıl çözebilirim? Eğer + kullanabilirsiniz bu durumda Numeric.Implicits._ içe sürece de, plus yöntemi için örnek ihtiyaç

class SumUtil[T: Numeric] extends MathUtil[T] { 
    private var sum: T = implicitly[Numeric[T]].zero 
    override def nextNumber(value: T) { 
    sum = implicitly[Numeric[T]].plus(sum, value) 
    } 
    override def result(): T = sum 
} 

Not:

+0

Yanıtlar için herkese teşekkürler. Bir takip sorumlum var. MathUtils türünde geçersiz kılınmış bir üyesi olan bir sınıfım olduğunu söyleyelim. – questionersam

cevap

11

Numeric type class instance istediğini yapar bir zero yöntemi vardır. Ayrıca bu durumda sözdizimi bağlı bağlamı kullanarak değil biraz kodunu temizleyebilir:

class SumUtil[T](implicit ev: Numeric[T]) extends MathUtil[T] { 
    import Numeric.Implicits._ 
    private var sum: T = ev.zero 
    override def nextNumber(value: T) { 
    sum = sum + value 
    } 
    override def result(): T = sum 
} 

Bu tam eşdeğerdir: bağlamla sınırlı sürümü bu örtük argüman için sadece sözdizimsel şeker, ancak gerekirse Bu argümanı açık bir şekilde kullanın (burada olduğu gibi, zero için), desugared versiyonunu yazmak için daha temiz buluyorum.

+0

Hey Travis! Seni buraya göndermeyi görmek güzel (bu Austin'den Ben). Ne yazık ki bu Sayısal şeyler, IMO, sadece tamamen fugly. Ayrıca cehennem kadar yavaş çıkıyor. IMO'nun bütün Scala imparatorluk mekanizması, sinsi, kırılgan ve anlaşılması zor bir şeydir ve yine de büyük ölçüde hacklenen @ specialized gibi başka bir şeye ihtiyacınız var. Sanırım C++ tarzı sınıf uzmanlığı kullanarak bu şeyler çok daha iyi ifade edilebilirdi. Bu, herkesin beklediği gibi, sadece s/int/double/ya da neyse, uygulamayı kopyalayarak. –

+0

@UrbanVagabond: Merhaba, Ben! "Sayısal" ın bir karmaşa olduğunu kabul ediyorum ve son kodları kendi kodumda kullandığımı hatırlayamıyorum, fakat kişisel olarak Scala'nın tip sınıflarını uyguladığı (aslında büyüdüğüm şey) problem olduğunu düşünmüyorum. beğenmek). –

0

Bunu başarmaya çalıştığınız şeyin biraz açıklığa kavuşturulması gerektiğini düşünüyorum. Scala belgelerinden, Sayısal türün kendisi jeneriktir. Burada hissettiğim şey, aslında istediğin şey, kodunuzun şu anda açıkladığı Numeric [_] alt sınıfları yerine herhangi bir Sayısal [T] 'yi işleyen bir MathUtil soyutlamasını tanımlamaktır. İşte bu varsayımı temel alan doğru uygulama.

//Define a MathUtil that works on any T 
abstract class MathUtil[T] { 
    def nextNumber(value: T) 
    def result(): T 
} 

//Define a SumUtil that works on any T that has an available Numeric 
//Will search implicit scope, but also allows you to provide an 
//implementation if desired. 
class SumUtil[T](implicit n: Numeric[T]) extends MathUtil[T] { 
    //Use the Numeric to generate the zero correctly. 
    private var sum: T = n.zero 
    //Use the Numeric to correctly add the sum and value 
    override def nextNumber(value: T) = sum = n.plus(sum, value) 
    override def result(): T = sum 
} 

//Test that it works. 
val a = new SumUtil[Int] 
val b = List(1,2,3) 

b map a.nextNumber //Quick and dirty test... returns a meaningless list 
println(a.result) //Does indeed print 6 

Yukarıdakiler ne yapmak istemiyorsa, lütfen sorunuzu açıklığa kavuşturun.

+0

Haklı değilsiniz ... '[T: Sayısal]' bir bağlama bağlı ve '[T] 'ye (örtük n: Sayısal [T])' genişleyecektir, bu nedenle kodunuz OP’ler ile hemen hemen aynıdır. n.zero için. – drexin