대수적 자료형이란?
대수적 자료형(Algebraic Data Types, ADT)이란 다른 타입의 결합으로 만들어지는 합성 타입을 말하며, 이러한 합성 타입은 수학적인 합(sum)과 곱(product)의 개념을 조합해서 만들어지게 됩니다.
곱타입(product)은 여러 값을 함께 가지며(AND를 뜻합니다) 대표적인 예시로 튜플(tuple)이나 우리가 평소에 객체지향적으로 프로그래밍하면서 만들게 되는 class 같은 자료형의 모음이 있습니다.
합타입(sum)은 타입의 모음 중 하나에만 속하게 되는 타입을 말하고(OR을 뜻합니다) 대표적인 예시로 enum class, sealed trait(interface) 같은 조합이 있습니다.
곱타입(product)과 합타입(sum)
곱타입(product)
곱타입은 개요에서 설명했듯이 여러 값을 함께 가져서 그 조합이 곱셈으로 늘어나는 타입을 말합니다.
예를 들어 scala의 Tuple 타입을 사용해서 객체를 만들경우 두 가지 필드가 있다면 그 타입이 만들 수 있는 경우의 수는 n * m만큼 늘어나게 됩니다. AND처럼 모든 필드를 보고 경우의 수가 곱셈으로 늘어나게 되니 product type이라고 말합니다.
// 이 튜플의 경우의 수는 Int의 범위 * Double의 범위가 됩니다
val tuple = (3, 150.0)
합타입(sum)
합타입은 개요의 설명처럼 타입의 모음 중 하나에만 속하게 되는 타입을 말합니다.
예를 들어 sealed trait로 생성한 닫힌 자료형의 모음이 있으면 해당 자료형에 속한 객체는 오로지 닫힌 자료형의 모음 중 하나에만 속하게 됩니다. OR처럼 경우의 수가 자료형의 모음에서 하나에만 속하게 되니 sum type이라고 말합니다.
// shape가 가능한 경우는 Circle, Rectagle의 2개 뿐입니다
sealed trait Shape
case class Circle(radius: Double) extends Shape
case class Rectangle(width: Double, height: Double) extends Shape
합타입과 곱타입의 패턴 매칭 차이점
곱타입에서의 패턴 매칭은 모든 경우의 수를 매칭할 수 없어서 if else문처럼 모든 경우의 수를 포함하는 구문이 있어야 안전하게 프로그래밍 할 수 있습니다.
trait NameCallable {
def name: String
}
case class User(name: String, age: Int) extends NameCallable
case class Product(name: String, price: Double) extends NameCallable
def callName(obj: NameCallable): Unit = obj match {
case u: User => println(s"사용자: ${u.name}")
case p: Product => println(s"물품: ${p.name}")
// 다른 경우의 수가 생겨도 컴파일러가 모르니 모든 경우의 수를 포함하는 매칭이 있어야 합니다
case other => println(s"모름: ${other.name}")
}
합타입에서의 패턴 매칭은 모든 경우의 수를 컴파일러가 알고 있어서 컴파일 단계에서 경우의 수를 처리할 수 있으니 항상 타입 안전하게 프로그래밍 할 수 있습니다.
sealed trait Expression
case class Const(value: Int) extends Expr
case class Add(left: Expr, right: Expr) extends Expr
def eval(expr: Expr): Int = expr match {
case Const(v) => v
case Add(l, r) => eval(l) + eval(r)
// 다른 경우의 수는 없다는 것을 컴파일러가 알고 있어서 컴파일 단계에서 처리할 수 있습니다
}
약어가 동일한 추상 자료형(Abstract Data Type)이라는 개념도 있습니다.
이는 객체지향 프로그래밍에서 자주 쓰이며, 캡슐화와 정보 은닉에 중점을 두어서 내부 구현을 숨기고 오직 외부 인터페이스만을 통해 동작하는 자료형을 말합니다.
추상 자료형은 리모컨처럼 어떻게 동작하는지 숨기고, 버튼만 보이게 해서 동작과 행위에 초점을 맞추는 것이고
대수적 자료형은 레고 블럭처럼 조합으로 표현해서 데이터에 초점을 맞추는 것입니다.
약어가 동일해서 헷갈리는데 아예 다른 개념이라고 생각하면 됩니다.