2014-05-22 2 views
0

을 감안할 때 이러한 정의 :옵션으로 시작하여 스칼라에서 컴파일을하지 않는 이유는 무엇입니까?

val guys = List("Albert", "Tom") 
val girls = List("Mary", "Stacy", "Josie") 

val optRoom: Option[String] = Some("Room 303") 

이 날 List[String] 기대에 평가 : 루프 내부의 일을 조금 돌리면

for { 
    guy <- guys 
    girl <- girls 
    room <- optRoom 
} yield { 
    s"$guy dances with $girl in $room" 
} 

을, 나는 이것이 Option[List[String]]로 평가 기대하지만, 그것도하지 않습니다 컴파일 :

for { 
    room <- optRoom 
    guy <- guys 
    girl <- girls 
} yield { 
    s"$guy dances with $girl in $room" 
} 

왜 안 되니? 내가 뭘 놓치고 있니? (나는 optRoot을 시퀀스 /리스트/iterable로 변환 할 수 있지만, 원하는 것은 아니다)

Option[List[String]]을 얻으려면 코드를 어떻게 다시 작성해야합니까?

답변

2

두 번째 예는 당신이 OptionoptRoom.flatMap에 반환하지 않는 때문에 작동하지 않습니다

optRoom flatMap { room => 
    guys flatMap { guy => 
    girls map { girl => 
     s"$guy dances with $girl in $room" 
    } 
    } 
} 

에 해당합니다. 답에 대한

for { 
    room <- optRoom 
} yield for { 
    guy <- guys 
    girl <- girls 
} yield { 
    s"$guy dances with $girl in $room" 
} 
+0

감사합니다 : 당신이 Option[List[String]]을 원하는 경우에 당신이 Option에 싸여 결과를 원하기 때문에

은, 당신은하지 flatMapoptRoom.map를 호출 할 수 싶습니다. 당신은 "optRoom.flatMap'에'Option'을 반환하지 않기 때문에 말합니다. 그렇게 할 수 있습니까? 그것은 의미가 있습니까? –

+0

'optRoom'이 'None'이 아닌 경우 계산 한 결과가 자연스럽게'Option [something]'입니다. 귀하의 경우에는 자연스럽게 'List [String]'입니다. 그래서 당신은'Some [List [String]]'으로 변환 할 수 있습니다,하지만'flatMap'을'map'을 에뮬레이트하기 위해서 사용하고 있습니다. –

1

당신은 할 수 있습니다 :

optRoom.map(room => for { 
    guy <- guys 
    girl <- girls 
} yield s"$guy dances with $girl in $room") 

for 대략로 번역됩니다 2 귀하의 :

optRoom.flatMap(room => guys.flatMap(guy => girls.map(girl => s"$guy dances with $girl in $room"))) 

당신이이 매개 변수가 String => Option[B]에서 기능입니다 것으로 예상된다 optRoom.flatMap(room => ...)을 가지고 있기 때문에,하지만 guys.flatMap(...)은 아니다 유형은 Option입니다.