티스토리 뷰

javascript

Javascript currying

kmj24 2021. 6. 26. 18:30

다른 함수를 parameter로 받거나 함수를 반환하는 함수를 고차함수(higher-oreder function)라고 한다.

(React library에서는 어떤 컴포넌트를 받아 새로운 컴포넌트를 반환하는 고차컴포넌트(HOC)란것도 있다..)

고차함수를 응용하는 함수형 프로그래밍 방법 중 하나로, parameter를 여러개 가진 함수를 한개의 parameter만 받는 함수의 조합으로 표현하는 기법을 currying이라고 한다.

Currying

Currying이란 1967년 Christopher Strachey가 Haskell Brooks Curry의 이름에서 착안한것이다.

수학과 컴퓨터 과학에서 Currying이란 다중인수를 갖는 함수를 단일 인수를 갖는 함수들의 함수열로 바꾸는 것을 말한다. -위키백과-Javascript에서 직접 currying을 구현할 수 있다.

또는 currying 기법을 이용한 여러가지 method가 있다.

예시로 함수를 binding하는 call(), apply(), bind() 메서드가 이러한 currying 기법을 이용한다.

interface Function {
    apply(this: Function, thisArg: any, argArray?: any): any;
    call(this: Function, thisArg: any, ...argArray: any[]): any;
    bind(this: Function, thisArg: any, ...argArray: any[]): any;

    toString(): string;

    prototype: any;
    readonly length: number;

    arguments: any;
    caller: Function;
}

실제 es5의 libraray에 있는 Function interface의 내용이다. 

첫번째 인자로 함수를 두번째 인자로는 ...arg를 인자로 받는다.

call메서드는 아래의 형태로 작성하며, 이런 작성규칙은 currying 기법을 활용한 구체적인 예시이다.

함수.call(넘겨줄함수, 넘겨줄함수의인자1, 넘겨줄함수의인자2, ...); 

 

산술연산을 진행하는 currying 형태의 예시 코드를 작성해보았다.

숫자를 받아 곱연산과 덧셈연산을 하도록 하는 currying 함수이다.

function mulNum(arg: number[]){
    let val = 1;
    for(let i = 0; i < arg.length; i++){
        val *= arg[i]
    }
    console.log(val);
}

function addNum(arg: number[]){
    let val = 0;
    for(let i = 0; i < arg.length; i++){
        val += arg[i];
    }
    console.log(val);
}

function currying(fn: Function, ...arg: number[]){
    return function(){
        fn(arg);
    }
}

function curryingRun(){
    const mul = currying(mulNum, 1, 2, 3, 4, 5);
    const add = currying(addNum, 1, 2, 3, 4, 5, 6);
    mul();
    add();
}

결과

함수를 받아 binding하여 넘겨주는 currying형태의 함수를 만들어보았다.

interface examObjType {
    first: string;
    second: string; 
}

const examObject: examObjType = {
    first: "first",
    second: "second"
}

function examFunc(this: examObjType,  ...arg: string[]){
    const arr = [this.first, this.second];
    const outputArr = arr.concat(arg);
	console.log(`${outputArr}`);
}

Function.prototype.myBinding  = function (...args: string[]) {
    const obj = this; 
    const rest = args.slice(1);
    
    return function(...args2: string[]){
        obj.apply(args[0], [...rest, ...args2]);
    };
}

export function curryingRun(){
    const tmp = examFunc.myBinding(examObject, "third", "forth", "fifth");
    tmp("sixth", "seventh");
}

examFunc는 첫번째 인자로 object를 받고, 2번째, ...n번째 인자로 string배열을 받아 출력하는 함수이다.

myBinding은 Function의 prototype에 커스텀 메서드를 만든것이다.

myBinding의 역할은 바인딩 된 함수(this)의 내용과 인자값으로 입력받은 값을 배열로 합치는 함수를 반환한다.

실행 결과는 examObject의 기본 내용과 입력받은 문자열을 배열로 합쳐 출력한다.

실행 결과

'javascript' 카테고리의 다른 글

Event - Capturing/Bubbling  (0) 2021.09.01
Javascript와 비동기(asyncronous), Callback/Promise/async await  (0) 2021.06.25
this, arrow function  (0) 2021.06.25
Event Loop  (0) 2021.05.11
closer function  (0) 2021.04.28
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/07   »
1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30 31
글 보관함