2012-11-27 15 views
7

मैं एक Dictionary जिस पर मैं शुरू में thusly दोहराया है:एफ # सक्रिय पैटर्न को समझने की कोशिश कर रहा, मैं क्यों ऐसा कर सकते हैं:

myDictionary |> Seq.iter (fun kvp -> doSomething kvp.Key kvp.Value)

बाद में, मुझे लगता है कि मैं KeyValue सक्रिय पैटर्न का उपयोग कर सकता की खोज की , और ऐसा करते हैं:

myDictionary |> Seq.iter (fun (KeyValue (k, v)) -> doSomething k v)

यह जानते हुए कि सक्रिय पैटर्न पूर्वप्रक्रमक निर्देश के कुछ फार्म नहीं कर रहे हैं, मैं कैसेस्थानापन्न करने में सक्षम हूँलैम्ब्डा में एक समारोह के लिए तर्क जो इसे विघटित करता है?

उत्तर

14

फ़ंक्शंस तर्क कॉल हमेशा पैटर्न मिलान का उपयोग करके नष्ट हो जाते हैं। उदाहरण के लिए:

let getSingleton = fun [x] -> x 
let getFirst = fun (a,b) -> a 
let failIfNotOne = fun 1 ->() 
let failIfNeitherOne = fun (x,1 | 1,x) ->() 

शब्दार्थ fun < पैट>-> < शरीर> मोटे तौर पर

fun x ->
match x with
| < पैट>-> < शरीर के बराबर है>
| _ -> raise MatchFailureException(...)

+0

धन्यवाद, यह एक आंख खोलने वाला, केवीबी है! मुझे निश्चित रूप से उस अंतिम उदाहरण को ध्यान में रखना होगा, विशेष रूप से। – MiloDC

5

मुझे लगता है कि पर्याप्त डीटा में @ केवीबी कवर से जवाब ils आप fun के तर्कों में पैटर्न का उपयोग क्यों कर सकते हैं। यह एक विज्ञापन-प्रसार सुविधा नहीं है - F # में, आप कहीं भी पैटर्न का उपयोग कर सकते हैं जहां आप एक चर को बांध सकते हैं। एक और संदर्भों में @kvb द्वारा उदाहरण के कुछ दिखाने के लिए: इसी प्रकार

// When declaring normal functions  
let foo [it] = it // Return the value from a singleton list 
let fst (a, b) = a // Return first element of a pair 

// When assigning value to a pattern using let 
let [it] = list 
let (a, b) = pair 

, आप पैटर्न का उपयोग जब fun लिख सकते हैं। match निर्माण थोड़ा अधिक शक्तिशाली है, क्योंकि आप एकाधिक खंड निर्दिष्ट कर सकते हैं।

अब, सक्रिय पैटर्न वास्तव में जादुई नहीं हैं। वे विशेष नामों के साथ सामान्य कार्य हैं। जब संकलक एक नामित पैटर्न पाता है तो संकलक सक्रिय पैटर्न के लिए खोज करता है।

val (|KeyValue|) : KeyValuePair<'a,'b> -> 'a * 'b 

पैटर्न एक सामान्य एफ # टपल जाता है कि उसके बाद एक नेस्टेड पैटर्न (k, v) (जो k और करने के लिए पहला तत्व प्रदान करती है से मिलान में एक KevValuePair वस्तु बदल जाता है: उदाहरण के लिए, पैटर्न का उपयोग कर रहे बस एक समारोह है दूसरा v)। कंपाइलर अनिवार्य रूप से आपके कोड का अनुवाद करता है:

myDictionary |> Seq.iter (fun _arg0 -> 
    let _arg1 = (|KeyValue|) _arg0 
    let (k, v) = _arg1 
    doSomething k v) 
+4

काफी हर जगह नहीं ... कम से कम 'उपयोग' बाइंडिंग और सदस्य घोषणाओं में 'यह' पहचानकर्ता पैटर्न के बजाए उचित पहचानकर्ताओं का उपयोग करने के लिए प्रतिबंधित हैं, दुख की बात है। – kvb

+4

@kvb सही और सत्य। निहित-रचनाकार वर्गों में 'स्वयं के रूप में' के लिए भी नहीं। मेरा मानना ​​है कि ये केवल तीन मामले हैं, जहां वास्तव में नाम का अर्थ है। –

+1

@kvb यह एक उत्कृष्ट बिंदु है, आह ठीक है, सिद्धांत और अभ्यास के बीच संघर्ष फिर से हमला करता है :-) –

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