2016-08-22 9 views
5

में दो (डबल विकल्प) को गुणा कैसे करें मेरे कोड में कुछ डबल विकल्प प्रकार हैं; मैं विकल्प.मैप फ़ंक्शन का उपयोग करके सफलतापूर्वक अब तक कुछ और किसी भी जगह पर मिलान करने की ज़रूरत को खत्म करने के लिए सफलतापूर्वक उपयोग नहीं कर रहा हूं और उन्हें ऊपर उठाए गए प्रकार के रूप में व्यवहार करना है, लेकिन मुझे यकीन नहीं है कि निम्नलिखित परिदृश्य में क्या करना है:एफ #

let multiplyTwoOptions option1 option2 : double option = 
    if not (option1.IsSome && option2.IsSome) then None 
    else Some (option1.Value * option2.Value) 

मेरे पास read है कि आपको इस तरह से IsSome का उपयोग नहीं करना चाहिए, लेकिन विकल्प (जहां तक ​​मैं देख सकता हूं, अनुक्रमिक रूप से पैटर्न मिलान के लिए, काफी लंबा लगता है)। मैं अभी भी एफ # के लिए काफी नया हूं इसलिए सोचा कि क्या एक और बेवकूफ तरीका है? मुझे लगता है कि शायद मुझे एक विकल्प की तरह कुछ चाहिए। फोल्ड 2 एक बार में दो विकल्पों पर कार्य करने के लिए लेकिन एक नहीं है।

उत्तर

10

पैटर्न घोंसला जा सकता है, यह उनकी महान शक्ति है। इस विशेष मामले में, आप टपल पर पैटर्न मैच कर सकते हैं:

match option1, option2 with 
| Some x, Some y -> Some (x * y) 
| _ -> None 
+0

आह! मुझे पता था * कुछ होगा, धन्यवाद – Dutts

9

सही जवाब वास्तव में निम्नलिखित:

https://fsharpforfunandprofit.com/posts/elevated-world/#apply

एक फिर कुछ कोड की जरूरत है इसके बारे में करने पर निर्भर करता निम्न उदाहरण:

module Option = 

    // The apply function for Options 
    let apply fOpt xOpt = 
     match fOpt,xOpt with 
     | Some f, Some x -> Some (f x) 
     | _ -> None 


let (<!>) = Option.map 
let (<*>) = Option.apply 

let a = Some(4) 
let b = Some(5) 

let multiplication = (*) 

//Some multiplication function applied on a and resulting function applied on b 
let res1 = Some(multiplication) <*> a <*> b 
let res2 = Some(*) <*> a <*> b 

//Map a onto multiplication function and resulting function applied on b 
let res3 = multiplication <!> a <*> b 
let res4 = (*) <!> a <*> b 


val res1 : int option = Some 20 
val res2 : int option = Some 20 
val res3 : int option = Some 20 
val res4 : int option = Some 20 

//The following is without any options to try to clarify the above 

let op = (*) //multiplication 
//let partialRes = (*) 4 
let partialRes = op 4 //make function for multiplying param with 4 
let fullres = partialRes 5 //use function for multiplying with 4 

val op : (int -> int -> int) 
val partialRes : (int -> int) 
val fullres : int = 20 

यह कह के लिए कारण यह है कि इसके बाद के संस्करण एक साथ में और Wlaschin क्या कॉल "ऊंचा दुनिया", या विकल्प में से बाहर काम कर सकते हैं है इस मामले में, और दोनों से सामान मिलाएं। एक प्रकार का। पूरी साइट या पुस्तक पढ़ें Wlaschin अच्छी माप के लिए लिखा है।

कोई फर्म एक विकल्प के रूप में कोई विकल्प लेने की आवश्यकता नहीं है और रैपिंग और अनचाहे को एक बार और सभी के लिए देखभाल की जा सकती है।

ऊपर कोड से पता चलता है (बेशर्म लिंक से चोरी हो, और कुछ हद तक फिर से लिखा), समारोह रिचर्ड की जरूरत है के रूप में:

Option.apply 

हाँ प्रतीकों संभवतः भ्रमित, खासकर जब से हम गुणा बात कर रहे हैं या * यहाँ होगा, लेकिन मानचित्र के लिए ये प्रतीक <!> और लागू करें < *> कुछ हद तक 'मानक' हैं।

मुझे लगता है कि कोड को पढ़ने के तरीके के संबंध में कोड में टिप्पणियां कम या ज्यादा सही हैं।

और हाँ, मैं शायद मेरी शिक्षण शैलियों ;-)

+0

इस बहुत अच्छी पोस्ट के लिए धन्यवाद, मुझे एक मिनट होने पर इसे ग्रोक करने की आवश्यकता होगी =) – Dutts

+2

मैं उसी वाक्य में 'ग्रोक' और 'मिनट' शब्द का उपयोग नहीं करूंगा ;-) विशेष रूप से इस विषय के लिए नहीं। मैं अभी भी इसे ग्रोक नहीं करता हूं, और यह सुनिश्चित करने के लिए कि मैं इसे सही समझता हूं, हर विवरण के बारे में बहुत सावधानी से सोचने की आवश्यकता है। और फिर मैं हमेशा आश्चर्य करता हूं: क्या मुझे यह सही मिला ... यह पोस्ट मुझे भी मदद करने के लिए किया गया था ... –

+2

यकीन नहीं है कि मैं इसे ** ** सही उत्तर कहूंगा। आवेदक फंक्शंस शायद ही एफ # पाठ्यक्रम का हिस्सा हैं। – scrwtp

3

आपका fold2 विचार पर काम करने की जरूरत मार्क बंद नहीं है। यहां तक ​​कि यदि यह मानक पुस्तकालय का हिस्सा नहीं है, तो आप आसानी से ऐसे कार्यों को कार्यान्वित कर सकते हैं।

यहाँ एक bind2 है:

module Option = 
    let bind2 f a b = 
     match a, b with 
     | Some a, Some b -> f a b 
     | _, _ -> None 

मैं bind3 के रूप में अच्छी तरह से इस्तेमाल देखा है, लेकिन है कि शायद यह खींच रहा है। मुझे संदेह है कि 3 से अधिक तर्कों के लिए बहुत व्यावहारिक उपयोग है। आप इसी तरह की योजना के बाद map, iter या fold की विभिन्न धर्मार्थियों को लागू कर सकते हैं।

यह आवेदक फ़ैक्टर का उपयोग करने के रूप में मजबूत या औपचारिक रूप से सुरुचिपूर्ण नहीं है, लेकिन यह अधिक वैचारिक ओवरहेड पेश किए बिना समस्या हल करता है।

3

मैं match के साथ जाना चाहते हैं, लेकिन एक विकल्प के रूप में आप भी से https://www.nuget.org/packages/FSharpx.Extras/

let multiplyTwoOptions option1 option2 : double option = 
    maybe { 
    let! x = option1 
    let! y = option2 
    return x * y 
    } 

maybe अभिव्यक्ति का उपयोग कर सकते आदानों match और अधिक सरल है का एक ज्ञात सेट के लिए करते हैं, आप ध्यान दें हूँ

maybe { 
    let! a = getAOption() 
    let! b = getBOption a 
    let! c = getCOption a b 
    return! getFinalOption a b c 
} 

बनाम

: maybe अभिव्यक्ति अब तदर्थ भाव के लिए अच्छे है

इसका भी आवेदक फ़ैक्टर शैली पर इसका लाभ है उदा। b उत्पन्न करने वाला फ़ंक्शन a पर निर्भर करता है, और ca और b पर निर्भर हो सकता है, और इसी तरह, जो आवेदक शैली में संभव नहीं है। गणना अभिव्यक्ति वाक्यविन्यास भी आवेदक फंक्चररों की तुलना में समझना आसान बनाता है जिनमें कच्चे ऑपरेटरों के अलावा कुछ भी नहीं है।