커링 알아보기

skyepodium·2022년 4월 13일
0

1. 개요

1) 정의

커링이란 여러 파라미터를 가지는 함수를 단일 파라미터를 갖는 함수들의 연속으로 변경하는 것을 의미합니다.

2) 예시

// 1. 커링
// 1. 2개의 파라미터를 받아 합을 계산하는 함수에 커링 적용
const curriedSum = a => {
    return b => {
        return a + b
    }
}

// 화살표 함수를 적용한다면 한줄로 표현이 가능합니다.
// const curriedSum = a => b => a + b

// 2. 커링이 적용된 함수 실행
const res = curriedSum(3)(4)

console.log('res', res) // 7

3) 커링이 가능한 이유

커링이 가능한 이유는 외부 함수의 컨텍스트가 소멸되어도 내부 함수가 외부 함수의 실행환경을 참조할 수 있는 클로져 때문입니다.

4) 클로져

수학자 하스켈 커리에 의해 발전되어 붙여진 이름이고, 클로져가 가능한 다른 언어에서도 해당합니다.

# 1. 2개의 파라미터를 받아 합을 계산하는 함수에 커링 적용
def curried_sum(a):
    def sum_a(b):
        return a + b
    return sum_a

# 람다를 적용한다면 한줄로 표현이 가능합니다.
# curried_sum = lambda a: lambda b: a + b

# 2. 커링이 적용된 함수 실행
res = curried_sum(3)(4)

print('res', res) # 7

2. 어디에 유용한가?

1) 함수 합성

함수 합성을 통해 코드 재활용성을 높일 수 있습니다.

reduce, args(유사 배열 객체) 와 섞어서 여러 함수를 받아서 실행하는 compose 함수를 만들 수 있습니다.

const compose = (...args) => {
    return args.reduce((prev, next) => {
        return (...values) =>{
            return next(prev(...values))
        }
    }, k => k)
}

다음 예시처럼, 1. 버림, 2. 절대값, 3. 세제곱 3개의 함수를 합성 후

-5.54[1, 2, 3, 4, 5]리스트의 map에 적용할 수 있습니다.

// 1. 버림 함수
const trunc = x => ~~x

// 2. 절대값 함수
const abs = x => x < 0 ? x * -1 : x

// 3. 세제곱 함수
const triple = x => x * x * x

// 4. 컴포즈 함수
const compose = (...args) => {
    return args.reduce((prev, next) => {
        return (...values) =>{
            return next(prev(...values))
        }
    }, k => k)
}

// 5. 함수 합성
const composed = compose(
    trunc,
    abs,
    triple
)

// 6. 결과 확인
console.log('res', composed(-5.54)) // 125

const a = [1, 2, 3, 4, 5]
console.log(a.map(composed)) // [ 1, 8, 27, 64, 125 ]

물론 아래처럼 클로져랑 커링 1번 사용해서 할수도 있는데 compose랑 비교했을때 아래 방법은 오른쪽에서 왼쪽으로(f1~f3)을 읽어야 해서

아무래도 왼쪽 -> 오른쪽으로 읽는 compose 보다는 조금 낯설다는 점이 있습니다.

const f = (f1, f2, f3) => {
    return x => f3(f2(f1(x)))
}

const fComposed = f(trunc, abs, triple)

const res = fComposed(-5.54)

console.log('res', res) // 125

2) 지연 평가

함수가 바로 실행되지 않습니다. 비용이 많이드는 파라미터를 넣고 재활용해서 효율적으로 사용할 수 있습니다.

const log = a => b => c => `${a}-${b}-${c}`

const todayLog = log(new Date().getDate())

const res = todayLog('service')('error')

console.log('res', res) // 14-service-error
profile
callmeskye

0개의 댓글