본문 바로가기

Programming/Javascript

15. Javascript 함수형 프로그래밍 적용(1) - 필수 선행지식 + 커링(curry) 3

javascript logo image

 

 

앞서 구현해 본 커링의 경우, Javascript에서는 기본적으로 제공되는 메서드는 아닙니다. 그래서 프로토타입 함수로 정의하여 사용하는 것이 일반적입니다. 앞서 calculate 함수 사례를 프로토타입 메서드로 정의해 실행해 보도록 하겠습니다.

 

 

function calculate(a, b, c) {
    return a * b + c;
}

Function.prototype.curry = function() {
    var fn = this;
    var args = Array.prototype.slice.call(arguments);

    console.dir(args);

    return function() {
        return fn.apply(this, args.concat(Array.prototype.slice.call(arguments)));
    }
}

var new_func1 = calculate.curry(1);
console.log(new_func1(2,3));

 

 

앞서 작성해 본 사례와 거의 유사하지만, curry 함수에 파라미터 값으로 함수가 들어가지 않기 때문에 args에 반환되는 slice함수를 call 할 때의 인자 값에서 인덱스 1이 사라졌습니다. (자연스럽게 arguments에는 정수만 들어가기 때문에 calculate 함수를 떼어낼 필요가 없으니까요)

 

 


 

 

이제까지 살펴본 커링 예제의 경우, 세 개의 파라미터가 있는 caculate 함수(파라미터 a, b, c)에 a부터 특정 값을 고정시켜 호출하는 함수로서 정의하여 사용했습니다. 하지만, 다음과 같은 경우도 생각해 볼 수 있습니다. 만일 a, b, c 중에서 a와 c의 값만 먼저 사전에 정의하고 싶다면? 그리고 중간에 위치한 b의 값만 사용자가 지정해 calculate 함수를 실행하고 싶다면? 기존의 curry 함수로는 대응할 수 없는 사항입니다. 

 

이제 이러한 상황까지 감안한 curry 함수를 새로 작성해 살펴보도록 하겠습니다. 

 

function curry2(func) {
    var args = Array.prototype.slice.call(arguments, 1);
    console.log(args);
    console.log(arguments.length);

    return function() {
        var arg_idx = 0;
        for (var i = 0; i < args.length && arg_idx < arguments.length; i++){
            if(args[i] === undefined){
                console.log(arg_idx);
                args[i] = arguments[arg_idx++];
            }
        }

        console.log(args);
        return func.apply(null, args);
    }
}

var new_func = curry2(calculate, 2, undefined, 4);
console.log(new_func(3));