함수형 프로그래밍과 카테고리 이론 (Category Theory)

[원본 링크]

카테고리 이론은 함수형 신자들이 경전처럼 외는 함수형 프로그래밍의 핵심 이론 중 하나다.

함수형 프로그래밍의 많은 특성들이 이 이론적 토대 위에서 만들어졌다고 보면 된다.

여기서는 기본적인 부분들만 간단하게 정리해본다.




수학의 Category Theory

Category Theory은 원래 프로그래밍과 전혀 관련이 없는 수학 이론 용어였다.
1940년대에 수학자들이 algebraic topology라는 것을 연구하던 과정 중에 만들어진 부산물이다.

대수학, 위상수학, 논리학 등의 다른 수학 분야들을 카테고리라는 단위로 추상화해서 상호간의 변환을 할 수 있게 하는 메타-수학 같은 것이라고 보면 된다.
각 수학 장르가 category고, 이 category들 간의 변환을 정의하는 것이 functor다.

근데 수학으로서의 Category Theory이 지금 중요한건 아니니까, 대충 넘기겠다.




Haskell과 Category Theory

프로그래밍에 category theory을 들여온 주범이 바로 하스켈이다.
80-90년대에 이걸 끌고 들어와서 현대 함수형 프로그래밍의 뼈대를 세웠다고 보면 된다.

아무튼, Category Theory의 핵심 구성 요소는 둘이다.
모든 값과 함수를 나타내는 Category, 그리고 카테고리 간 변환을 정의하는 Functor.

2가지 용어를 기준으로 이론의 얼개만 간략하게 정리해본다.



Category

하스켈 내에서는 Category를 Hask라고 부른다.
대부분의 구성요소는 카테고리에 속한다.

기본 카테고리로는 다음과 같은 것들이 있다.



Functor

이제 저 타입과 타입, 카테고리와 카테고리 사이의 변환을 구조를 유지하며 수행할 수 있게 해주는 추상화 장치가 Functor다.
이게 용도가 개념이 좀 복잡하게 느껴질 수도 있는데, 구현 관점에서 보면 "변환 가능한 형태의 제너릭 타입" 정도로 이해할 수 있다. 결국은 그냥 좀 더 넓은 개념의 제너릭 컨테이너다.

대표적인 Functor로는 Maybe가 있다.
Maybe는 값이 존재할 수도 있고 아닐 수도 있는 것을 나타내는 Functor(정확히는 Monad) 타입인데, 이걸 통해서 값의 변환을 수행하고, 타입 수준에서 유효하게 변환이 된 것인지 아닌지를 처리할 수 있다.

하스켈의 List도 Functor에 속한다.
List는 다음과 같이 functor연산을 수행할 수 있고, [Int] 같은 형태로 타입 파라미터를 받아서 정의되기 때문이다.

fmap (+1) [1, 2, 3]  -- [2, 3, 4]

기본 자료구조가 이런 거창한 것이라는게 이해가 잘 되지 않을 수도 있는데, functor는 그 자체로 특수화된 개념이 아니라, 공통 패턴을 추상화하는 것에도 목적이 있다.

그리고 IO - 입출력 수단 또한 Functor에 속한다.
IO 또한 제너릭 타입의 형태로 표현이 되는데

  getLine :: IO String
  -- "String을 반환할 계산"을 표현

  readFile "test.txt" :: IO String
  -- "파일을 읽어서 String을 돌려줄 계산"의 명세

내부 동작은 좀 이질적일지언정, 이 또한 결국 어떠한 값을 내보내는 제너릭 컨테이너로서 동작하기 때문이다.
더 정확히 말하면 "미래의 값"을 갖고 있는 제너릭 컨테이너라고 보면 된다.

저 자체로는 특수한 동작을 하지는 않고, fmap으로 "실행을 계획"하고 나중에 실행을 트리거하면 IO functor가 내부적으로 기능하면서 실제 입출력을 수행하는 식으로 동작한다.

  -- 파일 읽어서 길이 구하기
  fileLength :: IO Int
  fileLength = fmap length (readFile "test.txt")

... 
    main = do
    value <- fileLength  -- 여기서 IO 실행해서 가져오기!

이런 느낌이다.




카테고리 이론의 구현

하스켈이 카테고리 이론을 컴퓨팅 세계로 가져오긴 했지만, 하스켈만의 전유물은 아니다.

카테고리 이론을 거의 완벽하게 구현했다고 알려진 언어는 다음과 같다.

  1. Haskell

  2. Scala

  3. Purescript



그 외에는 부분적으로 실용성이 높은 Monad 개념만을 수입해서 구현한 언어들이 제법 있다.
그렇게 취사선택해서 적당히 사용한 대표적인 언어는 Rust, F#, Kotlin, Swift 등이다. 하지만 카테고리 이론을 구현했다고 말하지는 않는다.



참조
https://en.wikipedia.org/wiki/Category_theory
https://en.wikibooks.org/wiki/Haskell/Category_theory