🍛커링

👉 함수에 인자를 하나씩 나눠서 전달할 수 있게 만드는 기법

함수와 함께 사용하는 고급기술❗
자바스크립트에만 존재하는 것이 아닌 다른 언어에도 존재🙆‍♀️

sum(1, 2, 3)
sum(1)(2)(3)

이렇게 하나씩 나눠서 쓸 수 있게 만드는 걸 '커링' 이라고 함
( 이름은 수학자 'Haskell Curry'에서 따옴 )

🧪 커링 예제

🟢 일반 함수

function sum(a, b) {
  return a + b;
}

console.log(sum(1, 2));  // 3

🟡 커링된 함수

function curriedSum(a) {
  return function(b) {
    return a + b;
  }
}

console.log(curriedSum(1)(2));  // 3

🧩 동작 순서

    1. curriedSum(1) 호출 : 이 때 a = 1
      그리고 function(b) { return a + b; }를 반환🔁
    1. 반환된 함수에 (2) 호출 : b = 2, a = 1은 여전히 기억됨(클로저!)
      1 + 2 결과인 3을 반환🔁

💡 화살표 함수로 더 간단하게

const curriedSum = a => b => a + b;
console.log(curriedSum(1)(2));  // 3

🐱‍💻

const sum = (x, y) => x + y;
console.log(sum(10, 20));  // 30

const curriedSum = x => y => x + y;
console.log(curriedSum()());

x의 값 넣어주니까 이부분이 처리되고
y => x + y 이게 리턴되는 걸 볼 수 있음🔁

y값을 넣어줘야 그제서야 함수가 리턴되는 걸 알 수 있음

👩‍🍳음식을 만들때 재료를 하나하나 넣을텐데
ingredient1 첫번째 재료 넣어주고
ingredient2 두번째 재료 넣어주고
ingredient3 세번째 재료까지 넣어줘야
음식이 만들어지게 해줄거임

const makeFood = (ingredient1) => {
  return (ingredient2) => {
    return (ingredient3) => {
      return `${ingredient1} ${ingredient2} ${ingredient3}`
    }
  }
}
// 🍔 Bread Ham Tomato
const hamburger = makeFood('Bread')('Ham')('Tomato');
console.log(hamburger);

makeFood'Bread' 하나 넣어주면 이 부분이 리턴됨

두번째 인자 "Ham" 넣어주면 이 부분이 리턴됨

세번째 인자 "Tomato"까지 넣어줘야 햄버거가 잘 완성이 됨🍔
👇 이 코드를 좀 더 깔끔하게 사용하려면 ❓

const cleanerMakeFood = ingredient1 => 
	ingredient2 => 
		ingredient3 => 
			`${ingredient1} ${ingredient2} ${ingredient3}`;
const hamburger = cleanerMakeFood('Bread')('Ham')('Tomato');
console.log(hamburger);

이렇게 화살표 함수로 해주면 위에 코드랑 같은거임✨

function log(date, importance, message) {
  // log라는 함수 선언 (3개의 매개변수를 받음: 날짜, 중요도, 메시지)
  
  alert(`[${date.getHours()}: ${date.getMinutes()}] [${importance}] ${message}`);
  // 알림창 띄움
  // date.getHours() : 시(hour)를 가져옴
  // date.getMinutes() : 분(minute)을 가져옴
  // importance : 중요도 표시 (예: "DEBUG", "INFO" 등)
  // message : 실제 메시지 내용
  // 전체적으로 [시:분] [중요도] 메시지 형식으로 알림창에 출력
}

log(new Date(), "DEBUG", "some debug");
// log 함수 호출
// new Date() : 현재 날짜와 시간 객체 생성
// "DEBUG" : 중요도
// "some debug" : 메시지

위에 코드는 한번에 호출 했으니까 이젠 커링으로 바꿔보자❗

function log(date, importance, message) {
  alert(`[${date.getHours()}: ${date.getMinutes()}] [${importance}] ${message}`);
}

function curry(f) {
  return function(a) {
    return function(b) {
      return function(c) {
        return f(a, b, c);
      }
    }
  }
}

const curriedLog = curry(log);
// curriedLog(new Date())("DEBUG")("some debug");
// Date는 현재 시간을 나타내는거라 안 변하는 부분이니 이렇게 해주는 게 좋음
let logNow = curriedLog(new Date());
logNow("INFO")("dsfsdfsfdfsf");  // 종종 바뀌는 것만

하나 하나 하나 호출해야 완성된 리턴을 갖고 싶다면
'커링' 이라는 기술 이용하면 됨🔥

만약 매개변수의 수가 달라질 때마다 이렇게 일일이 추가 해줘야함🥴

😵 매번 커링 코드를 다 쓰기 귀찮잖아 ❓
👉 그래서 만든 게 “자동 커링 함수”

어떤 함수든! 매개변수 몇 개든!
자동으로 나눠서 받을 수 있게 만들어줌

🎈 진짜 쉬운 예제 ( 외우지 말고 읽기만! )

function autoCurry(fn) {
  return function curried(...args) {
    if (args.length < fn.length) {
      return function(...next) {
        return curried(...args, ...next);
      };
    }
    return fn(...args);
  };
}

📦 원래 함수가 3개 받는 거라면 → 다 받을 때까지 기다렸다가 실행!

🧪 사용 예시

function log(a, b, c) {
  console.log(a, b, c);
}

const curriedLog = autoCurry(log);

// 이렇게도 되고
curriedLog(1)(2)(3);

// 이렇게도 되고
curriedLog(1, 2)(3);

// 이렇게도 돼!
curriedLog(1)(2, 3);

👉 무조건 다 받고 나서 log(a, b, c) 실행!

profile
안녕하세요! 퍼블리싱 & 프론트엔드 개발 공부 블로그 입니다!

0개의 댓글