프로그래밍

#1 함수형 프로그래밍에서 모나드는 무엇인가?

암것두몰러유 2022. 4. 7. 01:23

함수형 프로그래밍에 대해 알아보다보면 모나드 얘기가 참 많이 나옵니다. 함수형 프로그래밍에서 모나드가 어떤 개념을 말하는지 알아보도록 하겠습니다.

수학적 대상

수학적인 구조를 말합니다. 정수, 자연수, 행렬, 집합, 군, 환 체, 카테고리 등등 입니다.

범주(카테고리)

위키백과를 보고 정리 해봤습니다. 범주는 아래의 내용으로 구성된다고 합니다.

  • 수학적 대상의 모임
  • 범주 안의 대상 A, B에 대하여 A를 정의역으로, B를 공역으로 하는 사상(morphism)의 모임
    • 프로그래밍 입장에서 사상은 꼭 범주 안의 대상 A, B를 정의역, 공역으로 할 필요는 없습니다.
  • 사상은 합성 가능합니다. (해당 사상을 수행하는 모든 집합의 곱집합)
  • 항등 사상이 존재 합니다. 
  • 결합법칙을 만족 합니다.
  • 항등원이 존재 합니다.

입니다. 

 

사상(morphism)은 뭘까?

정의역에서 공역으로 연결하는 것을 사상 이라고 한다. f: 자연수 -> 자연수 는 자연수에서 자연수로 연결하는 사상 이라고 말합니다. 프로그래밍적으로 생각해본다면 아래 morphism 함수는 string -> number로 연결하는 사상이겠네요

function morphism(text: string): number {
	return string.length;
}

text가 뭐가 들어올진 모르지만 좌우지간 숫자로 바뀝니다. 이게 사상 입니다.

 

함자(functor)

위키백과를 보고 정리 해보았습니다.

C와 D가 범주라 할때 C와 D사이의 함자 F: C->D는 아래의 내용으로 구성되어 있다.

  • C의 임의의 대상 X에 대응되는 D의 대상 F(X)
  • C의 임의의 사상 f: X->Y에 대해 대응되는 D의 사상 F(f): F(X)->F(Y)
  • 항등사상의 보존
  • 사상합성의 보존

입니다.

이해한대로 풀어 써보면 

  • 함자는 사상(함수)를 인자로 받습니다. 
  • 함자는 범주 C의 임의의 대상을 D의 대상이 존재 합니다.
  • 함자는 범주 C의 임의의 사상을 D의 사상이 존재 합니다. 

이것도 와닿지 않습니다. 프로그래밍 입장에서 살펴보겠습니다. 

const arr = [1, 2, 3, 4];
const morphism = (e) => e + 1
const identity = (e) => e // 항등사상
const result = arr.map(morphism) // [2, 3, 4, 5]

 

map 함수는 무엇일까요? map 함수가 바로 함자 입니다.

 

map 함수의 정의인 'map 함수를 통해 받은 함수의 파라미터로 어떤 배열의 모든 값을 하나씩 넣어 실행하고 그 결과들을 새로운 배열에 담아 리턴한다' 만으로 우리는 map 함자를 갖고있는 어떤 범주에 대해 유추할 수 있습니다. 네 맞습니다. 그 범주는 배열 입니다. 자연히 arr과 result가 하나씩 대응된다는 것도 map 함수의 정의에 따라 알 수 있습니다. 

 

우리가 사실 공부 할때는 'Array prototype에 map 함수가 있다' 고 배우지만, 수학적인 의미로는 'Array prototype의 map 함자의 정의에 따라 배열에서 배열로 대응하는 함수다.' 가 더 자연스럽습니다.

따라서 함자로부터 범주를 유추하고 범주의 성질도 알 수 있습니다(우리 입장에서는 length, forEach 등등의 속성과 메서드 입니다)

 

드디어 모나드, 모나드는 자기함자(endofunctor)입니다. 

위의 코드를 재탕하겠습니다. map 함자는 배열 범주에서 배열범주로 대응 한다고 하였습니다. 

const arr = [1, 2, 3, 4];
const morphism = (e) => e + 1
const result = arr.map(morphism) // [2, 3, 4, 5]

위와 같이 같은 범주로 대응하는 것을 모나드라고 합니다. 정의역과 공역이 같은 함자 입니다.

사실 배열 말고도 여러가지 모나드가 더 있습니다. 아래 코드를 보면

Promise.then(()=>{ ... }).then(()=>{ ... }).then(()=>{ ... }))

Promise도 역시 then을 함자로 갖고있는 모나드 입니다.

주어진 모나드 말고 우리가 직접 만들수도 있습니다. 앞으로 함수의 합성과 몇 가지 유명한 모나드들의 코드와 설명을 올려보도록 하겠습니다. 

 

이 내용을 몰라도 함수형 프로그래밍을 하는 것과 상관은 없습니다. 

하지만 우리가 무심코 쓰는 것들이 어떤 의미를 갖는지 생각해보는 것은 의미가 있다고 생각 합니다. 

 

 

(이 글은 제 과거 블로그 글을 다시 정리하여 쓴 글입니다. 지식이 일천하여 틀린곳이 있을 수 있습니다.)

'프로그래밍' 카테고리의 다른 글

#4 부수효과  (0) 2022.04.08
#3 maybe 모나드와 either 모나드  (0) 2022.04.08
#2 함수의 합성  (0) 2022.04.07
CSS 적용 우선순위  (0) 2022.04.06
typescript - enum 값에 따라 함수 타입 설정하기  (0) 2022.04.05