2013-08-23 13 views
6

पर विचार करें निम्नलिखित बकवास लैम्ब्डा:एफ # पैटर्न मिलान विषमता

function 
| [] -> "Empty list" 
| hd::tl -> "Not so empty list" 

यह ठीक काम करता है। अब मैं इसे फिर से लिखने इस प्रकार है:

function 
| [] -> "Empty list" 
| hd::tl & l -> "Not so empty list" 

फिर, बकवास कारणों के लिए (और मुझे पता है कि मैं & के बजाय as, उपयोग करके एक ही प्रभाव को प्राप्त कर सकते हैं लेकिन यह सब एक कोड गोल्फ समस्या है कि के साथ क्या करना इस सवाल से संबंधित नहीं है)। अब एफ # कंपाइलर मुझे बताता है:

चेतावनी FS0025: इस अभिव्यक्ति पर अपूर्ण पैटर्न मिलान। उदाहरण के लिए, मान '[]' पैटर्न (ओं) द्वारा कवर न किए गए मामले को इंगित कर सकता है।

यह कोई समझ नहीं आता है - मैं स्पष्ट रूप से पहले नियम में [] के मामले को संभालने में सक्षम हूं। मैं नहीं देखता कि [] के संबंध में पहले फ़ंक्शन से दूसरे में क्या बदल गया है; न तो फ़ंक्शन का दूसरा नियम मेल खाता होगा, फिर भी दूसरा फ़ंक्शन चेतावनी देता है। मैंने जो कुछ किया वह एक अतिरिक्त पैटर्न जोड़ता था जो से मेल खाता है

बेशक, एक खाली सूची के साथ दूसरे समारोह का आह्वान सफल होता है।

क्या कोई वैध कारण है कि यह चेतावनी क्यों हुई, या F # पैटर्न सत्यापन में कुछ quirks है? मैं इस तरह के कुछ मामलों को देख सकता था जब अधिक उन्नत पैटर्न नियोजित होते हैं, लेकिन यह एक सुंदर मूल जैसा लगता है। यहां तक ​​कि अगर समस्या को हल नहीं किया जा सकता है, तो ऐसा लगता है कि इस प्रकार का मामला संकलक में विशेष हैंडलिंग की योग्यता के लिए पर्याप्त होगा।

+1

मैंने कभी भी इस तरह से उपयोग नहीं किया है। क्या आप कुछ दस्तावेज से लिंक कर सकते हैं जो करता है? – JaredPar

+3

@ जेरेडपार - यहां देखें और पैटर्न http://msdn.microsoft.com/en-us/library/dd547125.aspx। असल में इसका मतलब है कि आप एक ही समय में सिर, पूंछ और पूरी सूची प्राप्त कर सकते हैं –

उत्तर

6

मुझे लगता है कि इस मामले में एफ # कंपाइलर व्यावहारिक है।

अंत में, दूसरा नियम इनपुट सूची xs पर एक बाधा के रूप में व्यक्त किया जा सकता है:

xs = hd :: tl && xs = l 

एफ # संकलक && की कमी का पता लगाने के प्रतीत नहीं होता। यह उचित है क्योंकि बाधाएं मनमाने ढंग से जटिल हो सकती हैं और & का उपयोग काफी दुर्लभ है।

हम partial active patterns के साथ एक समान समस्या है:

let (|Empty|_|) = function 
    | [] -> Some() 
    | _ -> None 

let (|NonEmpty|_|) = function 
    | _ :: _ -> Some() 
    | _ -> None 

// warning FS0025 
let f = function 
    | Empty -> "Empty list" 
    | NonEmpty -> "Not so empty list" 

इस समस्या को हल करने के लिए, आप कर सकते हैं:

  • उपयोग as बजाय & है, जो अधिक उपयुक्त है के बाद से l सिर्फ एक बाध्यकारी है।
  • चेतावनी को खत्म करने के अंत में वाइल्डकार्ड पैटर्न जोड़ें। मैं आमतौर पर

    let f = 
        function 
        | hd::tl & l -> "Not so empty list" 
        | _ -> "Empty list" 
    
  • दबाने चेतावनी nowarn "25" का उपयोग कर लिखें।

+0

हाँ, मैंने पहले आंशिक सक्रिय पैटर्न के साथ चेतावनी देखी है। वह वास्तव में समझ में आता है, सक्रिय पैटर्न के रूप में देखकर संकलन संकलित होते हैं और मैक्रोज़ नहीं होते हैं और इसलिए संकलक मैचों की पूर्णता को स्थिर रूप से सत्यापित नहीं कर सकता है। अब अगर 'इनलाइन' कीवर्ड (मैंने कोशिश की है) के साथ एक सक्रिय पैटर्न को परिभाषित करने का कोई तरीका था, तो यह एक अलग कहानी हो सकती है। – luksan

+1

आप सक्रिय पैटर्न के साथ 'इनलाइन' का उपयोग कर सकते हैं:' इनलाइन (| खाली | _ |) xs = match xs के साथ [] -> कुछ() | _ -> कोई नहीं ', लेकिन चेतावनी अभी भी वहां है। – pad

+0

मुझे लगता है कि आप सही हैं। हालांकि अगर मैं '<@@ फ़ंक्शन करता हूं [] -> कुछ() | _ -> कोई नहीं @@> 'मैं देखता हूं कि मिलान अभिव्यक्ति के लिए एएसटी सिर्फ एक/अन्य है, इसलिए पैटर्न की जानकारी अभी भी खो गई है। – luksan

4

मुझे लगता है कि तुम कहाँ संकलक के निर्णय प्रक्रिया पर्याप्त शक्तिशाली नहीं है (when खंड और आंशिक सक्रिय पैटर्न को छोड़ कर) एक अन्य मामले में पाया गया। (यही कारण है कि चेतावनी संदेश :-) इंगित कर सकता है)।

यदि आप चेतावनियों के बिना समान कार्यक्षमता प्राप्त करना चाहते हैं, तो आप इस तरह के एक पूर्ण सक्रिय पैटर्न का उपयोग कर सकते हैं (लेकिन हकीकत में, सूचियों के लिए, मैं शायद खाली सूची केस के लिए _ के साथ जाऊंगा क्योंकि @pad सुझाता है) :

let (|Empty|NonEmpty|) l = 
    match l with [] -> Empty | x::xs -> NonEmpty(x, xs, l) 

let foo = function 
    | Empty -> 0 
    | NonEmpty(x, xs, l) -> 1 
+0

यह कहता है "संकेत दे सकता है," लेकिन यह "अपूर्ण" बल्कि "संभवतः अपूर्ण" भी कहता है, इसलिए यह कुछ हद तक संदिग्ध है। – luksan

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