2017-06-14 7 views
17

Operators.id<'T> Function (F#) से:FSharp.Core में `id` फ़ंक्शन का उद्देश्य क्या है?

पहचान समारोह।

पैरामीटर: एक्स प्रकार: 'टी (इनपुट मूल्य)

वापसी मान: एक ही मूल्य

एफ # कोर लाइब्रेरी संस्करण, में समर्थित: 2.0, 4.0, पोर्टेबल

क्यों क्या कोई ऐसा कार्य है जो अपना इनपुट देता है?

+3

गणितीय पृष्ठभूमि को भी ध्यान में रखना दिलचस्प है। 'कुछ भी नहीं' ऑब्जेक्ट होने से महत्वपूर्ण संरचना मिलती है।चूंकि शून्य संख्याओं के तहत संख्याओं की पहचान है, और एक गुणा के तहत संख्याओं की पहचान है, इसलिए 'आईडी' संरचना के तहत कार्यों के सेट के लिए एक पहचान है। और कार्यात्मक भाषाओं में आप अक्सर कार्यों के रूप में कार्यों को कुशल बनाना चाहते हैं, उन पर संचालन कर सकते हैं आदि –

+0

@matt_t_gregg अगर आप इसे उत्तर के रूप में पोस्ट करते हैं, तो मुझे यकीन है कि आपको कुछ अपवर्त मिलेगा। –

+0

@ फ्योडोर सोइकिन मैं बहुत खुश था कि आपके उत्तर में व्यावहारिकताओं को शामिल किया गया था कि इसकी आवश्यकता क्यों थी और उपयोग की गई - गणित की बात मैंने सोचा कि यह एक और दिलचस्प था। –

उत्तर

24

जब उच्च क्रम कार्यों के साथ काम करने (यानी कार्यों कि अन्य कार्यों वापसी और/या पैरामीटर के रूप में अन्य कार्यों लेने के लिए), तो आप हमेशा पैरामीटर के रूप में कुछ प्रदान करने के लिए है, लेकिन वहाँ हमेशा एक वास्तविक नहीं है डेटा परिवर्तन जो आप लागू करना चाहते हैं।

उदाहरण के लिए, फ़ंक्शन Seq.collect अनुक्रमों का एक अनुक्रम flattens, और एक समारोह लेता है जो "बाहरी" अनुक्रम के प्रत्येक तत्व के लिए "नेस्टेड" अनुक्रम देता है। उदाहरण के लिए, यह आप कैसे किसी प्रकार की यूआई नियंत्रण के सभी पोते की सूची प्राप्त हो सकता है:

let control = ... 
let allGrandChildren = control.Children |> Seq.collect (fun c -> c.Children) 

लेकिन समय की एक बहुत, अनुक्रम के प्रत्येक तत्व पहले से ही अपने आप में एक दृश्य हो जाएगा - उदाहरण के लिए तो आप सूचियां की एक सूची है हो सकता है:

let flattened = [ [1;2]; [3;4]; [5;6] ] |> Seq.collect (fun x -> x) 

यह अभिव्यक्ति:

let l = [ [1;2]; [3;4]; [5;6] ] 

इस मामले में, पैरामीटर समारोह है कि आप Seq.collect आवश्यकताओं के पारित सिर्फ तर्क लौटने की सायन fun x -> x एक ऐसा फ़ंक्शन है जो केवल अपना तर्क देता है, जिसे "पहचान फ़ंक्शन" भी कहा जाता है।

let flattened = [ [1;2]; [3;4]; [5;6] ] |> Seq.collect id 

इसका उपयोग फसलों ऊपर इतनी बार उच्च क्रम कार्यों (जैसे ऊपर Seq.collect के रूप में) है कि यह मानक पुस्तकालय में एक स्थान के पात्र के साथ जब काम कर रहे।

एक अन्य आकर्षक उदाहरण Seq.choose है - एक फ़ंक्शन जो Option मानों का अनुक्रम फ़िल्टर करता है और उन्हें एक ही समय में अनचाहे करता है।

let tryParse s = match System.Int32.TryParse s with | true, x -> Some x | _ -> None 
let strings = [ "1"; "2"; "foo"; "42" ] 
let numbers = strings |> Seq.choose tryParse // numbers = [1;2;42] 

लेकिन क्या साथ शुरू करने के लिए अगर आप पहले से Option मानों की सूची दिया जाता है: उदाहरण के लिए, यह कैसे आप संख्याओं के रूप में सभी स्ट्रिंग्स पार्स और उन जिसे पार्स नहीं किया जा सकता है त्यागने सकता है? बचाव के लिए पहचान समारोह!

let toNumbers optionNumbers = 
    optionNumbers |> Seq.choose id 
+0

'Seq.choose id' उदाहरण एक महान है, लेकिन 'Seq.collect id'' Seq.concat' कहने का एक कम पठनीय तरीका है। (उसने कहा, मुझे पूरा यकीन है कि मैंने कई बार 'Seq.collect id' लिखा है और यह दिखाता है कि' आईडी 'क्या करता है!) –

11

यह निश्चित उच्च आदेश कार्य (कार्यों कि तर्क के रूप में कार्य लेने के लिए) तो यह है कि आप के बजाय लैम्ब्डा (fun x -> x) बाहर लिखने के तर्क के रूप में id पारित कर सकते हैं के लिए उपयोगी है।

[[1;2]; [3]] |> List.collect id // [1; 2; 3] 
+0

इस मामले में, आप केवल 'List.concat' का उपयोग कर सकते हैं और यह अधिक पठनीय होगा :-)। –

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