---
type: snippet
tags: ['fp']
status: release
ctime: 2025-02-02
mtime: 2025-02-02
---

import QuoteLink from '@components/QuoteLink.astro'

<QuoteLink url="https://janhesters.com/blog/unleash-javascripts-potential-with-functional-programming">
Unleash JavaScript's Potential with Functional Programming
</QuoteLink>

```ts
/**
 * - 인자 수 확인: `curry` 함수는 전달된 함수 `fn`의 인자 수를 확인
 * - 인자 수가 충분한 경우: 만약 `args`의 길이가 `fn`의 인자 수 이상이면, `fn`을 호출하고 결과를 반환
 * - 인자 수가 부족한 경우: 그렇지 않으면 추가 인자(`moreArgs`)를 받을 수 있는 새 함수를 반환. 이 함수는 기존 인자(`args`)와 새로운 인자(`moreArgs`)를 합쳐 다시 `curry(fn)`을 호출하여 최종적으로 인자가 충분할 때까지 이 과정을 반복
 */
const curry =
  (fn: Function) =>
  (...args: any[]) =>
    args.length >= fn.length
      ? fn(...args)
      : (...moreArgs: any[]) => curry(fn)(...args, ...moreArgs)

/**
 * - `...fns: Function[]` 여러 개의 함수를 인자로 받는다
 * - 내부에서 `reduce` 메서드를 사용하여 함수 배열을 순회 초기값으로 `x`를 사용하며, 각 함수 `fn`을 차례로 호출하여 결과를 다음 함수로 전달
 */
const pipe =
  (...fns: Function[]) =>
  (x: any) =>
    fns.reduce((acc, fn) => fn(acc), x)

/**
 * - `...fns`: 여러 개의 함수를 매개변수로 받음
 * - `(x)`: 초기값 `x`를 인자로 받아 결과를 리턴
 * - `fns.reduceRight(...)`: 배열의 오른쪽부터 왼쪽으로 각 함수를 적용합니다. `y`는 이전 함수의 결과이며, `f`는 현재 함수
 * - `f(y)`: 현재 함수 `f`를 이전 함수의 결과 `y`에 적용
 */
const compose =
  (...fns) =>
  (x) =>
    fns.reduceRight((y, f) => f(y), x)
```

---

1. **함수 조합(Composition)**: 작은 함수들을 조합하여 새로운 함수를 만들며, 예를 들어 `compose(f, g, h)`는 `f(g(h(x)))`로 실행
2. **`compose`**: 오른쪽에서 왼쪽으로 함수를 실행하며, `compose(square, double)(3)`은 36을 반환
3. **`pipe`**: 왼쪽에서 오른쪽으로 함수를 실행하여, `pipe(double, square)(3)`의 결과는 36
4. **커링(Currying)**: `f(a, b, c)`를 `f(a)(b)(c)` 형태로 변환하고, 예를 들어 `add(1)(2)(3)`의 결과는 6
5. **부분 적용(Partial Application)**: 일부 인자만 미리 적용하여 새로운 함수를 만들 수 있으며, `const double = multiply(2, _)`로 정의
6. **포인트-프리 스타일**: 변수를 사용하지 않고 함수를 조합하여 작성하며, 예를 들면 `compose(square, double)`와 같은 형태
7. **데이터 마지막 원칙(Data Last)**: 데이터를 마지막 인자로 배치하여 조합성을 높이는데, 예를 들어 `const halve = divideDataLast(2)`와 같이 사용

---

- [Higher-Order Functions](https://eloquentjavascript.net/05_higher_order.html)
- [How to compose JavaScript functions that take multiple parameters (the epic guide)](https://jrsinclair.com/articles/2024/how-to-compose-functions-that-take-multiple-parameters-epic-guide/)
- [JavaScript function composition: What’s the big deal?](https://jrsinclair.com/articles/2022/javascript-function-composition-whats-the-big-deal/)
