करीबी एक तर्क को एकल तर्क कार्यों की एक श्रृंखला में एकाधिक तर्कों के साथ बदलने की प्रक्रिया का वर्णन करता है। तीन-तर्क समारोह के लिए सी # में उदाहरण:
Func>> Curry(Func f)
{
return a => b => c => f(a, b, c);
}
void UseACurriedFunction()
{
var curryCompare = Curry(String.Compare);
var a = "SomeString";
var b = "SOMESTRING";
Console.WriteLine(String.Compare(a, b, true));
Console.WriteLine(curryCompare(a)(b)(true));
//partial application
var compareAWithB = curryCompare(a)(b);
Console.WriteLine(compareAWithB(true));
Console.WriteLine(compareAWithB(false));
}
अब, बूलियन तर्क शायद नहीं तर्क है जिसे आप आंशिक एप्लिकेशन के साथ खोलना चाहते हैं। यह एक कारण है कि एफ # कार्यों में तर्कों का क्रम पहले थोड़ा अजीब लग सकता है। आइए एक अलग सी # करी फ़ंक्शन को परिभाषित करें:
Func>> BackwardsCurry(Func f)
{
return a => b => c => f(c, b, a);
}
अब, हम कुछ और अधिक उपयोगी कर सकते हैं:
void UseADifferentlyCurriedFunction()
{
var curryCompare = BackwardsCurry(String.Compare);
var caseSensitiveCompare = curryCompare(false);
var caseInsensitiveCompare = curryCompare(true);
var format = Curry(String.Format)("Results of comparing {0} with {1}:");
var strings = new[] {"Hello", "HELLO", "Greetings", "GREETINGS"};
foreach (var s in strings)
{
var caseSensitiveCompareWithS = caseSensitiveCompare(s);
var caseInsensitiveCompareWithS = caseInsensitiveCompare(s);
var formatWithS = format(s);
foreach (var t in strings)
{
Console.WriteLine(formatWithS(t));
Console.WriteLine(caseSensitiveCompareWithS(t));
Console.WriteLine(caseInsensitiveCompareWithS(t));
}
}
}
सी # में इन उदाहरण क्यों हैं? क्योंकि एफ # में, फ़ंक्शन घोषणाएं डिफ़ॉल्ट रूप से curried हैं। आपको आमतौर पर कार्यों को करी करने की आवश्यकता नहीं होती है; वे पहले से ही चिंतित हैं। इसका मुख्य अपवाद फ्रेमवर्क विधियों और अन्य अधिभारित फ़ंक्शंस है, जो उनके एकाधिक तर्क वाले टुपल लेते हैं। इसलिए आप ऐसे कार्यों को करी करना चाहते हैं, और वास्तव में, मैं इस प्रश्न पर आया था जब मैं लाइब्रेरी फ़ंक्शन की तलाश में था जो ऐसा करेगा। मुझे लगता है कि यह गायब है (यदि वास्तव में यह है) क्योंकि यह लागू करने के लिए बहुत छोटा है:
let curry f a b c = f(a, b, c)
//overload resolution failure: there are two overloads with three arguments.
//let curryCompare = curry String.Compare
//This one might be more useful; it works because there's only one 3-argument overload
let backCurry f a b c = f(c, b, a)
let intParse = backCurry Int32.Parse
let intParseCurrentCultureAnyStyle = intParse CultureInfo.CurrentCulture NumberStyles.Any
let myInt = intParseCurrentCultureAnyStyle "23"
let myOtherInt = intParseCurrentCultureAnyStyle "42"
String.Compare के साथ विफलता के आसपास होने के लिए, जहां तक मैं कह सकता हूं कि कौन सा 3-तर्क अधिभार चुनने का कोई तरीका नहीं है, आप एक गैर-सामान्य समाधान का उपयोग कर सकते हैं:
let curryCompare s1 s2 (b:bool) = String.Compare(s1, s2, b)
let backwardsCurryCompare (b:bool) s1 s2 = String.Compare(s1, s2, b)
मैं एफ # में आंशिक फ़ंक्शन एप्लिकेशन के उपयोग के बारे में विस्तार से नहीं जाऊंगा क्योंकि अन्य उत्तरों ने पहले से ही कवर किया है।