2017-04-23 12 views
7

데프 방법과 발 기능에 대 flatMap을 평평 :데프 방법과 발 기능에 대 flatMap을 평평하게

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

그리고이 방법이 잘 작동 : 나는 toInt라는 데프 방법을 정의

다음과 같이 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)) 

이제는 동일한 toInt

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

당신이 좀 도와 주 시겠어요 : 함수 "tooInt"에서 발을 사용하여 (DEF 방법 등) 기능 : 아래 그림과 같이

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

이 flatMap와 평평하게하지만 하지와 함께 잘 작동 이걸 이해하는거야? 그것은 모두 우리가 암시 option2Iterable에 정의가 있다는 사실에 귀결

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

:

최고 감사합니다, 키란

답변

9

당신은이 일을하기 위해 확장을 컴파일러에게 약간의 도움이 필요 . 처음에 map을 입력 한 다음 flatten을 입력하면 Option[Int]이 이미 범위에 있고 암시 적으로 적용될 수 있습니다. 그러나 flatMap 때 컴파일러는 먼저 tooInts => 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 

우리는 또한이 디 컴파일 코드에서 볼 수 있습니다

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

도 Q를. flatMap (tooInt (_))가 작동합니다. 그 질문은 flatMap에 메소드를 전달할 수있는 이유와 함수 리터럴이 전달할 수없는 문제에 관한 것 같습니다. – jrook