प्लास्ट ग्रोव द्वारा जुड़े उत्तर में शब्दार्थ अंतर को काफी अच्छी तरह से समझाया गया है ।
कार्यक्षमता के संदर्भ में, हालांकि इसमें बहुत अधिक अंतर नहीं है। आइए इसे सत्यापित करने के लिए कुछ उदाहरण देखें। सबसे पहले, एक सामान्य कार्य:
scala> def modN(n: Int, x: Int): Boolean = ((x % n) == 0)
scala> modN(5, _ : Int)
res0: Int => Boolean = <function1>
इसलिए हमें एक आंशिक रूप से लागू होता है <function1>
जो एक लेता है Int
, क्योंकि हमने पहले ही इसे पूर्णांक दिया है। अब तक सब ठीक है। अब करी करने के लिए:
scala> def modNCurried(n: Int)(x: Int): Boolean = ((x % n) == 0)
इस अंकन के साथ, आप निम्न कार्य करने की उम्मीद करेंगे:
scala> modNCurried(5)
<console>:9: error: missing arguments for method modN;
follow this method with `_' if you want to treat it as a partially applied function
modNCurried(5)
तो कई पैरामीटर सूची संकेतन वास्तव में एक करी फ़ंक्शन को तुरंत बनाने के लिए प्रतीत नहीं होता है (अनावश्यक ओवरहेड से बचने के लिए), लेकिन आपके लिए यह स्पष्ट रूप से बताने की प्रतीक्षा करता है कि आप इसे चाहते हैं (नोटेशन के कुछ अन्य फायदे भी हैं):
scala> modNCurried(5) _
res24: Int => Boolean = <function1>
जो ठीक वैसा ही है जो हमें पहले मिला था, इसलिए यहाँ कोई अंतर नहीं है, सिवाय संकेतन के। एक और उदाहरण:
scala> modN _
res35: (Int, Int) => Boolean = <function2>
scala> modNCurried _
res36: Int => (Int => Boolean) = <function1>
यह प्रदर्शित करता है कि एक "सामान्य" फ़ंक्शन को आंशिक रूप से लागू करने का कार्य एक फ़ंक्शन में होता है जो सभी मापदंडों को लेता है, जबकि आंशिक रूप से कई पैरामीटर सूचियों के साथ एक फ़ंक्शन लागू करने से फ़ंक्शन की एक श्रृंखला बनती है, प्रति पैरामीटर सूची में से एक, जो सभी एक नया फ़ंक्शन लौटाते हैं:
scala> def foo(a:Int, b:Int)(x:Int)(y:Int): Int = a * b + x - y
scala> foo _
res42: (Int, Int) => Int => (Int => Int) = <function2>
scala> res42(5)
<console>:10: error: not enough arguments for method apply: (v1: Int, v2: Int)Int => (Int => Int) in trait Function2.
Unspecified value parameter v2.
जैसा कि आप देख सकते हैं, क्योंकि पहले पैरामीटर की सूची foo
में दो पैरामीटर हैं, क्यूरी श्रृंखला में पहले फ़ंक्शन के दो पैरामीटर हैं।
सारांश में, आंशिक रूप से लागू किए गए फ़ंक्शंस वास्तव में कार्यक्षमता के मामले में भिन्न रूप से फ़ंक्स्ड फ़ंक्शंस नहीं हैं। यह आसानी से सत्यापित हो जाता है कि आप किसी भी फ़ंक्शन को एक करीबी में बदल सकते हैं:
scala> (modN _).curried
res45: Int => (Int => Boolean) = <function1
scala> modNCurried _
res46: Int => (Int => Boolean) = <function1>
स्क्रिप्टम के बाद
नोट: कारण कि आपका उदाहरण println(filter(nums, modN(2))
बिना अंडरस्कोर के काम करता है, modN(2)
ऐसा लगता है कि स्काला संकलक प्रोग्रामर के लिए एक सुविधा के रूप में उस अंडरस्कोर को मानता है।
इसके अलावा: जैसा कि @asflierl ने सही ढंग से बताया है, स्काला को उस प्रकार का अनुमान लगाने में सक्षम नहीं लगता जब आंशिक रूप से "सामान्य" कार्यों को लागू किया जाता है:
scala> modN(5, _)
<console>:9: error: missing parameter type for expanded function ((x$1) => modN(5, x$1))
जबकि यह जानकारी कई पैरामीटर सूची संकेतन का उपयोग करते हुए लिखे गए कार्यों के लिए उपलब्ध है:
scala> modNCurried(5) _
res3: Int => Boolean = <function1>
यह उत्तर दिखाता है कि यह कैसे बहुत उपयोगी हो सकता है।