[CS/Functional programming] 함수형 프로그래밍 : 커링(Currying)

0
post-thumbnail

커링(Currying)

  • 함수에 인자를 하나씩 적용해나가다가 필요한 인자가 모두 채워지면 함수 본체를 실행하는 기법
  • JS에서는 커링이 지원되지 않지만, 일급 함수가 지원되고 평가 시점을 다룰 수 있기 때문에 커링을 직접 구현할 수 있다.

  • 커리 함수는 인자로 함수를 받고 커리 함수를 실행하는 즉시 함수를 리턴한다. 해당 함수가 실행되면 또 다른 함수가 연쇄적으로 실행된다.

  • currying 함수에서 앞에 있는 인자일수록 변동가능성이 적게끔 구현하는 것이 좋다. 따라서 인자를 역으로 받아야되는 경우를 고려하여 오른쪽에서 부터 인자를 적용해나가는 curryr 함수를 별도로 만들어 사용한다.


currying 함수 예제

  • 미리 받아두었던 fn 함수를 내부에서 평가한다.

function _curry(fn) {
  return function(a) {
    return function(b) {
      return fn(a, b);
    }
  }
}

var add = _curry(function(a, b) {
  return a + b;
});

var add10 = add(10);
console.log(add(5)(3)); // 8 1) 바로 적용하는 경우
console.log(add10(3)); // 13 2) 미리 적용한 후 가져다쓰는 경우

console.log(add(1,2)); // 이런식으로 a,b를 한 번에 전달 불가. 이 경우 함수가 반환됨.
//인자 2개 한 번에 받는 경우도 허용하는 코드
function _curry(fn) {
  return function(a, b) {
    return arguments.length == 2? fn(a, b) : function(b) {return fn(a, b);};
  }
}

currying r (curryRight) 함수 예제

  • 오른쪽에서 부터 인자를 적용해나가는 커리 함수 구현
//인자 2개 한 번에 받는 경우도 허용하는 코드
function _curryr(fn) {
  return function(a, b) {
    return arguments.length == 2? fn(a, b) : function(b) {return fn(b, a);};//a, b 자리를 바꾸어 줌
  }
}

curry로 구현한 get

var _get = _curry(function(obj, key) {
  return obj == null ? undefined : obj[key];
});  

보통 curry 기능을 가진 함수를 매번 생성하면 코드가 복잡해지기 때문에, cuury, curryr 함수를 미리 생성해놓고 이 함수를 통해 currying 하는 방식으로 구현한다.

이 경우에도 미리 만들어 놓은 curry를 사용하여 currying 기능을 가진 get 함수를 구현하였다. 마찬가지로 왼쪽이 아닌 오른쪽부터 인자를 적용해나가고 싶으면 curry 대신 curryr을 적용하면 된다.


참고

0개의 댓글