2016-08-04 7 views
6

तक प्रयास करें मेरे पास एक ऐसा फ़ंक्शन है जो इनपुट लेता है और या तो सफल होता है और देता है कुछ इनपुट या रिटर्न कोई नहीं। मैं उदाहरण को फ़ोन नंबरों की एक सूची बनाउंगा जो डायल किए जाएंगे जब तक कोई संख्याओं में से किसी एक का उत्तर न दे, और फिर शेष संख्याओं को छोड़ दिया जाना चाहिए। और अंत में एक सफल संख्या या एक त्रुटि संदेश का लॉगिंग है।एफ # idiomatic

मेरा पहला समाधान मुझे लगता है कि बहुत ही जटिल है और यह भी पहली कोशिश है, जो असजीला लगता है पर विफलता राज्य के एक बोने का उपयोग करता है:

type PhoneNumber = int 

let tryCallNumber phoneNumber = 
    if phoneNumber % 2 = 0 then Some phoneNumber 
    else None 

let nextCall phoneNumberOption nextNumber = 
    match phoneNumberOption with 
    | Some num -> phoneNumberOption 
    | None  -> tryCallNumber nextNumber 

let logCall phoneNumberOption = 
    match phoneNumberOption with 
    | Some num -> printfn "%i" num 
    | None  -> printfn "%s" "failed" 


let phoneNumbers = [111; 222; 444; 555] 

do List.fold (fun state num -> (nextCall state num)) None phoneNumbers 
|> logCall 

मैं इसे कड़ी कर दी गई एक बेहतर सूची समारोह के साथ, tryPick:

type PhoneNumber = int 

let tryCallNumber phoneNumber = 
    if phoneNumber % 2 = 0 then Some phoneNumber 
    else None 

let logCall phoneNumberOption = 
    match phoneNumberOption with 
    | Some num -> printfn "%i" num 
    | None  -> printfn "%s" "failed" 


let phoneNumbers = [111; 222; 444; 555] 

do List.tryPick (fun num -> tryCallNumber num) phoneNumbers 
|> logCall 

क्या यह एक अच्छा दृष्टिकोण जैसा प्रतीत होता है? मोनैडिक एरर हैंडलिंग के बारे में पढ़ने के बाद, मुझे आश्चर्य है कि मुझे उस भावना में कुछ और करना चाहिए।

+4

'List.tryPick' का उपयोग कर आपका समाधान ठीक उसी कोड जैसा दिखता है जो मैं लिखूंगा ... –

+0

धन्यवाद टॉमस। अपने उत्तर की सराहना करें। – RomnieEE

+5

लैम्बडा को 'List.tryPick' पर पास किया गया है, केवल 'tryCallNumber' – TheQuickBrownFox

उत्तर

3

मूर्खता को मापना मुश्किल है। मुझे लगता है कि आपका दृष्टिकोण निकटतम से अधिक मूर्खतापूर्ण है। और तुम टॉमस की प्रवेश बंद मिल गया है ... मैं function शॉर्टकट logCall के लिए पाइप phoneNumbers में जोड़ना होगा, ड्रॉप do,, ईटा-को कम tryCallNumber लैम्ब्डा:

let phoneNumbers = [111; 222; 444; 555] 

let tryCallNumber phoneNumber = 
    if phoneNumber % 2 = 0 then Some phoneNumber 
    else None 

let logCall = function 
| Some num -> printfn "%i" num 
| None  -> printfn "failed" 

phoneNumbers 
|> List.tryPick tryCallNumber 
|> logCall 

निजी तौर पर (दुर्भाग्य से गैर .NET/F # मानक-lib में -idiomatic), मैं tryCallNumber का नाम केवल callNumber पर पुनर्नामित करता हूं, क्योंकि आईएमओ option रिटर्न प्रकार पर्याप्त स्पष्ट हैं और मेरा कोड try -heavy और अपवादों पर निर्भर नहीं है। async -by-default लाइब्रेरीज़ के समान जहां ...Async प्रत्यय गिरा दिया गया है।

+1

लेकिन एक विकल्प को वापस करने के लिए 'try'-prefixed शुद्ध फ़ंक्शन के लिए F # मानक लाइब्रेरी में एक उदाहरण है - उदा। 'List.tryFind' - जब एक गैर-प्रीफिक्स्ड समकक्ष होता है जो अपवाद फेंक सकता है। तो मैं अक्सर उस सम्मेलन का भी पालन करता हूं। मुझे यकीन नहीं है कि 'tryCallNumber' वैसे भी बहुत लंबे समय तक शुद्ध रहेगा। वर्तमान कार्यान्वयन प्लेसहोल्डर की तरह लगता है। – TheQuickBrownFox

+0

@TheQuickBrownFox हां, बिल्कुल। मुझे इसे और स्पष्ट करना चाहिए था कि यह मूर्खतापूर्ण नहीं है (अब)। उम्मीद है कि यह अंततः बदल जाएगा :-) – CaringDev

+0

टिप्पणियों के लिए धन्यवाद। यह बहुत आसान था! (लेकिन मैंने इसे पाने के लिए एक चौराहे का मार्ग लिया ...) लेकिन मैं इसे पॉइंटर्स से अभी भी थोड़ा सा परिष्कृत करूंगा। एक बार फिर धन्यवाद। – RomnieEE