Applicative Functor의 수학적 이해
Tags: applicative, functional, mathematics, category
Published: 2020-11-15 01:36:29

---
title: Applicative Functor의 수학적 이해
published: true
description: 
tags: applicative, functional, mathematics, category
cover_image: https://dev-to-uploads.s3.amazonaws.com/i/ei7qnclj9k3zydn2c333.jpeg
---

아래는 제가 생각했을때 가장 좋은 Applicative 를 설명하는 방법이에요.

이 글의 목적은 수학을 잘 모르더라도 Applicative Functor 의 수학적 배경을 이해할 수 있게끔 쉽게 설명하는것이 목적이에요.

모든건 매우 단순한 수학적 구조 중 하나인 *Apply* 로 부터 시작해요.

## Apply 란?

생소해서 뭔지 모르겠다고 생각하실 수도 있지만 절대 그렇지 않아요. 프로그래머라면 이미 Apply 마스터에요. Apply 는 2항 함수에요. 어떤 함수{% katex inline %}
f:X \rightarrow Y
{% endkatex %}와 {% katex inline %}
x \in X
{% endkatex %}를 받아서 {% katex inline %}
x
{% endkatex %}를{% katex inline %}
f
{% endkatex %}에 적용한 결과값을 리턴해요.

{%katex%}
\begin{aligned}
&\text{apply}:Y^X \times X \rightarrow Y \newline \\\\
&\text{apply}(f,x) = f(x)
\end{aligned}
{%endkatex%}

쉽게 말해서 우리가 프로그래밍과 수학에서 늘 쓰던 notation 인 f(x) 의 이름이에요. 대부분은 아마 apply 를 너무 당연한듯이 써와서 이름을 알 필요성도 못느꼈을거에요.

하찮아 보일 수도 있지만 apply 도 법칙이 있어요. 이름하야 Applicative rule 이죠.

### Rule 1 - identity

{% katex inline %}
\text{apply}(\text{id},x)
{% endkatex %} 는 언제나 {%katex inline%}
x 
{%endkatex%}를 그대로 리턴해야 해요. 여기서 `id` 는 파라메터로 받은 x 를 그대로 리턴하는 함수에요.

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/tiddq2u9eq8vhlb043jk.jpeg)

### Rule 2 - composition

다음이 성립해야 해요.

{%katex%}
\text{apply}(f, \text{apply}(g,x)) = \text{apply}( \text{apply}(\text{apply}( \cdot , f), g),x)
{%endkatex%}

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/osp5ajd0spx4re7c684n.jpeg)

> ###### 참고로 {% katex inline %}
\text{apply}( \cdot , f)
{%endkatex%}는 합성 함수{%katex inline%}
\cdot_f(g) = f \cdot g
{%endkatex%}의 curried 된 형태가 되어요.

위 매우 단순해보이는 법칙들이 수학과 프로그래밍이 고장나지 않게끔 유지해준답니다.

## Applicative Functor란?

수학적 구조를 보존한다는 컨셉은 수학의 근본중 하나이고, 모든곳에서 나타나요. 예를들어 행렬은 선형성을, homomorphism 은 대수적 구조를, 연속함수는 위상구조를, Functor 는 Categorical 구조를 보존해주죠.

Applicative Functor는 Categorical 구조와 더불어 Applicative rules 를 보존해주어요. 다른말로, Applicative functor는 universal constructor와, ({%katex inline%}\eta{%endkatex%} 라고 부를게요)
{%katex%}
\eta:X \rightarrow AX
{%endkatex%}
Functor *A* 로 lift 된 타입들을 위한 apply 인 {%katex inline%}
\text{apply}_A : A(X -> Y) -> AZ
{%endkatex%}을 제공해 주고,

합성 가능한 두 함수 {%katex inline%}
f
{%endkatex%} 와 {%katex inline%}
g
{%endkatex%} 그리고 g 의 도메인에 속한 {%katex inline%}
x
{%endkatex%} 가 주어졌을때, 이들이 {% katex inline %}
\eta
{%endkatex%} 로 transform 되었을때 Applicative rule 이 보존 된다는 뜻이에요.

{%katex%}
\text{apply}_A ( A\text{id}, A x) = A x
{%endkatex%}

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/m102eudpb8q45ntiwihv.jpeg)

{%katex%}
\text{apply}_A(Af, \text{apply}_A(Ag,Ax)) = \text{apply}_A( \text{apply}_A(\text{apply}_A( A, Af), Ag),Ax)
{%endkatex%}

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/ei7qnclj9k3zydn2c333.jpeg)

다시 말하지만, 수학적 구조를 보존하는것이 핵심이에요.

> ###### 참고로 {%katex inline%}\eta{%endkatex%} 는 프로그래머에게는 *pure* 혹은 *return* 로, {% katex inline %}\text{apply}_A{%endkatex%}는 *ap* 으로 많이 알려져있어요.

## “이항 함수를 위한 Functor” 로서의 Applicative Functor

많으 사람들이 Applicative Functor 를 “이항 함수를 위한 Functor” 로 알고있어요. Applicative rules을 보존하면 자연스럽게 이항 함수(혹은 이항 연산자) 구조가 보존되기 때문이죠. 그리고 이는 너무나도 유용하고 많이 쓰여요. 이게 어떻게 가능한지 알아볼게요.
다른말로 어떤 이항 함수 
{%katex%}+:X\times Y \rightarrow Z{%endkatex%}
와 Applicative Functor {%katex inline%}A{%endkatex%}
가 주여졌을때 우리는 다음과같은 새로운 이항 함수를 만들 수 있어요.

{%katex%}
+_A:AX \times AY \rightarrow AZ
{%endkatex%}

그리고 이는 원래 이항함수의 성질을 그대로 이어받아요. e.g associativity, identity, commutativity etc.

> ###### 왜 Functor 만으로는 이걸 할 수 없는지 생각해보는것도 많은 도움이 돼요. Functor 만으로 위 construction을 만들어 보려고 하면 금방 불가능하다는 것을 깨닳게 되죠. 이유는 object 로서의 함수가 등장하게 되는데, Functor 혼자선 apply 를 하기엔 너무 약하기 때문이죠. Functor는 함수가 object 가 아닌 morphism 으로서의 function 일 때만 apply 를 할 수 있어요.

아래와 같은 전개로써 construction 이 가능해요.

+ 를 currying 해 보면

{%katex%}
+ : X \rightarrow (Y \rightarrow Z)
{%endkatex%}

이 나오죠.
{%katex%}
+’ = \eta(+)
{%endkatex%}
새로운 +' 의 타입은
{%katex%}
A(X \rightarrow (Y \rightarrow Z))
{%endkatex%}
와 같아지는데 이제 여기에 {%katex inline%}\text{apply}_A{%endkatex%}를 적용해보면
{%katex%}
+’’ = \text{apply}_A (+’)
{%endkatex%}
그렇게 되면 새로운 +'' 의 타입은
{%katex%}
AX \rightarrow A(Y \rightarrow Z)
{%endkatex%}
함수가 된것을 볼 수가 있죠. 
이 함수를 이제 {%katex inline%}\text{apply}_A{%endkatex%} 와 함성해보면.
{%katex%}
+_A = \text{apply}_A(+’’)
{%endkatex%}
이 돼요. {%katex inline%}
+_A
{%endkatex%}의 타입은
{%katex%}
+_A : AX \rightarrow AY \rightarrow AZ
{%endkatex%}
이 되죠. 우리가 원하던 함수죠.

## 마무리



Applicative functor 는 너무나도 단순한 수학적 구조인 *apply*의 보존이에요. 어렵게 생각하실 것 하나도 없어요.