2017-04-23 20 views
7

डीईएफ़ विधि और वैल समारोह के साथ बनाम flatMap समतल:डीईएफ़ विधि और वैल समारोह के साथ बनाम flatMap समतल

मैं परिभाषित toInt नामक एक डीईएफ़ विधि:

def toInt(s: String): Option[Int] = { 
    try { 
     Some(Integer.parseInt(s.trim)) 
    } catch { 
     case e: Exception => None 
    } 
    } 

और इस विधि ठीक काम करता है निम्नानुसार flatten और flatMap दोनों के साथ:

//using toInt method 
val x = 1.to(5).toList 
val y = List("a") 
val z = x ++ y 
val q = z.map(_.toString) 

//using map and flatten 
println(q.map(toInt).flatten) 
//using flatMap 
println(q.flatMap(toInt)) 

अब मैंने इसे परिभाषित किया है INT (डीईएफ़ विधि के रूप में) कार्यक्षमता एक समारोह "tooInt" में वैल का उपयोग कर:

val tooInt: String => Option[Int] = s => { 
    try { 
    Some(Integer.parseInt(s.trim)) 
    } catch { 
    case c: Exception => None 
    } 
} 

इस समतल लेकिन नहीं flatMap साथ साथ ठीक काम करता है जैसा कि नीचे दिखाया:

//using map and flatten 
println(q.map(tooInt).flatten) 
//using flatMap // this has error 
**println(q.flatMap(tooInt))** 

आप कृपया मेरी मदद कर सके इसे समझने में?

q.flatMap(s => tooInt(s)) 

यह सब तथ्य यह है कि हम एक अंतर्निहित option2Iterable में परिभाषित किया गया है कि करने पर निर्भर करता:

शुभकामनाओं सहित, किरण

उत्तर

9

आप इस काम करने के लिए संकलक विस्तार के साथ एक छोटे से मदद की जरूरत है Option.scala। जब आप पहले map और फिर flatten, Option[Int] पहले से ही दायरे में हैं और निहित लागू किया जा सकता है। लेकिन जब आप flatMap, कंपाइलर को पहले tooInt से s => tooInt(s) तक विस्तार करना होगा और फिर निहित संकल्प लागू करना होगा, लेकिन यह काम नहीं करता है। यह क्यों काम नहीं करता है? क्योंकि संकलक प्रकार के अंतर्निहित दिखता है:

pt=(=> String => Option[Int]) => (String => scala.collection.GenTraversableOnce[?]) 

जो मौजूद नहीं है। इसके विपरीत, toInt विधि पहले एक समारोह प्रकार में विस्तार किया है, और फिर निहित Option[Int] के लिए खोज की है:

-- toInt : pt=String => scala.collection.GenTraversableOnce[?] BYVALmode-EXPRmode-POLYmode (site: value r in X) 
| | | | | | |-- { ((s: String) => toInt(s)) } : pt=String => scala.collection.GenTraversableOnce[?] BYVALmode-EXPRmode-POLYmode (site: value r in X) 
| | | | | | | |-- ((s: String) => toInt(s)) : pt=String => scala.collection.GenTraversableOnce[?] BYVALmode-EXPRmode-POLYmode (site: value r in X) 
| | | | | | | | |-- (s: String)Option[Int] : pt=scala.collection.GenTraversableOnce[?] EXPRmode (site: value $anonfun in X) 
| | | | | | | | | |-- s : pt=String BYVALmode-EXPRmode (site: value $anonfun in X) 
| | | | | | | | | | \-> String 
| | | | | | | | | [search #3] start `(s: String)Option[Int]`, searching for adaptation to pt=Option[Int] => scala.collection.GenTraversableOnce[?] (silent: value $anonfun in X) implicits disabled 
| | | | | | | | | [search #3] considering scala.this.Option.option2Iterable 

हम भी यह decompiled कोड में देख सकते हैं:

val r: scala.collection.immutable.IndexedSeq[Int] = q.flatMap[Int, scala.collection.immutable.IndexedSeq[Int]]({ 
    { 
     final <artifact> def $anonfun$main(s: String): Iterable[Int] = scala.this.Option.option2Iterable[Int](toInt(s)); 
     ((s: String) => $anonfun$main(s)) 
    } 
    }, immutable.this.IndexedSeq.canBuildFrom[Int]()); 
+0

भी क्ष। flatMap (भी INT (_)) काम करेगा। मुझे लगता है कि प्रश्न इस बात के बारे में है कि फ्लैटमैप को विधि क्यों पारित किया जा सकता है और फ़ंक्शन अक्षर नहीं हो सकते हैं। – jrook

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