xtring.dev

[JS] Currying in JavaScript ES6 본문

Front-End/JavaScript

[JS] Currying in JavaScript ES6

xtring 2020. 1. 1. 21:34

Currying은 JavaScript에 대한 깊은 이해를 제공합니다. Arrow funtion과 함께 어떻게 수행되는지 알아봅시다!

 

 

What is Currying?

Haskell B. Curry이 제시한 ES6의 새로운 Function 정의방법으로 기존의 Function 정의 시에 한번에 여러 개의 argument 불러오는 방식에서 argument 1개만으로 Function을 정의하는 방식입니다.

 

Currying은 lamda calculus를 통해 하나 이상의 인수를 가진 함수로 하나 이상의 인수를 가진 함수를 줄이는 프로세스입니다. 말로만 설명하기에는 한번에 알기 어려운 개념인 것 같습니다. 아래 코드를 보겠습니다.

curryedMultiply = (n) => (m) => n * m
curryedMultiply(3)(4) === 12	// true

multiply = (n, m) => curryedMultiply(n)(m)
multiply(3, 4) === 12	// true

Is There Uncurrying?

Uncurrying은 currying의 반대 개념입니다.

f(n)(m) --> f'(n, m)

 

curryedMultiply = (n) => (m) => n * m
curryedMultiply(3)(4) === 12	// true

multiply = (n, m) => curryedMultiply(n)(m)
multiply(3, 4) === 12	// true

 

 

What about Partial Application?

Partial Application(부분 적용)은 인수와 관련하여 부분적으로 함수를 미리 적용했음을 의미합니다.

multiply = (n, m) => n * m
multiply(3, 4) === 12 // true

triple = (m) => multiply(3, m)
triple(4) === 12 // true

Real World Currying Examples

실제 JavaScript에서 어떻게 쓰이는지 볼까요?

 

JavaScript Bind

Function.prototype.bind()는 실제로 Partial Application(부분 적용)입니다.

// first param is thisArg which is irrelevant now
increment = add.bind(undefined, 1)
increment(4) === 5

 

React and Redux

react-redux 모듈의 connect() 메소드를 사용하는데 가장 간단한 사용 방법입니다.

export default connect(mapStateToProps)(TodoApp)

저 또한 connect() 메소드를 사용하며 이 방식에 대해 궁금해졌습니다.

Rendering HTML

Render Function을 재사용하여 유사한 HTML 태그를 렌더링 할 수 있습니다.

renderHtmlTag = tagName => content => `<${tagName}>${content}</${tagName}>`

renderDiv = renderHtmlTag('div')
renderH1 = renderHtmlTag('h1')

console.log(
  renderDiv('this is a really cool div'),
  renderH1('and this is an even cooler h1')
)

Higher Order Function으로서 Curry

curry, uncurry 및 papply를 다음과 같이 Higher Order Function(고차 함수)로 정의 할 수 있습니다. 화살표 표기법은 올바른 연관성이 있으며 대괄호({})를 생략 할 수 있습니다. 아래 코드를 보면 쉽게 이해 할 수 있겠죠?

curry = f => a => b => f(a, b)
uncurry = f => (a, b) => f(a)(b)
papply = (f, a) => b => f(a, b)

 

Properties

curry와 uncurry는 반대입니다.

add = (a, b) => a + b
curriedAdd = a => b => a + b

add(5,6) === 11
curriedAdd(5)(6) === 11

uncurry(curry(add))(5,6) === 11
curry(uncurry(curriedAdd))(5)(6) === 11

Conclusion

Curry라는 용어는 거의 40년 정도 되었으며 lamda calulus(람다 미적분학)에서 필수적인 변화입니다.

JavaScript의 ES6를 더 많이 사용해 갈 수록 특히 navtive promise와 Arrow Function과 함꼐 더 많이 사용되고 있습니다. 언어를 습득하기 위해서는 lamda calulus 및 Functional Programming에 대한 지식이 있어야 합니다. Gang of Four를 넘어 서면 더 높고 더 나은 소프트웨어 구성을 할 수 있게 됩니다.

 

 

 

 

Copyright & Originality : https://blog.benestudio.co/currying-in-javascript-es6-540d2ad09400

반응형
Comments