munifico.github.io

munifico's anything page

Follow me on GitHub

함수를 반환하는 함수

함수를 반환하는 함수는 아마 함수의 가장 난해한 사용법이겠지만, 그만큼 유용하기도 합니다. 어떤 기능이 있는 것을 만든다는 점에서, 함수를 반환하는 함수를 일종의 3D 프린터라고 생각할 수 있을 겁니다. 3D 프린터에 입력하는 설계도를 바꾸는 것과 마찬가지로, 반환받는 함수 역시 마음대로 바꿀 수 있습니다.

sum 함수를 다시 생각해 봅시다. 이 함수는 각 요소를 더하기 전에 해당 요소를 바꾸는 함수를 받습니다. 원한다면 sumOfSquares 함수를 만들 수도 있다고 했습니다. 그런데 상황이 바뀌어서, 그런 함수가 정말 필요하다고 해봅시다. 배열과 함수를 받는 함수로는 만족스러운 결과를 얻을 수 없고, 배열 하나만 받아서 제곱의 합을 반환하는 함수가 필요합니다(그런 상황이 언제 필요할지 잘 떠오르지 않겠지만, API에서 sum 함수를 허용하되 그 함수의 매개변수를 하나만 허용하는 경우가 있을 수 있습니다).

먼저, 이미 만들어둔 sum 함수를 활용하는 방법이 있습니다.

function sumOfSquares(arr) {
    return sum(arr, x => x*x);
}

물론 이렇게 해도 됩니다. 필요한 것이 함수 하나라면 가장 간단한 해결책이 될 수 있습니다. 하지만 제곱근의 합을 구하는 함수, 세제곱의 합을 구하는 함수, 하는 식으로 이런 패턴이 계속 반복된다면 어떻게 해야 할까요? 필요한 함수를 반환하는 함수를 만들어 문제를 해결할 수 있습니다.

function newSummer(f) {
    return arr => sum(arr, f);
}

새 함수 newSummer가 반환하는 함수는 단 하나의 매개변수만 받으면서도, 우리가 원하는 중간 함수를 마음대로 쓸 수 있습니다. 다음 예제를 보십시오.

const sumOfSquares = newSummer(x => x*x)
const sumOfCubes = newSummer(x => Math.pow(x, 3));
sumOfSquares([1,2,3]);      // returns 14
sumOfCubes([1,2,3]);        // returns 36

NOTE 이 예제처럼 매개변수 여러 개를 받는 함수를 매개변수 하나만 받는 함수로 바꾸는 것을 커링currying이라 부릅니다. 커링이라는 이름은 이 패턴을 만든 미국의 수학자 하스켈 커리Haskell Curry의 이름을 딴 것입니다.


이전 : 함수에 함수 전달
다음 : 재귀
목차