And Brain said,
함수적인, 너무나 함수적인 - 2. 범주론 (Category Theory) 본문
Index
0. 함수형 프로그래밍
1. 람다 대수 (Lambda Calculus)와 합성함수
2. 범주론 (Category Theory)
3. 모노이드 (Monoide)
4. 펑터 (Functor)와 엔도펑터(Endo Functor)
5. 모나드 (Monad)
6 함수형 프로그래밍의 고급 기법
범주 (Category)
범주론 (Category Theory) 대수학의 한 분야로, 추상적인 수학구조를 다룹니다. 범주론 자체가 고도로 추상적인 분야이기도 하여 함수형 프로그래머인 우리는 수학자 수준의 이해가 필요하지 않습니다. 하지만, 범주론은 함수형 프로그래밍에서 사용되는 개념들의 수학적 배경을 제공하기에 짚고 넘어갈 필요가 있습니다.
범주의 정의는 무엇일까요? 범주란, 대상(Object)과 사상(Morphism)의 모음입니다. 범주는 다음과 같은 조건들을 만족할 때, 비로소 범주라고 불립니다.
각 대상 A에 대해 항등 사상(id_A)가 존재해야 합니다. 이 사상은 A에서 A로 가는 사상입니다.
사상의 연속성: 사상 f: A -> B와 g: B -> C가 주어졌을 때, 이 두 사상의 합성 g ∘ f: A -> C가 존재해야 합니다. 즉, 두 사상을 연결하여 하나의 사상으로 만들 수 있어야 합니다.
합성의 결합법칙: 세 개의 사상 f, g, h가 주어졌을 때, (h ∘ g) ∘ f = h ∘ (g ∘ f)가 성립해야 합니다. 이것은 사상을 연결할 때 순서가 중요하지 않다는 것을 의미합니다.
앞서, 함수의 합성까지 제대로 이해하셨다면, 크게 어렵진 않으실 겁니다만 이해가 안되셨다해도 괜찮습니다. 대상과 사상은 프로그래머들에게 친숙한 말들이 아닙니다.
그렇다면, 프로그래밍에서의 범주란 무엇일까요? 이를 알기 위해 먼저, 대상은 일반적으로 집합이라고 생각하신다면 편합니다.
그럼 이제, 이 집합이라는 개념 또한 쉽게 여러분들에게 매우 친숙한 하나의 예시로 바꿔봅시다. 무엇이 여러분들에게 매우 친숙한 집합일까요?
그건 바로 타입입니다. 타입이 곧 집합입니다. 각 타입은 그에 속하는 값들의 집합을 나타냅니다. 예를 들어, 정수 타입은 모든 정수를 포함하는 집합이고, 부울 타입은 참(True)과 거짓(False) 값만을 포함하는 집합입니다.
즉, 결론적으로 대상은 타입, 데이터 구조, 모듈 등과 같은 추상적인 개념입니다.
그렇다면 이번엔, 사상도 바꿔봅시다. 사상은 무엇일까요? 사상은 바로 화살표(Arrow)입니다. 화살표는 두 대상 사이의 관계를 나타냅니다. 프로그래밍에서 화살표는 함수, 변환, 매핑 등이 될 수 있습니다.
이제 어느정도 감이 오실겁니다. 그럼, 이번엔 프로그래밍으로 범주의 조건을 나타내볼까요?
interface Category<T> {
// 항등 함수를 나타내는 identity입니다. 입력된 값을 그대로 반환합니다.
// 범주론에서, 각 대상 A에 대해 항등 사상(id_A)가 존재해야 합니다.
identity: (x: T) => T;
// compose는 두 함수 f와 g를 합성하여 새로운 함수를 반환하는 함수입니다.
// 범주론에서, 사상 f: A -> B와 g: B -> C가 주어졌을 때, 이 두 사상의 합성 g ∘ f: A -> C가 존재해야 합니다.
compose<A, B, C>(f: (x: A) => B, g: (x: B) => C): (x: A) => C;
}
// testAssociativity 함수는 결합법칙이 성립하는지 테스트하는 함수입니다.
// 범주론에서, 세 개의 사상 f, g, h가 주어졌을 때, (f ∘ g) ∘ h = f ∘ (g ∘ h)가 성립해야 합니다.
function testAssociativity<U, V, T>(
categoryInstance: Category<T>,
f: (x: T) => U,
g: (x: U) => V,
h: (x: V) => T,
sampleInput: T
) {
// 왼쪽의 결합법칙 표현을 계산합니다: (f ∘ g) ∘ h
const leftSide = categoryInstance.compose(categoryInstance.compose(f, g), h);
// 오른쪽의 결합법칙 표현을 계산합니다: f ∘ (g ∘ h)
const rightSide = categoryInstance.compose(f, categoryInstance.compose(g, h));
console.log(`Left side result: ${leftSide(sampleInput)}`);
console.log(`Right side result: ${rightSide(sampleInput)}`);
if (leftSide(sampleInput) !== rightSide(sampleInput)) {
throw new Error("Associativity does not hold.");
}
}
// ex) 문자열을 처리하는 함수들
const stringCategoryInstance: Category<string> = {
identity: (x: string) => x,
compose: <A, B, C>(f: (x: A) => B, g: (x: B) => C): (x: A) => C => {
return (x: A) => g(f(x));
}
};
// Example
// 문자열을 처리하는 함수들
const toUpperCase = (x: string) => x.toUpperCase();
const exclaim = (x: string) => x + '!';
const repeat = (x: string) => x.repeat(2);
// testAssociativity 함수를 호출하여 문자열 타입으로 테스트합니다.
testAssociativity(
stringCategoryInstance,
toUpperCase, // f: string -> string
exclaim, // g: string -> string
repeat, // h: string -> string
"hello" // sampleInput은 string 타입
);
// Left side result: HELLO!HELLO!
// Right side result: HELLO!HELLO!
이제 아까 봤던 범주의 조건을 다시 한 번 봅시다.
각 대상 A에 대해 항등 사상(id_A)가 존재해야 합니다. 이 사상은 A에서 A로 가는 사상입니다.
사상의 연속성: 사상 f: A -> B와 g: B -> C가 주어졌을 때, 이 두 사상의 합성 g ∘ f: A -> C가 존재해야 합니다. 즉, 두 사상을 연결하여 하나의 사상으로 만들 수 있어야 합니다.
합성의 결합법칙: 세 개의 사상 f, g, h가 주어졌을 때, (h ∘ g) ∘ f = h ∘ (g ∘ f)가 성립해야 합니다. 이것은 사상을 연결할 때 순서가 중요하지 않다는 것을 의미합니다.
다시보니 범주란 것이 그닥 어려운 것이 아니라고 느껴지지 않나요? 아직은 이것을 어떻게 활용할지 감이 안 잡히시는 것은 괜찮습니다.
자, 그럼 정리해보겠습니다. 범주론은 추상적인 수학구조로, 대상(Object)과 사상(Morphism)의 모음인 범주를 다루는 학문입니다. 이 범주론 또한 함수형 프로그래밍에 적용할 수 있는데, 대상은 타입, 데이터 구조, 모듈 등과 같은 개념으로, 사상은 화살표(함수, 변환, 매핑 등)으로 나타낼 수 있습니다. 다음은, 모노이드에 대해 배워봅시다.
Thanks for watching, Have a nice day.
References
https://wikidocs.net/7056
https://teamdable.github.io/techblog/Moand-and-Functional-Architecture
'IT > 함수적인, 너무나 함수적인' 카테고리의 다른 글
함수적인, 너무나 함수적인 - 5. 모나드(Monad) (4) | 2023.05.01 |
---|---|
함수적인, 너무나 함수적인 - 4. 펑터 (Functor)와 엔도펑터(Endo Functor) (4) | 2023.04.22 |
함수적인, 너무나 함수적인 - 3. 모노이드(Monoid) (0) | 2023.04.17 |
함수적인, 너무나 함수적인 - 1. 람다 대수 (Lambda Calculus)와 합성 함수 (0) | 2023.04.16 |
함수적인, 너무나 함수적인 - 0. 함수형 프로그래밍 (0) | 2023.04.16 |