2011-11-27 17 views
7

आप कर सकते थे एक टपल बनाने और फिर एक मैच अभिव्यक्ति में यह destructuring द्वारा एक समारोह के कई तर्क के खिलाफ पैटर्न मैचों की:ओकैमल में, फ़ंक्शन के कई तर्कों के विरुद्ध मिलान करने का कैननिक तरीका क्या है?

let f x y = 
    match x, y with 
    | pattern1 -> expr1 
    | ... 

वैकल्पिक रूप से, अगर आप एक curried समारोह की जरूरत नहीं है, तो आप कर ऐसा कर सकता है f बनाने केवल तर्क के रूप में एक टपल ले:

let f (x, y) = function 
    | pattern1 -> expr1 
    | ... 

बाद विधि का लाभ यह है कि आप दो बार हर बार जब आप एक समारोह को परिभाषित तर्क लिखने की जरूरत नहीं है कि। लेकिन एक ट्यूपल लेने वाले कार्यों को करीबी लोगों की तुलना में लोकप्रिय नहीं लगता है।

तो ओकैम समुदाय में दोनों में से कौन सा कैननिकल या पसंदीदा माना जाता है?

संपादित करें: जैसे पैड नीचे बताया गया है, मेरा मतलब है कि दूसरे कोड स्निपेट में let f = function blah blah है। ; उन दो संस्करणों नहीं हैं

let f (x, y) = 
    match x, y with 
    | pattern1 -> expr1 
    | ... 

(सूचना अपने दूसरे निर्माण में एक गलती है कि वहाँ:

let f = function 
    | pattern1_of_x_y -> expr1 
    | ... 

रूप में ही है:

उत्तर

8

एक ट्यूपल सिर्फ एक वाक्य रचनात्मक निर्माण नहीं है, यह वास्तविक डेटा संरचना का प्रतिनिधित्व करता है। इसका मतलब है कि fun (x,y)f x y से x और y से पहले (बहुत कम) कम कुशल है, पहले से ही tupled नहीं है, क्योंकि एक ट्यूपल आवंटित किया जाना चाहिए। यदि यह स्पष्ट नहीं है, जावा में किसी न किसी तरह बराबर

void foo(X x, Y y) { ... } 
void bar(Tuple<X,Y> t) { ... } 

/* client code */ 
X x = new X(); 
Y y = new Y(); 

foo(x, y); // Just uses x and y directly 
bar(new Tuple<X,Y>(x, y)); // Has to "new" a Tuple 

इस कारण हो सकता है, यह समारोह तर्कों के रूप tuples का उपयोग कर जब तक आप ऐसा करने के लिए एक अच्छा कारण है से बचने के लिए आम तौर पर प्राथमिकता दी जाती है।

पीएस

type 'a foo = Foo of 'a * 'a; 
type 'a bar = Bar of ('a * 'a); 

Foo एक डेटाप्रकार निर्माता है कि दो तर्क लेता है: एक समान विचार डेटाप्रकार घोषणाओं, जहां निम्नलिखित आसानी से अलग हैं पर लागू होता है। Bar एक निर्माता है जो एक तर्क (एक tuple) लेता है।

4

वास्तव में, f = function...f (x, y) = match (x, y) with... का एक शॉर्टकट तो है संगत)।

जैसा कि आपने बताया है, कोई एक करीबी कार्य में match ... with... का उपयोग करने से बच नहीं सकता है। व्यक्तिगत रूप से, मैं एक समारोह के करीबी रूप को प्राथमिकता देता हूं क्योंकि यह अधिक लचीला है, खासकर आंशिक अनुप्रयोग के साथ। इसके अलावा, पैटर्न मिलान न केवल फ़ंक्शन तर्कों में लागू होता है; वे ओकैमल में हर जगह अनिवार्य रूप से उपयोग किए जाते हैं, जो match ... with... बनाता है और भी महत्वपूर्ण बनाते हैं।

जब भी आप ऊपर के रूप में उपयोग पैटर्न को देखते हैं, function के साथ प्रतिस्थापित करने का प्रयास करें। यह सिर्फ शैली का मामला है, इसलिए यहां कुछ और पसंद नहीं है।

8

यह समाधान विहित है:

let f x y = 
    match x, y with 
    | pattern1 -> expr1 
    | ... 

संकलक इस विशेष मामले का अनुकूलन और वास्तव में टपल (x, y) के लिए एक ब्लॉक का आवंटन नहीं है।

3

कैननिकल तरीका एक करीबी कार्य है और match टुपल पर, यानी आपका पहला स्निपेट है।

मानक पुस्तकालय लिखा गया है (मानक लाइब्रेरी स्रोतों को देखें, उदाहरण के लिए list.ml में कई फ़ंक्शन)।

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

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

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