2017-04-12 10 views
6

मैं एक सामान्य भारित औसत फ़ंक्शन लिखने की कोशिश कर रहा हूं। मैं मूल्यों और वजन के समान मूल्यों की आवश्यकताओं को आराम करना चाहता हूं। यानी, मैं कहना के दृश्यों का समर्थन करना चाहते: (value:Float,weight:Int) और (value:Int,weight:Float) तर्क और बस नहीं: (value:Int,weight:Int)स्कैला: जेनेरिक फ़ंक्शन गुणा को विभिन्न प्रकारों के अंकन

ऐसा करने के लिए, मैं पहली बार एक समारोह है कि दो सामान्य संख्यात्मक मानों का उपयोग करके अपने उत्पाद रिटर्न लागू करने के लिए की जरूरत है।

def times[A: Numeric, B: Numeric](x: B, y: A): (A, B) : ??? = {...} 

हस्ताक्षर लेखन और वापसी प्रकार के बारे में सोच, मुझे पता है कि मैं संख्यात्मक वापसी प्रकार का निर्धारण करने के लिए पदानुक्रम के कुछ प्रकार परिभाषित करने की जरूरत बना दिया। यानी x:Float*y:Int=z:Float, x:Float*y:Double=z:Double

अब, संख्यात्मक वर्ग केवल उसी प्रकार के तर्कों के लिए संचालन plus, times आदि परिभाषित करता है। मुझे लगता है कि मैं एक प्रकार लागू करने के लिए की आवश्यकता होगी: कि मैं के रूप में मेरे बार समारोह में लिख सकते हैं

class NumericConverter[Numeirc[A],Numeric[B]]{ 
type BiggerType=??? 
} 

तो:

def times[A: Numeric, B: Numeric](x: B, y: A): (A, B) : 
NumericConverter[Numeirc[A],Numeric[B]].BiggerType= {...} 

और "बड़ा एक" से "छोटे प्रकार" बदलने और यह फ़ीड times() पर।

क्या मैं सही रास्ते पर हूं? मैं BiggerType को "कार्यान्वित" कैसे करूं?

type myType = if(...) Int else Float 

के रूप में है कि, गतिशील रूप से मूल्यांकन किया जाता है यह इतना worn't काम:

स्पष्ट रूप से मैं की तरह कुछ नहीं कर सकते।

मैं समझता हूँ कि मैं Scalaz, आदि का उपयोग करते हुए यह करने के लिए सक्षम हो सकता है, लेकिन यह एक शैक्षिक व्यायाम है और मैं समझ कैसे एक समारोह है कि स्थिर एक प्रकार तर्क प्रकारों के आधार पर रिटर्न लिखने के लिए करना चाहते हैं।

यह करने के लिए स्वतंत्र महसूस करें कि ऐसा करने का एक आसान तरीका है या नहीं।

अद्यतन:

यह है कि क्या मैं इसे के साथ आया है।

abstract class NumericsConvert[A: Numeric,B: Numeric]{ 

    def AisBiggerThanB: Boolean 

    def timesA=new PartialFunction[(A,B), A] { 
     override def isDefinedAt(x: (A, B)): Boolean = AisBiggerThanB 
     override def apply(x: (A, B)): A = implicitly[Numeric[A]].times(x._1, x._2.asInstanceOf[A]) 
    } 

    def timesB=new PartialFunction[(A,B), B] { 
     override def isDefinedAt(x: (A, B)): Boolean = !AisBiggerThanB 
     override def apply(x: (A, B)): B = implicitly[Numeric[B]].times(x._1.asInstanceOf[B], x._2) 
    } 
    def times: PartialFunction[(A, B), Any] = timesA orElse timesB 
} 

def times[A: Numeric, B: Numeric](x: B, y: A)= implicitly[NumericsConvert[A,B]].times(x,y) 

जो मूर्ख है, क्योंकि मुझे लगता है कि times की वापसी प्रकार अब Any है उल्लेख करने के लिए दोनों

IntDouble extends NumericsConvert[Int,Double] 

और

DoubleInt extends NumericsConvert[Double,Int] 

नहीं के लिए implicits बनाना पड़ेगा, लेकिन परवाह किए बिना, मुझे अपने समय के कार्यों के लिए त्रुटियां मिल रही हैं। मैंने सोचा कि अगर मैं समाधान पर पहुंचने में मदद कर सकता हूं तो मैं इसे यहां जोड़ दूंगा। तो साइड सवाल: मैं कैसे एक वर्ग/समारोह के संदर्भ बाध्य प्रकारों को दूसरे में पास कर सकता हूं जैसे कि मैं में करने की कोशिश कर रहा हूं।

उत्तर

7

मुझे लगता है कि आप इसे जितना कठिन होना चाहते हैं उससे ज्यादा कठिन बना रहे हैं।

आपको "साक्ष्य" की आवश्यकता है कि दोनों पैरामीटर Numeric हैं। इसके साथ स्थापित सबूत काम करते हैं। स्कैला numeric widening नियोजित करेगा ताकि परिणाम दो प्राप्त प्रकारों का अधिक सामान्य हो।

def mult[T](a: T, b: T)(implicit ev:Numeric[T]): T = 
    ev.times(a,b) 

यदि आप थोड़ा फैनसीयर प्राप्त करना चाहते हैं तो आप आवश्यक निहितार्थों को खींच सकते हैं। फिर इसे पढ़ने और समझने में थोड़ा आसान है।

def mult[T: Numeric](a: T, b: T): T = { 
    import Numeric.Implicits._ 
    a * b 
} 

सबूत:

mult(2.3f , 7) //res0: Float = 16.1 
mult(8, 2.1) //res1: Double = 16.8 
mult(3, 2)  //res2: Int = 6 

सामान्य प्रकार के और संख्यात्मक को चौड़ा करने, this question के बारे में अधिक के लिए, और उसके जवाब है, का अध्ययन कर के लायक हैं।

+0

दुह! जगह में कास्ट किया जाता है! : डी – ShS

+0

दृश्य के पीछे क्या होता है यह बताने के लिए आपके उत्तर में http://scala-lang.org/files/archive/spec/2.11/06-expressions.html#value-conversions के संदर्भ जोड़ने के लिए स्वतंत्र महसूस करें। – ShS

+0

ठीक है, इसलिए मुझे अपनी विधि मिल रही है, लेकिन इसमें थोड़ी सी समस्या है। देखें कि क्या आप इसे हल करने में मेरी सहायता कर सकते हैं: http://stackoverflow.com/questions/43382282/scala- जेनरिक- भारित- लाभ- समारोह – ShS

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