2015-11-18 6 views
9

निम्नलिखित नमूना कार्यक्रम में, क्या कोई तरीका है कि मैं map2 को परिभाषित करने से बच सकता हूं?क्या दो विकल्प "गठबंधन" करने के लिए कोई भी बनाया गया है?

fn map2<T, U, V, F: Fn(T, U) -> V>(f: F, a: Option<T>, b: Option<U>) -> Option<V> { 
    match a { 
     Some(x) => match b { 
      Some(y) => Some(f(x, y)), 
      None => None, 
     }, 
     None => None, 
    } 
} 

fn main() { 
    let a = Some(5); 
    let b = Some(10); 
    let f = |a, b| { 
     a + b 
    }; 
    let res = map2(f, a, b); 
    println!("{:?}", res); 
    // prints Some(15) 
} 

लोगों के लिए जो भी हास्केल बात करते हैं, मैं इस सवाल के रूप में भी phrased जा सकता है लगता है कि "वहाँ किसी भी उपकरण हम बजाय जंग में liftM2 का उपयोग कर सकते है?"

उत्तर

12

मैं वहाँ एक सीधा समारोह बराबर liftM2 को विश्वास नहीं है, लेकिन आप Option::and_then और इस तरह Option::map गठजोड़ कर सकते हैं:

fn main() { 
    let a = Some(5); 
    let b = Some(10); 
    let f = |a, b| { 
     a + b 
    }; 

    println!("{:?}", a.and_then(|a| b.map(|b| f(a, b)))); 
} 

आउटपुट:

Some(15) 
+0

धन्यवाद, कि वास्तव में के लिए जब आप केवल जरूरत है एक बहुत अच्छा समाधान है इसे एक या दो बार करने के लिए। हालांकि, कुछ मामलों में फ़ंक्शन को परिभाषित करने के लिए शायद इसके लायक है। –

4

आपको लगता है कि Option तथ्य का उपयोग कर सकते एस को फिर से चालू किया जा सकता है। दोनों विकल्पों पर Iterate, उन्हें एक साथ ज़िप, और परिणामी iterator अपने समारोह पर नक्शा।

fn main() { 
    let a = Some(5); 
    let b = Some(10); 
    let f = |(a, b)| { 
     a + b 
    }; 
    let res = a.iter().zip(b.iter()).map(f).next(); 
    println!("{:?}", res); 
    // prints Some(15) 
} 

यह f के संशोधन की आवश्यकता है, तो तर्क एक भी टपल-बहस में विलय कर रहे हैं। यह f को संशोधित किए बिना |args| f.call(args) पर सीधे मैप करके संभव होगा, लेकिन फिर आपको specify the closure kind of f करना होगा।

+0

वैकल्पिक: 'मानचित्र (| (ए, बी) | एफ (ए, बी))' – sellibitze

+0

हाँ, मैं फ़ंक्शन कॉल को दोहराने से बचने की कोशिश कर रहा था। यदि आप इसे दोहरा रहे हैं, तो @ डॉगबर्ट का समाधान बेहतर है। –

2

मैं अगर आप एक लाइन के लिए नीचे प्राप्त कर सकते हैं पता नहीं है, लेकिन आप एक टपल पर मेल द्वारा नेस्टेड match बच सकते हैं:

let a = Some(5); 
let b = Some(10); 
let f = |a, b| { 
    a + b 
}; 
let res = match (a, b) { 
    (Some(a), Some(b)) => Some(f(a, b)), 
    _ => None, 
}; 
println!("{:?}", res); 
// prints Some(15) 
संबंधित मुद्दे