2010-02-16 47 views
6

पर बाधा मैं स्कैला के लिए बहुत नया हूं।स्कैला: जेनेरिक क्लास प्रकार

मैं एक जेनेरिक मैट्रिक्स क्लास "क्लास मैट्रिक्स [टी]" को कार्यान्वित करना चाहता हूं। टी पर एकमात्र बाधा यह होनी चाहिए कि टी को "+" और "*" मोथोड/फ़ंक्शन लागू करना चाहिए। मैं यह कार्य कैसे करूं?

उदाहरण के लिए मैं Int, Double, और अपने स्वयं के परिभाषित प्रकारों का उपयोग करने में सक्षम होना चाहता हूं उदा। परिसर

मैं पंक्तियों के साथ कुछ सोच रहा था:

class Matrix[T <: MatrixElement[T]](data: Array[Array[T]]) { 
    def *(that: Matrix) = ..// code that uses "+" and "*" on the elements 
} 
abstract class MatrixElement[T] { 
    def +(that: T): T 
    def *(that: T): T 
} 
implicit object DoubleMatrixElement extends MatrixElement[Double]{ 
    def +(that: Double): Double = this + that 
    def *(that: Double): Double = this * that 
} 
implicit object ComplexMatrixElement extends MatrixElement[Complex]{ 
    def +(that: Complex): Complex = this + that 
    def *(that: Complex): Complex = this * that 
} 

सब कुछ प्रकार की जाँच करता लेकिन मैं अभी भी एक मैट्रिक्स का दृष्टांत नहीं कर सकते। क्या मैं एक अंतर्निहित निर्माता हूं? मैं इसे बनाने के बारे में कैसे जाउंगा? या मैं अपनी विधि के बारे में पूरी तरह से गलत हूँ?

अग्रिम Troels

उत्तर

4

अंत में जवाब मिल गया :-) मुझे लगता है कि मैं अपने पहले प्रयास में बंद है कि अब तक नहीं था । यहाँ यह जाता है: (स्केला 2.8 के लिए लिखा)

trait MatrixElement[T] { 
    def +(that: T): T 
    def *(that: T): T 
} 

object MatrixElement { 
    implicit def intToMatrixElement(x : Int) = new MatrixElement[Int] { 
     def +(y : Int) = x + y 
     def *(y : Int) = x * y 
    } 
    implicit def doubleToMatrixElement(x : Double) = new MatrixElement[Double] { 
     def +(y : Double) = x + y 
     def *(y : Double) = x * y 
    } 
    implicit def complexToMatrixElement(x : Complex) = new MatrixElement[Complex] { 
     def +(y : Complex) = x + y 
     def *(y : Complex) = x * y 
    } 
} 

class Matrix[T <% MatrixElement[T] : ClassManifest ](d: Array[Array[T]]) { 
    def *(that: Matrix) = ..// code that uses "+" and "*" on the elements 
} 

अब मैं की तरह सामान कर सकते हैं:

scala> new Matrix(Array(Array(1,0),Array(0,1))) 
res0: Matrix[Int] = 
1 0 
0 1 

scala> new Matrix(Array(Array(new Complex(0),new Complex(1)),Array(new Complex(1),new Complex(0)))) 
res9: Matrix[Complex] = 
(0.0,0.0i) (1.0,0.0i) 
(1.0,0.0i) (0.0,0.0i) 
4

धन्यवाद आप उस के लिए स्काला 2.8 के लिए Numeric उपयोग कर सकते हैं। यह here का वर्णन करता है। यह MatrixElement और इसके कार्यान्वयन की जगह लेंगे:

class Matrix[T : Numeric](data: Array[Array[T]]) { 
    def *(that: Matrix[T]) = // 
} 
+0

मैं संख्यात्मक माना जाता है। लेकिन मैं वास्तव में नहीं देखता कि यह मेरे अपने प्रकार के लिए कैसे काम करेगा। परिसर। मुझे लगता है कि कॉम्प्लेक्स को संख्यात्मक विस्तार करने की आवश्यकता होगी। सबसे पहले मुझे केवल + और * की तुलना में कई और तरीकों को लागू करने की आवश्यकता होगी। इन आदेशों में से - जहां तक ​​मुझे पता है कि जटिल संख्याओं पर कोई सख्त आदेश नहीं है। मुख्य बिंदु यह है कि मुझे किसी भी प्रकार पर काम करने के लिए मैट्रिक्स की आवश्यकता है जो कि पूर्ण तरीके से भरें + और * लागू किए गए हैं। –

+0

यदि आपको केवल + और * की आवश्यकता है तो इसे लागू करने के लिए कई तरीके हैं। लेकिन आप अभी भी इन दो विधियों के साथ न्यूमेरिक जैसे कुछ बना सकते हैं। यह दो बहुत काम होना चाहिए। (और शायद बाद में वापस आएं और इसे सार्थक के साथ न्यूमेरिक के साथ प्रतिस्थापित करें।) –

+1

@ ट्रॉल्स आप हमेशा वास्तविक भाग से ऑर्डर कर सकते हैं, या सभी तुलनाओं के लिए केवल सादा वापसी "0" कर सकते हैं। और आप हमेशा 'त्रुटि "(अपरिभाषित विधि") के साथ विधियों को "कार्यान्वित" कर सकते हैं। ध्यान दें, हालांकि, 'कॉम्प्लेक्स' _extend_ 'संख्यात्मक 'नहीं होगा। इसके बजाय, 'संख्यात्मक [जटिल] 'का एक उदाहरण होगा। –

2

यहाँ है Numeric समाधान इस तरह दिखाई देंगे:

// ': Numeric[T]' adds an implicit parameter to the constructor, 
// which allows T to be used in arithmetic expressions. 
class Matrix[T: Numeric](val data: Array[Array[T]]) { 
    def *(that: Matrix[T]) = { 
     val nt = implicitly[Numeric[T]] 
     import nt._ // This imports an Implicit View to allow operator syntax 

     this.data(0)(0) * that.data(0)(0) 
     // etc 
    } 
} 
+0

'टी: न्यूमेरिक [टी]' 'टी: न्यूमेरिक 'होना चाहिए। क्या आप इसे आरईपीएल के बिना लिखते हैं? :-) –

+0

ओह! मुझे पकड़ा :) – retronym

संबंधित मुद्दे