관리자

https://docs.scala-lang.org/tutorials/FAQ/yield.html

 

for {...} yield 는 python의 yield와는 다르다.

 

python의 yield는 iterator를 만든다.

scala의 yield는 high order functionsyntactic sugar일 뿐이다.

 

scala는

for (enumerators) yield e

형태를 이용해서 sequence를 표현하는데, 이것을 for comprehension이라 한다.

https://docs.scala-lang.org/tour/for-comprehensions.html

 

for {...} yield는 이러한 for comprehension 형태로 high order function을 나타낸 것뿐이다.

 

javascript의 callback 지옥처럼, 여러 개의 high order function을 이용하면,

다음처럼 계속해서 nested되어 코드가 보기 좋지 않다.

l.flatMap(sl => sl.filter(el => el > 0).map(el => el.toString.length))

그래서 위 코드를 for{...} yield를 이용해서 다음처럼 바꿀 수 있다.

for{
  sl <- l
  el <- sl
  if el > 0
} yield el.toString.length

(예시는 scala documenation에서 가져왔습니다.)

 

실제로 for {...} yield 형태로 작성한 코드는 foreach, map, flatMap, filter, withFilter변환된다고 한다.

어떻게 변환되는지 알아보자

 

 

1.foreach

for(x <- c1; y <- c2) {...}
c1.foreach(x => c2.foreach(y => c3.foreach(z => {...})))

 

 

2.map

for(x <- c; y = ...) yield {...}
c.map(x => (x, ...)).map((x,y) => {...})

 

y = ... 부분이 없다면, vector가 만들어지는 기본 for {....} yield 가 된다.

생각해보면 당연히 이것은 map function과 동일하다

for(x <- c) yield {...}
c.map(x => (x, ...))

 

 

3.flatMap

for(x <- c1; y <- c2) yield {...}
c1.flatMap(x => c2.map(y =>{...}))

 

 

4. withFilter / filter

for(x <- c; if cond) yield {...}

withFilter가 정의되어 있으면 withFilter로,

withFilter가 정의되지 않으면 filter로 변환한다.

c.withFilter(x => cond).map(x => {...})

 

개인적으로 처음 for {...} yield를 사용할 때, high order function으로 변환된다는 것을 제대로 이해하지 못해 고생했다.

단순히 map의 chaining으로 변환된다고 생각해서 막무가내로 코드를 작성했는데, compile조차도 안되고 난리도 아니었다.

error 원인도 다양했다.

{} 안에서 <-가 안되거나, type mismatch, withFilter is not defined.... 등등

 

처음에는 withFilter is not defined를 보면서, 이게 왜 나오지...? 생각했는데,

high order function의 syntatic sugar라는 것을 알고 나니 이해가 되었다.

물론 그걸 이해했다고 해서 에러를 해결할 수 있는 것은 아니다...@

 

그리고 무조건적으로 high order function으로 바뀐다고 할 수도 없는 것 같다.

scala documentation에 

a syntactic sugar for composition of multiple monadic operations

라고 표현된 것을 보면, 추가적인 의미가 있는 것 같다.

 

몇 가지 실험한 결과를 정리해서 다른 글에 정리해보려 한다.

 

그리고 제발, documentation을 잘 읽자.....

+ Recent posts