ग्रूवी का कार्यान्वयन curry
वास्तव में किसी भी बिंदु पर करी नहीं जाता है, यहां तक कि पर्दे के पीछे भी। यह अनिवार्य रूप से आंशिक अनुप्रयोग के समान है।
curry
, rcurry
और ncurry
तरीकों एक वापसी CurriedClosure
वस्तु है कि बाध्य तर्क रखती है। इसकी एक विधि भी है getUncurriedArguments
(गलत-आप करी कार्य, न कि तर्कों) जो कि उस पर दिए गए तर्कों की रचना को बाध्य तर्कों के साथ लौटाता है।
जब कोई कॉल बंद हो जाता है, तो यह अंततः की invokeMethod
विधि कोMetaClassImpl
कॉल करता है , जो स्पष्ट रूप से यह देखने के लिए जांचता है कि क्या कॉलिंग ऑब्जेक्ट का एक उदाहरण है CurriedClosure
। यदि ऐसा है, तो यह getUncurriedArguments
लागू करने के लिए तर्कों की पूरी सरणी की रचना करने के लिए उपर्युक्त का उपयोग करता है :
if (objectClass == CurriedClosure.class) {
// ...
final Object[] curriedArguments = cc.getUncurriedArguments(arguments);
// [Ed: Yes, you read that right, curried = uncurried. :) ]
// ...
return ownerMetaClass.invokeMethod(owner, methodName, curriedArguments);
}
ऊपर दिए गए भ्रामक और कुछ असंगत नामकरण के आधार पर, मुझे संदेह है कि जिसने भी यह लिखा है, उसकी एक अच्छी वैचारिक समझ है, लेकिन शायद थोड़ी भीड़ थी और - कई स्मार्ट लोगों की तरह - आंशिक अनुप्रयोग के साथ करी हुई जानकारी। यह समझ में आता है (यदि पॉल किंग का उत्तर देखें), अगर थोड़ा दुर्भाग्यपूर्ण; पीछे की संगतता को तोड़े बिना इसे ठीक करना मुश्किल होगा।
एक समाधान जो मैंने सुझाया है, वह curry
तरीका है कि जब कोई तर्क पारित नहीं होता है तो यह वास्तविक करी है, और एक नए partial
फ़ंक्शन के पक्ष में तर्कों के साथ विधि को कॉल करने को चित्रित करता है। यह थोड़ा अजीब लग सकता है , लेकिन यह पश्चगामी संगतता को अधिकतम करेगा - क्योंकि शून्य तर्क के साथ आंशिक अनुप्रयोग का उपयोग करने का कोई कारण नहीं है - (IMHO) से बचने के लिए, उचित रूप से कार्य करने के लिए एक नए, अलग-अलग नाम वाले कार्य के लिए बदसूरत स्थिति। नाम curry
कुछ अलग और भ्रामक समान है।
यह बिना कहे चला जाता है कि कॉलिंग curry
का परिणाम वास्तविक करी से पूरी तरह से अलग है। यदि यह वास्तव में फ़ंक्शन को रोक देता है, तो आप लिखने में सक्षम होंगे:
def add = { x, y -> x + y }
def addCurried = add.curry() // should work like { x -> { y -> x + y } }
def add1 = addCurried(1) // should work like { y -> 1 + y }
assert add1(1) == 2
... और यह काम करेगा, क्योंकि addCurried
काम करना चाहिए { x -> { y -> x + y } }
। इसके बजाय यह एक रनटाइम अपवाद फेंकता है और आप थोड़ा अंदर मर जाते हैं।