2011-09-02 5 views
9

मैं एकाधिक पैरामीटर खंडों की इस भाषा सुविधा के बिंदु को समझने की कोशिश कर रहा हूं और आप इसका उपयोग क्यों करेंगे। उदाहरण के लिए, वास्तव में इन दो कार्यों के बीच क्या अंतर है?स्कैला में फ़ंक्शन परिभाषाओं में एकाधिक पैरामीटर खंडों का बिंदु क्या है?

class WTF { 
    def TwoParamClauses(x : Int)(y: Int) = x + y 
    def OneParamClause(x: Int, y : Int) = x + y 
} 

>> val underTest = new WTF 
>> underTest.TwoParamClauses(1)(1) // result is '2' 
>> underTest.OneParamClause(1,1) // result is '2' 

Scala specification at point 4.6 में इस पर कुछ है। देखें कि क्या यह आपको कोई समझ में आता है।

एनबी: स्पेक इन 'पैरामीटर क्लॉज' को कॉल करता है, लेकिन मुझे लगता है कि कुछ लोग उन्हें 'पैरामीटर सूचियां' भी कह सकते हैं।

+0

गैर- स्केला प्रोग्रामर यहाँ दो पैरामीटर सूची,

// analogous to a context bound: g3[A : Ordering](x: A) def g3[A](x: A)(implicit ev: Ordering[A]) {} 
  • की आवश्यकता है। शायद यह सिर्फ एक अलग शैली है? सबकुछ केवल इसे करने का एक तरीका नहीं है। – apscience

  • +0

    ठीक है, इसके बारे में डैनियल सोब्राल के जवाब में इसका कुछ जवाब है http://stackoverflow.com/questions/4697404/scala-currying-by-nested-functions-or-by-multiple-parameter-lists –

    +0

    स्वीकृत यहां जवाब शायद इस प्रश्न का उत्तर दें: (1) इसलिए आपको दूसरे खंड में पहले पैरा क्लॉज से प्रकार निर्दिष्ट करने की आवश्यकता नहीं है; (2) पुस्तकालय डिजाइन की लचीलापन के लिए; (3) करी को आसान बनाने के लिए: http://stackoverflow.com/questions/4915027/two-ways-of-currying-in-scala-whats-the-use-case-for-each –

    उत्तर

    9

    यहाँ कई पैरामीटर सूची के तीन व्यावहारिक उपयोग,

    1. प्रकार निष्कर्ष सहायता के लिए कर रहे हैं। उच्च आदेश विधियों का उपयोग करते समय यह विशेष रूप से उपयोगी होता है। नीचे, प्रकार पैरामीटर g2 की A पहले पैरामीटर x से अनुमान लगाया गया है, ताकि दूसरा पैरामीटर f में समारोह तर्क elided जा सकता है,

      def g1[A](x: A, f: A => A) = f(x) 
      g1(2, x => x) // error: missing parameter type for argument x 
      
      def g2[A](x: A)(f: A => A) = f(x) 
      g2(2) {x => x} // type is inferred; also, a nice syntax 
      
    2. अंतर्निहित पैरामीटर के लिए। केवल अंतिम पैरामीटर सूची को अंतर्निहित चिह्नित किया जा सकता है, और एक पैरामीटर सूची निहित और गैर-निहित पैरामीटर को मिश्रित नहीं कर सकती है। g3 की परिभाषा नीचे पिछले मापदंडों के आधार पर मूलभूत मूल्यों को सेट करने के

      def g4(x: Int, y: Int = 2*x) {} // error: not found value x 
      def g5(x: Int)(y: Int = 2*x) {} // OK 
      
    3

    कुछ मामलों में जहां इस तरह के अंतर मायने रखती हैं:

    1. एकाधिक पैरामीटर सूचियों आप TwoParamClauses तरह बातें की अनुमति (2); जो स्वचालित रूप से जेनरेट किया गया फ़ंक्शन int => Int है जो इसके तर्क में 2 जोड़ता है। बेशक आप एक ही चीज़ को स्वयं को OneParamClause का उपयोग करके परिभाषित कर सकते हैं, लेकिन इसमें अधिक कीस्ट्रोक

    2. यदि आपके पास अंतर्निहित पैरामीटर के साथ कोई फ़ंक्शन है जिसमें स्पष्ट पैरामीटर भी हैं, तो अंतर्निहित पैरामीटर अपने स्वयं के पैरामीटर खंड में होना चाहिए (यह एक मनमाना प्रतिबंध के रूप में प्रतीत हो सकता है लेकिन वास्तव में काफी समझदार है)

    इसके अलावा, मुझे लगता है कि अंतर स्टाइलिस्ट है।

    8

    TwoParamClause में दो विधि आमंत्रण शामिल हैं जबकि OneParamClause फ़ंक्शन विधि केवल एक बार आमंत्रित करता है। मुझे लगता है कि आप जिस शब्द को खोज रहे हैं वह करी है। कई उपयोग मामलों में से, यह आपको छोटे चरणों में गणना को तोड़ने में मदद करता है। यह answer आपको करी की उपयोगीता के बारे में बता सकता है।

    +1

    दो पैरामीटर खंडों वाला फ़ॉर्म केवल * विधि * को आमंत्रित करता है - उस आमंत्रण का परिणाम एक * फ़ंक्शन * होता है जिसे लागू किया जाता है जिसके परिणामस्वरूप अंतिम मान होता है। –

    +1

    @pst: लेकिन फ़ंक्शन को लागू करने से एक विधि (अर्थात्, फ़ंक्शन की 'लागू' विधि) भी आती है। –

    +0

    @Alexey Romanov True। मूल पोस्ट शब्द अलग था ;-) अब-दिनांकित टिप्पणी में मैं एक विधि (कुछ वस्तु को जानता है कि कैसे "जवाब देना है) के बीच अंतर पर जोर देने की कोशिश कर रहा था (एक अलग वस्तु जिसे लागू किया जा सकता है, यहां तक ​​कि यदि ऐसा आवेदन उस पर एक विधि का आह्वान करने का परिणाम है)। मैं अभी भी शब्दावली से असहमत हूं "...केवल एक बार फ़ंक्शन को आमंत्रित करता है "क्योंकि यह केवल एक बार 'OneParamClause' * विधि * को आमंत्रित करता है। –

    4

    एकाधिक पैरामीटर सूचियों अधिक जानकारी के लिए स्केला प्रकार निष्कर्ष मदद कर सकते हैं देखें: Making the most of Scala's (extremely limited) type inference

    प्रकार जानकारी भीतर एक बहस सूची बाएं से प्रवाहित नहीं होता सही को, केवल बाएं से दाएं तर्क पर सूचीबद्ध है। तो, हालांकि स्कैला पहले दो तर्कों के प्रकार जानता है ... वह जानकारी हमारे अज्ञात फ़ंक्शन पर नहीं जाती है।

    ...

    अब हमारे द्विआधारी समारोह एक अलग तर्क सूची में है कि, पिछले तर्क सूची से किसी भी प्रकार की जानकारी हमारे समारोह के लिए प्रकार में भरने के लिए प्रयोग किया जाता है ... इसलिए हम हमारे लैम्ब्डा के पैरामीटर को एनोटेट करने की आवश्यकता नहीं है।

    +0

    कृपया अंशों और/या तर्क शामिल करना सुनिश्चित करें और न केवल पोस्ट में नंगे लिंक। एक बहुत अच्छा लेख-खोज, हालांकि –

    +0

    मैंने सोचा कि मेरा संक्षिप्त वर्णन चिढ़ाने के लिए पर्याप्त होगा और पूर्ण संदर्भ के लिए ब्लॉग को पढ़ना चाहिए। लेकिन इस तरह यह ठीक है :) – AndreasScheinert

    6

    प्रकार निष्कर्ष के विषय में दोनों संस्करणों के बीच एक अंतर है।पर विचार करें

    def f[A](a:A, aa:A) = null 
    f("x",1) 
    //Null = null 
    

    यहाँ, प्रकार AAny के लिए बाध्य है, जो String और Int का एक सुपर प्रकार है। लेकिन:

    def g[A](a:A)(aa:A) = null 
    g("x")(1) 
    
    error: type mismatch; 
    found : Int(1) 
    required: java.lang.String 
         g("x")(1) 
          ^
    

    जैसा कि आप देख, प्रकार चेकर केवल पहला तर्क सूची पर विचार करता है, तो AString करने के लिए बाध्य हो जाता है, तो दूसरा तर्क सूची में aa के लिए Int मूल्य एक प्रकार की त्रुटि है।

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