2012-01-03 12 views
8

Compose फ़ंक्शन के नीचे। यदि f और g समान कार्य हैं जो मान वापस करते हैं, तो Compose(f,g) एक फ़ंक्शन देता है जिसे x पर कॉल किया जाता है f(g(x)) के बराबर करता है।फ़ंक्शन संरचना

Func<int, bool> is_zero = x => { return x == 0; }; 

Func<int, int> mod_by_2 = x => { return x % 2; }; 

जैसे:

static Func<X, Z> Compose<Z, Y, X>(Func<Y, Z> f,Func<X, Y> g) 
{ return x => f(g(x)); } 

यहाँ सरल Func मूल्यों के एक जोड़े जो बना जा सकता है इस काम करता है:

Console.WriteLine(Compose(is_zero, mod_by_2)(4)); 

हालांकि, अगर मैं बजाय इन बराबर स्थिर तरीकों:

static bool IsZero(int n) { return n == 0; } 

static int ModBy2(int n) { return n % 2; } 

एक ही उदाहरण लोगों के साथ काम नहीं करता। अर्थात।

Console.WriteLine(Compose(IsZero, ModBy2)(4)); 

स्पष्ट रूप से गुजर प्रकार Compose को ठीक करता है मुद्दा:

Console.WriteLine(Compose<bool, int, int>(IsZero, ModBy2)(4)); 

वहाँ वैसे भी है लिखने के लिए Compose इस तरह यह स्पष्ट प्रकार के बिना स्थिर तरीकों पर काम करता है कि यह एक संकलन समय त्रुटि पैदा करता है?

Compose लागू करने के लिए यह एक अच्छा तरीका है? क्या कोई इस में सुधार कर सकता है?

+0

सी # के समारोह/प्रतिनिधि प्रकार के अपने इलाज में कठोरता एक बात यह है कि हमेशा मुझे निराश है को शामिल किया गया जब बतख की तुलना में इस विशेष विषय पर एक व्यापक ब्लॉग लेख लिखा था जावास्क्रिप्ट जैसे टाइप की गई भाषाओं। –

उत्तर

10

यहां समस्या static विधियों का उपयोग नहीं है बल्कि विधि समूहों का उपयोग नहीं है। जब आप फ़ंक्शन नाम का उपयोग बिना अभिव्यक्ति के अभिव्यक्ति के रूप में करते हैं तो यह एक विधि समूह है और विधि समूह रूपांतरण के माध्यम से जाना चाहिए। उदाहरण विधियों के साथ आपको एक ही समस्या होगी।

जिस समस्या में आप चल रहे हैं वह यह है कि सी # विधि समूहों पर रिटर्न प्रकार अनुमान नहीं कर सकता है। Compose(IsZero, ModBy2)) का उपयोग करने के लिए वापसी प्रकार को IsZero और ModBy2 दोनों के लिए अनुमानित किया जाना चाहिए और इसलिए यह ऑपरेशन विफल हो जाता है।

यह सी # कंपाइलर की अनुमान क्षमताओं में एक ज्ञात सीमा है। एरिक Lippert जो विस्तार से इस समस्या को

+4

मुझे लगता है कि लेख थोड़ा पुराना है। इस विशेष मामले में यह सही है; आप विधि समूहों पर अनुमान नहीं लगा सकते क्योंकि हमारे पास चिकन-एंड-अंडे की समस्या है; हम यह निर्धारित नहीं कर सकते कि प्रतिनिधि प्रकार क्या हैं जब तक हम जानते हैं कि विधि समूह से कौन सी विधि चुनी गई है, और जब तक हम प्रतिनिधि * औपचारिक पैरामीटर * प्रकारों को नहीं जानते हैं, हम एक विधि समूह पर ओवरलोड रिज़ॉल्यूशन नहीं कर सकते हैं। यदि, इसके विपरीत, प्रतिनिधि * रिटर्न प्रकार * अनुमानित किए जा रहे थे लेकिन * औपचारिक पैरामीटर प्रकार * किसी भी तरह से ज्ञात थे तो वापसी प्रकार अनुमान विधि समूहों पर काम करेगा। –

+0

_ जब आप किसी फ़ंक्शन नाम का उपयोग बिना किसी अभिव्यक्ति के अभिव्यक्ति के रूप में करते हैं तो यह एक विधि समूह है और विधि समूह रूपांतरण के माध्यम से जाना चाहिए।ठीक है। तो 'IsZero' नाम एक विधि समूह को संदर्भित करता है। लेकिन इस मामले में, समूह में स्पष्ट रूप से केवल एक ही विधि है, और इस प्रकार रिटर्न प्रकार के बारे में कोई अस्पष्टता नहीं है।स्पष्ट रूप से कंपाइलर टीम ने इन मामलों (एकल विधि समूहों) का लाभ लेने के खिलाफ फैसला किया। क्या यह अन्यथा करने के लिए अस्वस्थ होगा? (मुझे बताएं कि मुझे इसके लिए एक अलग प्रश्न खोलना चाहिए ... :-)) – dharmatech

+0

बेशक, एक और अस्पष्ट मामला विधि समूह होगा जहां समूह के सभी तरीकों का एक ही रिटर्न प्रकार होगा। – dharmatech

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