2012-08-13 6 views
3

옵션의지도를 접을 때 짧은 손이 있는지 궁금합니다. 이 문제를 해결하려면 예를Scala, collapsing 옵션의 옵션

def divideByThree(x:Int) = if (x == 0) None else Some(x/3) 

val result = Some(6) map (divideByThree(_)) 
resut:Option[Option[Int]] = Some(Some(2)) 

위해 나는 약간 무거운가는 것 같습니다

val result = Some(6) match { 
    case Some(i) => divideByThree(i) 
    case None => None 
} 

을한다. Option에 대해 암시 적 함수를 만들면 mapOption을 처리 할 수 ​​있지만 생각하지 않은 것이 더 좋은지 궁금합니다.

def divideByThree(x:Int) = if (x == 0) None else Some(x/3) 

val opx = None // Or: Some(10) 
val mapped = opx.flatMap(divideByThree) 

println(mapped) 
+1

[모나드 재발견] (http://blog.sigfpe.com/2006/08/you-could-have-invented-monads-and.html)! 'flatMap' /'mapOption'과 같은 함수를 제공하는 중첩 구조를 무너 뜨릴 수있는 능력은 모나드를 구성하는 것의 절반이며, 값 (여기서는'Some')을 삽입하는 방법을 제공합니다 (그리고 후자에서는 'map' 연산). –

답변

9

당신은에서와 같은 flatMap을 사용할 수 있습니까? 그것은 수행거야 map 다음 flatten

val result = Some(6) flatMap (divideByThree(_)) 
result: Option[Int] = Some(2) 
+0

당신이 그것을 한 번 본 모든 명백한 그것의 종류. 옵션을 (최대로) 하나의 요소 목록으로 생각하는 것은 언제나 좋은 알림입니다. 건배! –

2

방법에 대한 flatMap() :

1

스칼라는 모나드 구문의 종류가 있습니다 이해를 위해

val div = (case x if x%3 == 0 => x/3} : PartialFunction[Int,Int]).lift 
val exp = (l : Option[Int]) => for { 
      x <- l 
      r <- div(x) 
      } yield r 

테스트를 그것을 : 당신은 당신의 방법에있어

scala> exp(Some(3)) 
res1: Option[Int] = Some(1) 

scala> exp(Some(4)) 
res2: Option[Int] = None 

scala> exp(None) 
res3: Option[Int] = None