Skip to content

rae-han(5주차): 5. 실전 함수형 프로그래밍.md #17

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jun 12, 2025
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
81 changes: 81 additions & 0 deletions raehan/5. 실전 함수형 프로그래밍.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
## 함수 합성 vs 함수 조합의 합성

### 함수 합성

```typescript
const f = (x: number) => x + 1;
const g = (x: number) => x * 2;
const h = (x: number) => f(g(x)); // 2를 곱한 뒤 1 더하기
```

### 함수 조합의 합성

```typescript
const h = async (f, g) => {
await f();
await g();
};
```

함수 합성과 함수 조합의 합성을 구분하는 것은 함수형 프로그래밍에서 중요하다. 여러 함수를 **값의 흐름**으로 연결해서 하나의 함수로 만드는 걸 함수 합성이라 한다. **값을 변형하는 함수 합성**과 달리 작업을 순서대로 실행하는 것은 **함수 적용의 합성**이다.

## 값으로 다루는 부수 효과

### 부수 효과가 있는 코드

```typescript
const result = await apiCall();
if (result.ok) {
alert("성공");
}
```

함수형 프로그래밍에서는 순수 함수와 순수 효과를 구분한다. 또한 이런 효과도 값으로 다루려고 한다.

```typescript
type Result<T, E> = { type: "ok"; value: T } | { type: "err"; error: E };

const handlePayment = async (): Promise<Result<SuccessData, ErrorInfo>> => {
try {
const res = await api();
return { type: "ok", value: res };
} catch (err) {
return { type: "err", error: err };
}
};
```

위 코드는 `try/catch` 없이 로직을 안전하게 처리할 수 있고, 그 **결과값(Result)** 을 기준으로 분기 후 **실제 효과만 따로 실행한다.**

## 조건을 값으로 다룬다면??

**패턴 매칭이 언어 레벨에서 지원되는** (모던한?)**언어**에서 프로그래밍을 한다면 `if/else` 같은 제어문보다 **조건 자체를 값처럼** 다루는 방식이 흔합니다. 자바스크립트에서도 현재 TC39의 Stage 1까지 올라와 논의 중이다.

기존 Javascript의 조건문에는 다음과 같은 단점이 있다.

- 기존 JS의 **`switch`**문은 오직 값의 동등성(===)만 비교할 수 있고,
fallthrough(의도치 않은 다음 case 실행), 스코프 불명확, 표현식으로 사용 불가 등 많은 한계가 있다.
- **`if/else`**는 강력하지만, 중첩 구조나 값 추출이 필요한 경우 매우 장황하고 반복적이다.
- 구조 분해(destructuring)는 값 추출은 가능하지만, 조건 분기와 결합이 어렵다.

패턴 매칭은 함수형 언어에서 널리 쓰이는 선언적 분기 방식으로, 값 중심, 불변 데이터, 구조 분해 등 함수형 프로그래밍 패러다임에 매우 적합하다. 복잡한 데이터 구조를 간결하게 처리하고, 함수형 프로그래밍 스타일에 적합하다.

### filter와 if문

**filter**는 배열 등 컬렉션에서 "조건을 만족하는 값만 골라내는 함수형 고차함수"이다. 즉, 조건에 따라 "새로운 배열(값)"을 만든다. 내부적으로는 각 요소마다 if문으로 조건을 검사하지만, 코드 흐름이 아니라 **'값'**을 만드는데 집중한다.

**if문**은 "조건에 따라 코드 흐름을 바꾼다"는 명령형 제어문이다. 값이 아니라, "어떤 블록을 실행할지"를 결정한다. 배열 전체가 아니라, 단일 값이나 흐름 제어에 더 적합하다.

### Pattern matching

- 단순 비교뿐 아니라, 구조체/객체/튜플/enum 등 복잡한 데이터 구조를 한 번에 분해하고,
- 여러 패턴을 한 번에 선언적으로 나열할 수 있다.
- if문은 boolean 조건 하나만 검사할 수 있지만, **패턴매칭은 구조, 타입, 값, 여러 조건을 동시에 검사하고 분해** 할 수 있다.

## 번외 Effect-TS

- **Promise**: 비동기 연산의 결과(성공/실패)를 값으로 캡슐화함.
- **패턴 매칭**: 조건 분기와 값 추출을 선언적으로, 값 자체처럼 다룸.
- **Effect**:
- 네트워크 요청, 파일 IO, 실패, 성공, 의존성 주입 등 "실행의 효과"를 값(Effect 객체)으로 표현함.
- Effect 객체는 실행 전까지 아무 일도 일어나지 않으며, 여러 Effect를 조합하고, 변환하고, 조건에 따라 분기하는 등 **모든 효과를 값처럼 조립** 할 수 있음