-
Notifications
You must be signed in to change notification settings - Fork 36
23장 for expressions revisited
outsideris edited this page May 26, 2012
·
2 revisions
-
for문 형식 (seq : generator, definition, filter의 나열)
for ( seq ) yield expr
for (p <- persons; n = p.name; if (n startsWith "To"))
yield n
-
generator의 형식(expr은 보통 리스트를 리턴한다. pat은 패턴으로 리스트에 하나씩 대응된다.)
pat <- expr
-
definition의 형식 (패턴 pat에 expr의 값이 바인드된다.)
pat = expr
-
filter의 형식 (expr은 Boolean타입의 표현식으로 expr이 false인 모든 아이템은 버린다.)
if expr
##23.2 The n-queens problem
##23.3 Querying with for expressions
- for문을 쿼리문처럼 사용할 수 있다.
##23.4 Translation of for expressions
-
for문은 higher-order 함수인 map, flatmap, withFilter로 변환할 수 있다.
for ( x <- expr1) yield expr2 expr1.map(x => expr2)
for (x <- expr1 if expr2) yield expr3
for (x <- expr1 withFilter (x => expr2)) yield expr3
expr1 withFilter (x => expr2) map (x => expr3)
for ( x <- expr1; y <- expr2; seq) yield expr3
// seq는 generator, definition, filter의 나열
expr1.flatMap(x => for (y <- expr2; seq) yield expr3)
for ((x1, ..., xn) <- expr1) yield expr2
expr1.map { case (x1, ..., xn) => expr2 }
for (pat <- expr1) yield expr2)
expr1 withFilter {
case pat => true
case _ => false
} map {
case pat => expr2
}
for (x <- expr1; y = expr2; seq) yield expr3
for ((x, y) <- for (x <- expr1) yield (x, expr2); seq) yield expr3
for (x <- expr1) body
expr1 foreach (x => body)
for (x <- expr1; if expr2; y <- expr3) body
expr1 eithFilter (x => expr2) foreach (x => expr3 foreach (y => body))
##23.5 Going the other way
##23.6 Generalizing for
-
직접 정의한 타입도 필요한 메서드를 구현하면 for문을 완전히 지원할 수 있다.
-
규칙
- 타입이 그냥 map을 정의하면 단일 제너레이터르 구성된 for문이 가능하다. - 타입이 map과 flatMap을 정의하면 여러 제너레티어구 구성한 for문이 가능하다. - 타입이 foreach를 정의하면 for 루프를 사요할 수 있다.(하나이상의 제너레이터로) - 타입이 withFilter를 정의하면 for문에 if로 시작하는 필터를 사용할 수 있다.
-
for문의 변환은 타입체킹 이전에 일어나므로 아주 유연한 구조가 된다. 왜냐하면 for문 타입케트를 확장한 결과만 필요하기 때문이다. Scala는 for문에 어떤 타입규칙도 없고 map, flatMap, withFilter, foreach가 어떤 시그치너를 가지도록 강제하지 않는다.
- flatMap
-
map의 수행 결과가 List인 경우 List 해체 작업을 수행해줌
-
다중 for 문
for ( x <- List(1,2,3,4,5); y<- List('a','b','c','d','e')) { (x,y) }
-
map, flatMap, filter 버젼으로 변경하는 예제
scala> List(1,2,3,4,5) res1: List[Int] = List(1, 2, 3, 4, 5) scala> List('a','b','c','d','e') res2: List[Char] = List(a, b, c, d, e) scala> res1.flatMap( x => res2.map( y=> (x,y)) ) res3: List[(Int, Char)] = List((1,a), (1,b), (1,c), (1,d), (1,e), (2,a), (2,b), (2,c), (2,d), (2,e), (3,a), (3,b), (3,c), (3,d), (3,e), (4,a), (4,b), (4,c), (4,d), (4,e), (5,a), (5,b), (5,c), (5,d), (5,e))
-