मैं विभिन्न संख्यात्मक प्रकारों के साथ-साथ बूलियन के मूल्यों को संग्रहीत करने के लिए कक्षा C
को लागू करना चाहता हूं। इसके अलावा, मैं प्रकार के बीच, इस वर्ग के उदाहरण पर संचालित करने के लिए, परिवर्तित करने में सक्षम होना चाहते हैं जहां आवश्यक Int --> Double
और Boolean -> Int
, यानी,, छोटी संभव लौटने Boolean + Boolean
, Int + Boolean
, Boolean + Int
, Int + Double
, Double + Double
आदि जोड़ने के लिए सक्षम होने के लिए टाइप करें (Int
या Double
) जब भी संभव हो।संख्यात्मक प्रकारों के बीच अंकगणित की अनुमति देने के लिए निहित रूपांतरण कैसे सेट करें?
अब तक मैं इस के साथ आया था:
abstract class SemiGroup[A] { def add(x:A, y:A):A }
class C[A] (val n:A) (implicit val s:SemiGroup[A]) {
def +[T <% A](that:C[T]) = s.add(this.n, that.n)
}
object Test extends Application {
implicit object IntSemiGroup extends SemiGroup[Int] {
def add(x: Int, y: Int):Int = x + y
}
implicit object DoubleSemiGroup extends SemiGroup[Double] {
def add(x: Double, y: Double):Double = x + y
}
implicit object BooleanSemiGroup extends SemiGroup[Boolean] {
def add(x: Boolean, y: Boolean):Boolean = true;
}
implicit def bool2int(b:Boolean):Int = if(b) 1 else 0
val n = new C[Int](10)
val d = new C[Double](10.5)
val b = new C[Boolean](true)
println(d + n) // [1]
println(n + n) // [2]
println(n + b) // [3]
// println(n + d) [4] XXX - no implicit conversion of Double to Int exists
// println(b + n) [5] XXX - no implicit conversion of Int to Boolean exists
}
यह कुछ मामलों के लिए काम करता है (1, 2, 3) लेकिन ऐसा नहीं करता के लिए (4, 5)। इसका कारण यह है कि नीचे से उच्च तक के प्रकार की अंतर्निहित चौड़ाई है, लेकिन दूसरी तरफ नहीं।
def +[T, A <% T](that:C[T]):T = that.s.add(this.n, that.n)
लेकिन यह है कि दो कारणों के लिए संकलन नहीं करता है, सबसे पहले कि संकलक को this.n
परिवर्तित नहीं कर सकते: एक तरह से, विधि
def +[T <% A](that:C[T]) = s.add(this.n, that.n)
किसी भी तरह एक साथी विधि है कि कुछ ऐसा दिखाई देगा की जरूरत में T
टाइप करें (भले ही हम व्यू बाउंड A <% T
निर्दिष्ट करते हैं), और दूसरी बात यह है कि अगर this.n
को कनवर्ट करने में सक्षम थे, तोविधियों को अस्पष्ट करने के बाद टाइप करें।
क्षमा करें यह बहुत लंबा है। कोई भी सहायताकाफी प्रशंसनीय होगी! अन्यथा ऐसा लगता है कि मुझे सभी प्रकार के बीच सभी परिचालनों को स्पष्ट रूप से लिखना है। और अगर मुझे अतिरिक्त प्रकार जोड़ना पड़ता है तो यह बालों वाली हो जाएगी (Complex
मेनू पर अगला है ...)।
शायद किसी को यह सब हासिल करने का एक और तरीका है? ऐसा लगता है कि कुछ सरल है जो मैं देख रहा हूं।
अग्रिम धन्यवाद!
ahha! मैं देखता हूं कि यह कैसे काम करता है - धन्यवाद! 'बूलियन 'जोड़ना आसान हो गया, वास्तव में, और' संख्यात्मक 'के एलयूबी को' परिसर 'के लिए बदलना बहुत मुश्किल नहीं होगा। मैं उत्सुक हूं - ऐसा लगता है कि आपने यह समाधान अपनी आस्तीन को संभाला है, इस समस्या में आप किस संदर्भ में आए थे? इसके अलावा मैंने इस समाधान के प्रदर्शन की जांच करने की कोशिश की और दस लाख 'इंट]' का योग दस लाख से अधिक धीमा लगता है ... इंटेल के बारे में कोई विचार ... कैसे शुरू करना है इसे अनुकूलित करें? – ostolop
आईआरसी पर @extempore के साथ चर्चा के दौरान मैंने इस के आसपास खेला, यह मेरी एक विशेष समस्या को हल नहीं कर रहा था। 5x ओवरहेड संकेत पर विचार करने में बहुत बुरा नहीं लगता है। आप 'unify' विधि का उपयोग करने के बजाय सीधे 'wc.a2b' और' wc.a2c' को कॉल कर सकते हैं। वर्तमान में 'न्यूमेरिक # प्लस' के इनपुट और आउटपुट को बॉक्स किया गया है, उम्मीद है कि स्कैला के भविष्य के संस्करण को उस समस्या को दूर करने का एक तरीका मिलेगा। – retronym
@ वास्तविकता वास्तव में ... मैंने उस चर्चा की शुरुआत की। :-) –