0Pricing
Scala for Backend Engineering & Functional Programming · 강의

합집합 타입과 교집합 타입

새로운 타입 기능

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

새로운 타입 기능

Scala 3는 타입 시스템에 합집합 타입(A | B)과 교집합 타입(A & B)을 추가합니다. 상속 계층 없이도 값을 더 정확하게 표현할 수 있습니다.

object Main:
  def main(args: Array[String]): Unit =
    println("Union: A | B, Intersection: A & B")

합집합 타입 기초

합집합 타입 A | B는 A이거나 B인 값을 나타냅니다. 타입에 대한 집합론적 OR입니다.

object Main:
  def show(x: Int | String): String = x match
    case i: Int    => s"int $i"
    case s: String => s"str $s"

  def main(args: Array[String]): Unit =
    println(show(42))
    println(show("hi"))

합집합에는 공통 상위 타입이 필요하지 않음

Scala 2의 Either와 달리 합집합 타입은 래핑할 필요가 없습니다. 두 타입이 같은 부모 클래스를 공유하지 않아도 서로 합칠 수 있습니다.

object Main:
  def parse(input: Int | Boolean): String =
    input match
      case n: Int     => s"number $n"
      case b: Boolean => s"flag $b"

  def main(args: Array[String]): Unit =
    println(parse(7))
    println(parse(true))

오류 모델링에 합집합 사용

합집합 타입은 래퍼 타입 없이 가벼운 오류 결과를 표현할 때 유용합니다. 열거형이나 싱글턴과 함께 사용하면 읽기 쉽게 표현할 수 있습니다.

case object NotFound

object Main:
  def lookup(id: Int): String | NotFound.type =
    if id == 1 then "Alice" else NotFound

  def main(args: Array[String]): Unit =
    println(lookup(1))
    println(lookup(2))

교집합 타입 기초

교집합 타입 A & B는 A이면서 동시에 B인 값을 나타냅니다. 집합론적 AND이며, 여러 트레이트를 결합할 때 자주 사용합니다.

trait Named:
  def name: String
trait Aged:
  def age: Int

object Main:
  def describe(p: Named & Aged): String =
    s"${p.name} is ${p.age}"

  def main(args: Array[String]): Unit =
    val person = new Named with Aged:
      def name = "Bob"
      def age = 40
    println(describe(person))

교집합은 교환 법칙을 따름

교집합 타입에서는 순서가 중요하지 않습니다. A & B는 B & A와 같은 타입입니다. 이는 Scala 2의 A with B 복합 타입과 다릅니다. 복합 타입은 일부 멤버 해석에서 순서의 영향을 받았습니다.

trait Readable:
  def read: String
trait Writable:
  def write(s: String): Unit

object Main:
  def use(r: Readable & Writable): Unit =
    r.write("x")
    println(r.read)

  def main(args: Array[String]): Unit =
    val rw = new Readable with Writable:
      def read = "data"
      def write(s: String) = println(s"wrote $s")
    use(rw)

여러 트레이트 결합

두 개보다 많은 타입을 교집합으로 묶을 수 있습니다. 그 결과는 나열된 모든 기능을 요구합니다.

trait A: def a: Int
trait B: def b: Int
trait C: def c: Int

object Main:
  def sum(x: A & B & C): Int = x.a + x.b + x.c

  def main(args: Array[String]): Unit =
    val v = new A with B with C:
      def a = 1
      def b = 2
      def c = 3
    println(sum(v))

합집합을 위한 타입 별칭

긴 합집합 타입은 type 별칭으로 이름을 지정해 시그니처를 읽기 쉽게 만들 수 있습니다.

type Json = Int | String | Boolean

object Main:
  def render(j: Json): String = j match
    case i: Int     => i.toString
    case s: String  => s"\"$s\""
    case b: Boolean => b.toString

  def main(args: Array[String]): Unit =
    println(render("hi"))
    println(render(true))

합집합의 모든 경우를 처리하는 패턴 일치

컴파일러는 합집합의 멤버를 알고 있으므로 패턴 일치가 모든 경우를 다루는지 확인할 수 있습니다. 모든 대안을 처리하면 완전한 패턴 일치가 됩니다.

type Shape = "circle" | "square"

object Main:
  def sides(s: Shape): Int = s match
    case "circle" => 0
    case "square" => 4

  def main(args: Array[String]): Unit =
    println(sides("square"))

합집합의 확장

합집합 값을 타입이 추론되는 변수에 할당하면 Scala는 합집합 타입을 유지합니다. 다만 일부 연산은 최저 상한으로 타입을 확장하므로 합집합을 유지하려면 타입을 명시해야 합니다.

object Main:
  def pick(flag: Boolean): Int | String =
    if flag then 1 else "one"

  def main(args: Array[String]): Unit =
    val x: Int | String = pick(false)
    println(x)

각 기능을 사용하는 경우

상황에 맞는 도구를 선택합니다.

  • 합집합: 값이 여러 타입 중 하나입니다(OR).
  • 교집합: 값이 여러 트레이트를 동시에 만족합니다(AND).
  • 합집합은 래퍼 타입을 피하고, 교집합은 깊은 상속을 피합니다.
trait Logger: def log(s: String): Unit
trait Clock:  def now: Long

object Main:
  def run(env: Logger & Clock): Unit =
    env.log(s"time=${env.now}")

  def main(args: Array[String]): Unit =
    val env = new Logger with Clock:
      def log(s: String) = println(s)
      def now = 100L
    run(env)

빠른 확인

합집합 타입과 교집합 타입에 대한 이해도를 확인해 보세요.

복습

Scala 3의 합집합 타입과 교집합 타입을 배웠습니다.

  • A | B: 값이 A이거나 B이며, 래퍼나 공통 부모가 필요하지 않습니다.
  • A & B: 값이 A이면서 B이고, 교환 법칙을 따릅니다.
  • 패턴 일치로 합집합의 타입 범위를 좁히고, 교집합으로 트레이트를 결합합니다.
  • type 별칭으로 긴 합집합에 이름을 지정합니다.
object Main:
  def length(x: String | List[Int]): Int = x match
    case s: String    => s.length
    case l: List[Int] => l.length

  def main(args: Array[String]): Unit =
    println(length("hello"))
    println(length(List(1, 2, 3)))

자주 묻는 질문

“합집합 타입과 교집합 타입” 강의는 무료인가요?

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

“합집합 타입과 교집합 타입”에서 뭘 배우나요?

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

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

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

“합집합 타입과 교집합 타입” 강의는 얼마나 걸리나요?

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

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

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

이 강의의 모든 강의

  1. 의미 있는 들여쓰기
  2. Scala 3의 열거형
  3. 불투명 타입
  4. 합집합 타입과 교집합 타입
← Scala for Backend Engineering & Functional Programming(으)로 돌아가기