2011-04-11 18 views
5

मान लीजिए मैं निम्नलिखित कोड है:फिल्टर के रूप में अपूर्ण पैटर्न मिलान का उपयोग कर?

type Vehicle = 
| Car of string * int 
| Bike of string 

let xs = [ Car("family", 8); Bike("racing"); Car("sports", 2); Bike("chopper") ] 

मैं जैसे पाश के लिए एक अनिवार्य में अधूरा पैटर्न मिलान का उपयोग कर सूची के ऊपर फ़िल्टर कर सकते हैं:

> for Car(kind, _) in xs do 
> printfn "found %s" kind;; 

found family 
found sports 
val it : unit =() 

लेकिन यह एक कारण होगा: warning FS0025: Incomplete pattern matches on this expression. For example, the value 'Bike (_)' may indicate a case not covered by the pattern(s). Unmatched elements will be ignored.

चूंकि बेजोड़ तत्वों की अनदेखी करना मेरा इरादा है, क्या इस चेतावनी से छुटकारा पाने की संभावना है?

और क्या इस काम को सूची-समझ के साथ मैचफेलर अपवाद के बिना बनाने का कोई तरीका है? जैसे ऐसा ही कुछ:

> [for Car(_, seats) in xs -> seats] |> List.sum;; 
val it : int = 10 
+0

मुझे लगता है कि लाइन होने का अनुमान था: [बस (_, सीटें) में xs -> सीटें] |> List.sum ;; सही? ;) –

+0

ओह मुझे मिल गया !!! 2 कारें! 5 एक्स 2 = 10! प्रभु मेरी मदद करें। –

+0

यह एक पारिवारिक कार और एक स्पोर्ट कार है, इसलिए 8 + 2 = 10. – Laurent

उत्तर

10

दो साल पहले अपने कोड मान्य था और यह यह करने के लिए मानक तरीका था। फिर, भाषा को साफ कर दिया गया है और डिजाइन निर्णय स्पष्ट वाक्यविन्यास का पक्ष लेना था। इस कारण से, मुझे लगता है कि चेतावनी को अनदेखा करना एक अच्छा विचार नहीं है।

अपने कोड के लिए मानक प्रतिस्थापन है:

for x in xs do 
    match x with 
    | Car(kind, _) -> printfn "found %s" kind 
    | _ ->() 

(आप भी उच्च आदेश कार्यों पैड नमूने में है इस्तेमाल कर सकते हैं) एक दूसरे के लिए, List.sumBy अच्छी तरह से फिट होगा:

0:
xs |> List.sumBy (function Car(_, seats) -> seats | _ -> 0) 

आप comprehensions साथ रहना पसंद करते हैं, इस स्पष्ट वाक्य रचना है

+0

दिलचस्प। क्या आपके पास एक संदर्भ/लिंक है जो आपके द्वारा उल्लिखित "सफाई" का वर्णन करता है, और इस परिवर्तन के औचित्य पर चर्चा करता है? – gasche

+4

@gasche: मेरे कंप्यूटर पर पुराने कंपाइलर्स हैं, मैं आपको बता सकता हूं कि परिवर्तन 1.9.3.14 और 1.9.6.16 के बीच हुआ था। मुझे इसके लिए उचित संदर्भ नहीं मिल रहा है, लेकिन उन रिलीज नोट्स में सिंटैक्स सरलीकरण का उल्लेख है: [लिंक] (http: //blogs.msdn।कॉम/बी/dsyme/संग्रह/2008/08/29/विस्तृत रिलीज नोट्स के लिए-च-सितंबर-2008-सीटीपी-release.aspx)। यहां एक चर्चा भी है: [लिंक] (http://cs.hubfs.net/forums/thread/12072.aspx)। – Laurent

+1

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

5

ज़रिए आप किसी भी चेतावनी मौन कर सकते हैं #nowarn निर्देश या --nowarn: संकलक विकल्प (चेतावनी नंबर, यहाँ 25 रूप FS0025 में पारित)।

लेकिन अधिक आम तौर पर, नहीं, सबसे अच्छा बात स्पष्ट रूप से फ़िल्टर करना है, जैसा कि दूसरे उत्तर में है (उदाहरण के लिए choose)।

+1

मुझे उम्मीद थी कि स्थानीय रूप से इस चेतावनी को अक्षम करने की संभावना थी। एक विशेषता का उपयोग करके। लेकिन फिर भी धन्यवाद! :) –

5

स्पष्ट रूप से यह बताने के लिए कि आप बेजोड़ मामलों को अनदेखा करना चाहते हैं, आप List.choose का उपयोग कर सकते हैं और उन बेजोड़ तत्वों के लिए None वापस कर सकते हैं। आपका कोड एक और अधिक idomatic तरह से लिखा जा सकता है इस प्रकार है:

let _ = xs |> List.choose (function | Car(kind, _) -> Some kind 
            | _ -> None) 
      |> List.iter (printfn "found %s") 

let sum = xs |> List.choose (function | Car(_, seats)-> Some seats 
             | _ -> None) 
      |> List.sum 
+5

आप इसे और अधिक संक्षिप्त बना सकते हैं जैसे 'xs |> List.choose (फ़ंक्शन कार (दयालु, _) -> कुछ (दयालु) | _ -> कोई नहीं) ' –

+0

धन्यवाद। आपका जवाब भी बहुत उपयोगी था (और आपके और लॉरेन के बीच फैसला करना मुश्किल था)। –