Scala for Backend Engineering & Functional Programming · 강의

for 구문 풀어쓰기

map과 flatMap을 알아봅니다

레슨 1/413개 단계

for 구문 풀어쓰기은(는) CoddyKit의 무료 Scala for Backend Engineering & Functional Programming 강의입니다. 이것은 4개 중 1번째 강의입니다. 아래에서 전체 강의를 무료로 읽을 수 있으며, 내장 코드 에디터와 24/7 AI 튜터와 함께 브라우저에서 직접 실습할 수 있습니다. 이 강의는 Scala for Backend Engineering & Functional Programming 학습 경로의 일부이며, 진행 상황이 웹과 CoddyKit 앱에 동기화됩니다. Scala for Backend Engineering & Functional Programming 강의에는 총 4개의 강의가 포함되어 있습니다.

for-comprehension이란 무엇인가

Scala의 for-comprehension은 컬렉션 및 기타 컨테이너 타입을 다루기 위한 특별한 문법입니다. 명령형 반복문처럼 보이지만, 실제로는 컴파일러가 map, flatMap, filter, foreach 호출로 다시 작성하는 문법적 편의 기능입니다.

문법이 어떻게 단순화되는지 이해하면 사용자 정의 타입을 포함한 모든 for-comprehension의 동작을 추론할 수 있습니다.

object Main {
  def main(args: Array[String]): Unit = {
    val result = for (x <- List(1, 2, 3)) yield x * 10
    println(result)
  }
}

단일 생성기는 map이 됩니다

for-comprehension에 정확히 하나의 생성기가 있고 yield를 사용하면, 컴파일러는 이를 하나의 map 호출로 다시 작성합니다.

  • for (x <- xs) yield f(x)
  • 다음과 같이 됩니다: xs.map(x => f(x))
object Main {
  def main(args: Array[String]): Unit = {
    val a = for (x <- List(1, 2, 3)) yield x + 1
    val b = List(1, 2, 3).map(x => x + 1)
    println(a == b)
  }
}

yield 키워드

yield 키워드는 결과를 같은 종류의 새 컬렉션으로 수집하도록 Scala에 지시합니다.

yield가 없으면 for-comprehension은 각 요소에 대해 부수 효과를 수행하고 Unit을 반환합니다(foreach가 됩니다).

object Main {
  def main(args: Array[String]): Unit = {
    // No yield: side effect only
    for (x <- List("a", "b")) println(x)
    // With yield: builds a new List
    val upper = for (x <- List("a", "b")) yield x.toUpperCase
    println(upper)
  }
}

두 생성기는 flatMap + map이 됩니다

두 개 이상의 생성기가 있으면 바깥 생성기들은 flatMap이 되고 가장 안쪽 생성기는 map이 됩니다.

  • for (x <- xs; y <- ys) yield f(x, y)
  • 다음과 같이 됩니다: xs.flatMap(x => ys.map(y => f(x, y)))
object Main {
  def main(args: Array[String]): Unit = {
    val pairs = for {
      x <- List(1, 2)
      y <- List("a", "b")
    } yield (x, y)
    println(pairs)
  }
}

동등한 flatMap 확인하기

여기서는 같은 로직을 두 가지 방식으로 작성합니다. 두 방식이 같다는 사실은 for-comprehension이 특별한 기능을 추가하는 것이 아니라 읽기 편의성만 제공한다는 것을 보여 줍니다.

object Main {
  def main(args: Array[String]): Unit = {
    val sugar = for {
      x <- List(1, 2)
      y <- List(10, 20)
    } yield x + y

    val desugared = List(1, 2).flatMap(x => List(10, 20).map(y => x + y))

    println(sugar)
    println(sugar == desugared)
  }
}

바깥 생성기에 flatMap을 사용하는 이유

각 바깥 요소는 안쪽 결과의 전체 컬렉션을 만듭니다. 바깥 생성기에 map을 사용하면 List(List(...), List(...))와 같은 중첩 컬렉션을 얻게 됩니다.

flatMap은 중첩된 목록을 하나의 평평한 결과로 만듭니다.

object Main {
  def main(args: Array[String]): Unit = {
    val nested = List(1, 2).map(x => List(10, 20).map(y => x + y))
    val flat   = List(1, 2).flatMap(x => List(10, 20).map(y => x + y))
    println(nested)
    println(flat)
  }
}

yield가 없는 for는 foreach입니다

yield가 없는 for 반복문은 foreach로 다시 작성됩니다. 본문을 부수 효과를 위해 실행하고 Unit을 생성합니다.

  • for (x <- xs) doSomething(x)
  • 다음과 같이 됩니다: xs.foreach(x => doSomething(x))
object Main {
  def main(args: Array[String]): Unit = {
    val r: Unit = for (x <- List(1, 2, 3)) print(x + " ")
    println()
    println("Return type is Unit")
  }
}

결과 타입은 첫 번째 생성기를 따릅니다

결과의 타입은 첫 번째 생성기의 컬렉션에 따라 결정됩니다. List에 대한 for는 List를, Set에 대한 for는 Set을, Option에 대한 for는 Option을 반환합니다.

object Main {
  def main(args: Array[String]): Unit = {
    val fromList = for (x <- List(1, 2, 2, 3)) yield x
    val fromSet  = for (x <- Set(1, 2, 2, 3)) yield x
    println(fromList)
    println(fromSet)
  }
}

=로 값 바인딩하기

for-comprehension 안에서는 =를 사용해 중간 값을 바인딩할 수 있습니다. 이렇게 하면 재계산을 피하고 가독성을 높일 수 있습니다.

이는 추가 값을 튜플에 담아 전달하는 map으로 단순화됩니다.

object Main {
  def main(args: Array[String]): Unit = {
    val result = for {
      x <- List(1, 2, 3)
      doubled = x * 2
    } yield doubled + 1
    println(result)
  }
}

map/flatMap이 있는 모든 타입에서 작동

문법 단순화가 map과 flatMap에만 의존하므로, for-comprehension은 이러한 메서드를 정의한 모든 타입에서 작동합니다. 예를 들어 Option, Either, Try, Future 및 직접 만든 클래스에서 사용할 수 있습니다.

object Main {
  def main(args: Array[String]): Unit = {
    val combined = for {
      a <- Some(2)
      b <- Some(3)
    } yield a * b
    println(combined)
  }
}

진정한 장점은 가독성입니다

깊게 중첩된 flatMap/map 연결과 깔끔한 for-comprehension을 비교해 보세요. 둘은 같은 코드로 컴파일되지만, for 방식은 조리법처럼 위에서 아래로 읽힙니다.

object Main {
  def main(args: Array[String]): Unit = {
    val chained = List(1, 2).flatMap(a => List(3, 4).map(b => a * b))
    val readable = for {
      a <- List(1, 2)
      b <- List(3, 4)
    } yield a * b
    println(chained == readable)
  }
}

빠른 확인

두 생성기와 yield가 있는 for-comprehension을 컴파일러는 어떻게 단순화할까요?

복습

for-comprehension이 어떻게 단순화되는지 배웠습니다.

  • 생성기 하나 + yield → map
  • 여러 생성기 + yield → flatMap(바깥) + map(안쪽)
  • yield 없음 → Unit을 반환하는 foreach
  • val = 바인딩은 중간 값을 추가합니다.
  • 결과 타입은 첫 번째 생성기를 따릅니다.

map과 flatMap이 있는 모든 타입을 for-comprehension에서 사용할 수 있습니다.

무료로 시작

AI 튜터와 함께 Scala을(를) 배우세요 — 무료

브라우저에서 실제 코드를 작성하고 실행하며, 24/7 AI 튜터로부터 즉각적인 도움을 받고, 웹이나 앱에서 중단한 부분부터 계속 학습하세요.

코스
39
레슨
143

자주 묻는 질문

“for 구문 풀어쓰기” 강의는 무료인가요?

네 — “for 구문 풀어쓰기” 전체 내용을 이 웹사이트에서 무료로 읽을 수 있습니다. 인터랙티브하게 실습하려면(내장 코드 에디터와 24/7 AI 튜터), CoddyKit PRO로 업그레이드하면 Scala for Backend Engineering & Functional Programming 강의 전체를 잠금 해제할 수 있습니다. Scala for Backend Engineering & Functional Programming 강의에는 총 4개의 강의가 포함되어 있습니다.

“for 구문 풀어쓰기”에서 뭘 배우나요?

map과 flatMap을 알아봅니다 브라우저에서 직접 실행하는 실습 코드로 Scala for Backend Engineering & Functional Programming을(를) 배우며, 24/7 AI 튜터가 강의를 진행하면서 질문에 답변해줍니다.

Scala for Backend Engineering & Functional Programming을(를) 시작하는 데 경험이 필요한가요?

사전 경험은 필요하지 않습니다. CoddyKit의 Scala for Backend Engineering & Functional Programming은(는) 초급자부터 고급 학습자까지를 위해 구성되어 있으므로, 여기서 시작하거나 처음부터 시작할 수 있으며 자신의 속도대로 진행할 수 있습니다. 이것은 4개 중 1번째 강의입니다.

“for 구문 풀어쓰기” 강의는 얼마나 걸리나요?

대부분의 CoddyKit 강의는 약 5~10분이 소요됩니다. 각 강의는 간결하고 인터랙티브하여 꾸준한 진행이 가능하며, 웹과 앱에서 중단한 부분부터 바로 시작할 수 있습니다.

이 Scala for Backend Engineering & Functional Programming 강의에서 코드를 작성하고 실행할 수 있나요?

네. 모든 Scala for Backend Engineering & Functional Programming 강의에는 내장 코드 에디터가 포함되어 있으므로, 브라우저에서 바로 실제 코드를 작성하고 실행한 후 즉시 AI 피드백을 받을 수 있습니다 — 로컬 설정이 필요 없습니다.

이 강의의 모든 강의

  1. for 구문 풀어쓰기
  2. if로 필터링
  3. 여러 생성기
  4. Option과 Future 함께 사용
← Scala for Backend Engineering & Functional Programming(으)로 돌아가기