조아마시

쓸모 있는 상세페이지 만들기

웹개발/javascript

[자바스크립트] 커링(currying)

joamashi 2024. 7. 30. 00:33

커링은 다수의 인자를 받는 함수를 단일 인자를 받는 함수들로 변환하는 기법입니다. 쉽게 말해, 하나의 함수를 여러 개의 함수로 쪼개서 사용하는 것이라고 생각하면 됩니다. 이렇게 쪼개진 각각의 함수는 이전 함수의 결과를 기억하고 다음 인자를 기다리는 형태로 작동합니다.

왜 커링을 사용할까요?

  • 함수의 재사용성 증가: 부분적으로 적용된 함수를 만들어 다양한 상황에 활용할 수 있습니다.
  • 코드 가독성 향상: 복잡한 함수를 작은 단위의 함수로 나누어 코드를 더 명확하게 만들 수 있습니다.
  • 함수형 프로그래밍 패러다임: 함수를 데이터처럼 다루는 함수형 프로그래밍에서 중요한 개념입니다.
  • 파이프라인 구축: 함수를 연결하여 데이터 처리 과정을 표현하기 좋습니다.

예시를 통해 알아보기

// 일반적인 함수
function sum(a, b, c) {
  return a + b + c;
}

// 커링된 함수
function curriedSum(a) {
  return function(b) {
    return function(c) {
      return a + b + c;
    };
  };
}

// 사용 예시
const result1 = sum(1, 2, 3); // 6
const result2 = curriedSum(1)(2)(3); // 6

// 부분 적용
const add1 = curriedSum(1);
const add3 = add1(2);
const finalResult = add3(3); // 6

위 예시에서 curriedSumsum 함수를 커링한 함수입니다. curriedSum(1)a에 1이 고정된 새로운 함수를 반환하고, 이 함수에 2를 전달하면 b에 2가 고정된 또 다른 함수를 반환합니다. 최종적으로 3을 전달하여 모든 인자가 채워지면 실제 계산이 이루어집니다.

커링의 장점

  • 부분 적용: 함수의 일부 인자만 고정하여 새로운 함수를 만들 수 있습니다.
  • 함수 조합: 다양한 함수를 연결하여 복잡한 연산을 표현할 수 있습니다.
  • 지연 평가: 필요한 시점에만 계산이 이루어지므로 성능을 향상시킬 수 있습니다.

커링의 단점

  • 코드가 길어질 수 있음: 특히 인자의 수가 많을 경우 코드가 복잡해질 수 있습니다.
  • 개념이 어려울 수 있음: 함수형 프로그래밍에 익숙하지 않은 사람들에게는 이해하기 어려울 수 있습니다.

커링의 다양한 예제

커링은 함수형 프로그래밍에서 매우 유용한 기법입니다. 앞서 간단한 예시들을 살펴보았고, 이번에는 실제 개발에서 어떻게 활용될 수 있는지 다양한 예시를 통해 알아보겠습니다.

1. 로깅 함수

const createLogger = (namespace) => (message) => {
  console.log(`${namespace}: ${message}`);
};

const errorLogger = createLogger('error');
errorLogger('Something went wrong'); // error: Something went wrong
  • createLogger 함수는 네임스페이스를 받아 로깅 함수를 생성하는 커링된 함수입니다.
  • 생성된 로깅 함수는 메시지를 받아 콘솔에 출력합니다.
  • errorLogger는 'error'라는 네임스페이스를 가진 로깅 함수입니다.

2. 데이터 변환 파이프라인

const toUpperCase = (str) => str.toUpperCase();
const addExclamationMark = (str) => str + '!';
const compose = (f, g) => (x) => f(g(x));

const processString = compose(addExclamationMark, toUpperCase);
const result = processString('hello'); // HELLO!
  • compose 함수는 두 함수를 합성하는 함수입니다.
  • processString 함수는 toUpperCase 함수와 addExclamationMark 함수를 합성하여 만들어진 함수입니다.
  • processString 함수는 문자열을 대문자로 변환하고 뒤에 느낌표를 추가하는 작업을 순차적으로 수행합니다.

3. 부분 적용을 통한 유연성

const multiply = (a) => (b) => a * b;
const double = multiply(2); // 2를 곱하는 함수
const triple = multiply(3); // 3을 곱하는 함수

const result1 = double(5); // 10
const result2 = triple(4); // 12
  • multiply 함수는 두 수를 곱하는 함수를 커링하여 만들었습니다.
  • doubletriple은 각각 multiply 함수에 2와 3을 부분 적용하여 생성된 함수입니다.
  • 이렇게 만들어진 함수는 특정 값을 고정하여 재사용할 수 있습니다.

4. React 컴포넌트 생성

const withLogging = (Component) => (props) => {
  console.log('Component rendered:', Component.name);
  return <Component {...props} />;
};

const EnhancedComponent = withLogging(MyComponent);
  • withLogging 함수는 컴포넌트를 받아 렌더링 시 로그를 출력하는 새로운 컴포넌트를 생성하는 고차 컴포넌트입니다.
  • 커링을 이용하여 컴포넌트를 감싸는 로직을 재사용 가능하게 만들었습니다.

5. 함수형 스타일의 데이터 처리

const users = [
  { name: 'Alice', age: 30 },
  { name: 'Bob', age: 25 },
  { name: 'Charlie', age: 35 },
];

const getNames = (users) => users.map((user) => user.name);
const filterByAge = (age) => (users) => users.filter((user) => user.age > age);

const namesOver30 = getNames(filterByAge(30)(users));
  • filterByAge 함수는 특정 나이 이상의 사용자만 필터링하는 함수입니다.
  • getNames 함수는 사용자 목록에서 이름만 추출하는 함수입니다.
  • 커링을 이용하여 데이터 처리 파이프라인을 구성할 수 있습니다.

커링의 활용 분야

  • 함수형 프로그래밍: 데이터 변환, 함수 조합 등 다양한 패턴에 활용됩니다.
  • 라이브러리: Lodash, Ramda 등 함수형 프로그래밍 라이브러리에서 널리 사용됩니다.
  • React: 고차 컴포넌트, 컨텍스트 API 등에서 커링을 활용하여 코드를 간결하게 만들 수 있습니다.
 
 
728x90