2015-12-03 6 views
8

तो मैं रियल वर्ल्ड हास्केल पुस्तक में व्यस्त रहा हूं और मैंने अंतिमबूटऑन अभ्यास किया था। मैं मिलानवास्तविक जीवन उदाहरण जब पैटर्न मिलान हास्केल में केस अभिव्यक्ति से अधिक बेहतर है?

lastButOne :: [a] -> a 
lastButOne ([]) = error "Empty List" 
lastButOne (x:[]) = error "Only one element" 
lastButOne (x:[x2]) = x 
lastButOne (x:xs) = lastButOne xs 

और एक एक मामला अभिव्यक्ति

lastButOneCase :: [a] -> a 
lastButOneCase x = 
    case x of 
    [] -> error "Empty List" 
    (x:[]) -> error "Only One Element" 
    (x:[x2]) -> x 
    (x:xs) -> lastButOneCase xs 

क्या मैं पता लगाने के लिए जब पैटर्न मिलान से अधिक प्राथमिकता दी जाएगी है चाहता था का उपयोग कर पैटर्न के साथ एक 2 समाधान के साथ आया था, केस एक्सप्रेशन और इसके विपरीत। यह उदाहरण मेरे लिए पर्याप्त नहीं था क्योंकि ऐसा लगता है कि दोनों कार्य इरादे के रूप में काम करते हैं, लेकिन यह मुझे दूसरे पर एक कार्यान्वयन का चयन करने के लिए प्रेरित नहीं करता है। तो पसंद पहली नज़र में अधिमानी "लगता है"?

तो सोर्स कोड के माध्यम से या तो हैकेल के अपने स्रोत या जिथब या कहीं और, जहां कोई भी विधि को प्राथमिकता दी जाती है या नहीं, जहां कोई देख सकता है?

+5

मैं दो लाइनों को छोटा करना चाहता हूं। – Bergi

+8

केस अभिव्यक्तियों को एक ही पैटर्न मिलान का उपयोग नहीं करते हैं, केवल एक अलग वाक्य रचनात्मक निर्माण के अंदर? – 9000

+3

एक केस अभिव्यक्ति को किसी अन्य अभिव्यक्ति में एम्बेड किया जा सकता है, जरूरी नहीं कि फ़ंक्शन परिभाषा का शीर्ष एक हो। मुझे लगता है कि पैटर्न के साथ कई समारोह घोषणाएं दूसरे रूप में सिर्फ एक वाक्य रचनात्मक चीनी है। – 9000

उत्तर

15

पहले एक छोटी अवधि शब्दावली मोड़: मैं इन दोनों "पैटर्न मिलान" को कॉल करूंगा। मुझे यकीन नहीं है कि पैटर्न-मिलान-थ्रू-केस-पैटर्न और मिलान-मिलान-बहु-परिभाषा को अलग करने के लिए एक अच्छी अवधि है।

दोनों के बीच तकनीकी भेद वास्तव में काफी हल्का है। -ddump-simpl ध्वज का उपयोग करके, जीएचसी को दो कार्यों के लिए उत्पन्न कोर को डंप करने के लिए आप इसे स्वयं सत्यापित कर सकते हैं। मैंने इसे कुछ अलग अनुकूलन स्तरों पर आजमाया, और सभी मामलों में कोर में केवल अंतर ही नामकरण कर रहे थे। (वैसे, अगर कोई कोर के लिए एक अच्छा "अर्थात् diff" प्रोग्राम जानता है - जो कम से कम अल्फा समकक्षता के बारे में जानता है - मुझे इसके बारे में सुनने में बहुत दिलचस्पी है!)

कुछ छोटे हैं हालांकि, देखने के लिए गेटचास। आप सोच सकते हैं कि निम्नलिखित समकक्ष भी है:

{-# LANGUAGE LambdaCase #-} 
lastButOne = \case 
    [] -> error "Empty List" 
    (x:[]) -> error "Only One Element" 
    (x:[x2]) -> x 
    (x:xs) -> lastButOneCase xs 

इस मामले में, उत्तर हाँ है। लेकिन पर विचार यह एक समान दिखने वाले एक:

-- ambiguous type error 
sort = \case 
    [] -> [] 
    x:xs -> insert x (sort xs) 

एक यह अचानक एक typeclass-बहुरूपी सीएएफ है, और इसलिए वर्ष GHCs पर इस monomorphism प्रतिबंध को गति प्रदान और एक त्रुटि का कारण है, एक साथ अल्पज्ञता समान संस्करण जबकि होगा स्पष्ट तर्क नहीं करता है:

-- this is fine! 
sort [] = [] 
sort (x:xs) = insert x (sort xs) 

अन्य मामूली अंतर (जो मैं बारे में भूल गया - मुझे याद दिलाने के लिए Thomas DuBuisson को धन्यवाद) जहां खंड की हैंडलिंग में है। चूंकि बाध्यकारी साइटों से क्लॉज जुड़े हुए हैं, इसलिए उन्हें कई समीकरणों में साझा नहीं किया जा सकता है लेकिन कई मामलों में साझा किया जा सकता है।

-- error; the where clause attaches to the second equation, so 
-- empty is not in scope in the first equation 
null [] = empty 
null (x:xs) = nonempty 
    where empty = True 
     nonempty = False 

-- ok; the where clause attaches to the equation, so both empty 
-- and nonempty are in scope for the entire case expression 
null x = case x of 
    [] -> empty 
    x:xs -> nonempty 
    where 
    empty = True 
    nonempty = False 

आप इस का मतलब है आप समीकरणों के साथ कुछ है कि आप मामले भाव के साथ ऐसा नहीं कर सकते कर सकते हैं सोच सकते हैं, अर्थात्, दो समीकरणों में एक ही नाम के लिए अलग अलग अर्थ है, इस तरह है::

उदाहरण के लिए
null [] = answer where answer = True 
null (x:xs) = answer where answer = False 

हालांकि, case भाव के पैटर्न के बाद से बाध्यकारी साइटों रहे हैं, इस case भाव में नकल करते किया जा सकता है और साथ ही:

null x = case x of 
    [] -> answer where answer = True 
    x:xs -> answer where answer = False 

चाहे where खंड case के पैटर्न से जुड़ा हुआ है या समीकरण के लिए, इंडेंटेशन पर निर्भर करता है।

+4

"मुझे यकीन नहीं है कि पैटर्न-मिलान-थ्रू-केस-पैटर्न और पैटर्न-मिलान-से-एकाधिक-परिभाषा को अलग करने के लिए एक अच्छी अवधि है।" हास्केल के इतिहास पर [हुडक, ह्यूजेस, पेटन जोन्स और वाडलर पेपर] (http://haskell.cs.yale.edu/wp-content/uploads/2011/02/history.pdf) इस "घोषणा शैली" (के लिए) एकाधिक समीकरण) बनाम "अभिव्यक्ति शैली" ('केस' अभिव्यक्ति के लिए)। –

+0

महान जवाब! मैं एक के लिए नहीं जानता था कि आप 'मामले' के पैरों में 'कहां' बाइंडिंग कर सकते हैं। –

4

यदि मुझे सही ढंग से याद है तो ये दोनों ghc में एक ही कोर कोड में "desugar" करेंगे, इसलिए विकल्प पूरी तरह स्टाइलिस्ट है। व्यक्तिगत रूप से मैं पहले के लिए जाना होगा। जैसा कि किसी ने कहा, इसके छोटे, और आप "पैटर्न मिलान" शब्द का क्या अर्थ है इस तरह इस्तेमाल किया जाना है। (असल में दूसरा संस्करण पैटर्न मिलान भी है, इसके लिए सिर्फ एक अलग वाक्यविन्यास का उपयोग कर)।

1

यह एक स्टाइलिस्ट वरीयता है। कुछ लोग कभी-कभी तर्क देते हैं कि एक विकल्प या कोई अन्य कोड परिवर्तन कम प्रयास करता है, लेकिन मुझे आमतौर पर ऐसे तर्क मिलते हैं, भले ही सटीक, वास्तव में बड़े सुधार की मात्रा न हो। तो आप पसंद करते हैं।

एक परिप्रेक्ष्य जो इसमें लायक है, वह हुडक, ह्यूजेस, पेटन जोन्स और वाडलर के पेपर "A History of Haskell: Being Lazy With Class" है। धारा 4.4 इस विषय के बारे में है। छोटी कहानी: हास्केल दोनों का समर्थन करता है क्योंकि डिजाइनर एक दूसरे से सहमत नहीं हो सकते थे। हां, फिर, यह एक स्टाइलिस्ट वरीयता है।

0

जब आप पर एक से अधिक अभिव्यक्ति से मेल खाते हैं, case अभिव्यक्ति अधिक आकर्षक लगने लगती हैं।

f pat11 pat21 = ... 
f pat11 pat22 = ... 
f pat11 pat23 = ... 
f pat12 pat24 = ... 
f pat12 pat25 = ... 

से अधिक

f pat11 y = 
    case y of 
    pat21 -> ... 
    pat22 -> ... 
    pat23 -> ... 
f pat12 y = 
    case y of 
    pat24 -> ... 
    pat25 -> ... 

और भी महत्वपूर्ण है लिखने के लिए कष्टप्रद हो सकता है, मैंने पाया है कि जब GADTs का उपयोग कर, "घोषणा शैली" बाएं से सबूत प्रचार करने के लिए सही प्रतीत नहीं होता है जिस तरह से मैं इसकी उम्मीद करूँगा। ऐसी कुछ चाल हो सकती है जो मैंने काम नहीं की है, लेकिन मैं नकली अपूर्ण पैटर्न चेतावनियों से बचने के लिए case अभिव्यक्तियों को घोंसला कर रहा हूं।

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