2010-03-25 28 views
9

मैं स्कैला (स्कैला कोड धावक संस्करण 2.7.7.final) में नया हूं, और मुझे वास्तव में समझ में नहीं आता कि कॉलर की आवश्यकता क्यों है पैरामीटर प्रकार प्रदान करने के लिए जब हम उच्च ऑर्डर फ़ंक्शंस का उपयोग कर रहे हों।स्कैला जेनेरिक फ़ंक्शन मान (बेनामी फ़ंक्शन) - गुम पैरामीटर प्रकार (त्रुटि)

नमूने में नीचे, मैं एक योग्य स्वतंत्र वस्तु (Util) एक समारोह है कि है। लेकिन Main ब्लॉक में, फोन करने वाले गुमनाम कार्य करने के लिए पैरामीटर प्रकार से गुजरना होगा।

क्यों स्काला Array प्रकार (अर्थात String) से समारोह के प्रकार के अनुमान नहीं करता है? क्या उसे करने का कोई तरीका है ?

object Util { 

// Just for fun! Suppose that the arrayOne and arrayTwo are all the same length. 
// will swap the elements from arrayOne to ArrayTwo. 
    def swap[T](arrayOne:Array[T], arrayTwo:Array[T] , f:(T,T) =>(T,T)) { 
    for(i <- 0 until (arrayOne.length min arrayTwo.length)){ 
     val (left, right) = f(arrayOne(i),arrayTwo(i)) 
     arrayOne(i) = left 
     arrayTwo(i) = right 
    } 
    } 
} 

object Main extends Application { 

    val arrayOne = Array("A","B","C") 
    val arrayTwo = Array("D","E","F") 

//If not specified the type String,the compiler throws "Missing Parameter Type" error 

Util swap(arrayOne, arrayTwo,(elem1:String,elem2:String)=>(elem2,elem1)) 

} 
+0

वर्क्स केवल एक} util वस्तु में याद आ रही है। –

+0

@Thomas यह काम करता है, क्योंकि वह समारोह में प्रकार निर्दिष्ट। :-) –

+0

@Daniel प्रकार एनोटेशन आखिरी बात है कि मुझे इस कोड के साथ परेशान है। मुझे आश्चर्य है कि इसे ठीक करने के लिए अशिष्ट होगा। आखिरी पंक्ति पर ध्यान खो दिया। –

उत्तर

14

यह T के प्रकार इसका अनुमान नहीं लगा है, क्योंकि केवल एक चीज यह है इस बिंदु पर से जाने के लिए arrayOne और arrayTwo होगा। हालांकि, स्काला, एक और के प्रकार के अनुमान लगाने के लिए एक पैरामीटर के प्रकार का उपयोग नहीं करता शायद क्योंकि यह विधि ओवरलोडिंग के साथ समस्याओं का कारण होगा। हालांकि, यह काम करता है आप इसे करी यदि:

Object Util { 

// Just for fun! Suppose that the arrayOne and arrayTwo are all the same length. 
// will swap the elements from arrayOne to ArrayTwo. 
    def swap[T](arrayOne:Array[T], arrayTwo:Array[T])(f:(T,T) =>(T,T)) : Unit = { 
    var i = 0 
     var tuple :Tuple2[T,T] = null 
     while(i < arrayOne.length && i < arrayTwo.length){ 
     tuple =f(arrayOne(i),arrayTwo(i)) 
     arrayOne(i) = tuple._1 
     arrayTwo(i) = tuple._2 
     i+=1 
     } 
     } 
} 

object Main extends Application { 

    // val works fine below -- the object is mutable 
    val arrayOne = Array("A","B","C") 
    val arrayTwo = Array("D","E","F") 

    (Util swap(arrayOne, arrayTwo))((elem1,elem2)=>(elem2,elem1)) 
    // The weird parenthesis is caused by mixing operator notation and currying 
    // One could also write it like this: 
    // Util.swap(arrayOne, arrayTwo)((elem1,elem2)=>(elem2,elem1)) 
} 

कारण (कारण है कि यह ठीक काम करता है अगर आप करी यह है कि एक curried विधि वास्तव में एक विधि पहले पैरामीटर सूची प्राप्त करने और एक समारोह है कि अन्य की आवश्यकता है लौटने है या अन्य) पैरामीटर सूची। इसके कारण, पहले पैरामीटर सूची में ओवरलोडिंग का निर्णय लिया जा सकता है, इसलिए दूसरी पैरामीटर सूची अनुमानित प्रकार का लाभ उठा सकती है। मेरे लिए

+0

धन्यवाद डैनियल .. वास्तव में अपने उत्तर का आनंद लें! – CHAPa

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