Curry And Compose (why you should be using something like ramda in your code) - Lee-hyuna/33-js-concepts-kr GitHub Wiki

원문 : https://jsleao.wordpress.com/2015/02/22/curry-and-compose-why-you-should-be-using-something-like-ramda-in-your-code/

Curry And Compose (why you should be using something like ramda in your code)

원문: https://jsleao.wordpress.com/2015/02/22/curry-and-compose-why-you-should-be-using-something-like-ramda-in-your-code/

ν•¨μˆ˜ν˜• ν”„λ‘œκ·Έλž˜λ°μ— κ΄€ν•΄μ„œλŠ” μ£Όμš” νŠΉμ§•μ€ κ²°ν•©μ„±, κΈ°μ‘΄ ν•¨μˆ˜λ₯Ό κ²°ν•©ν•΄μ•Όλ§Œ μƒˆλ‘œμš΄ ν•¨μˆ˜λ₯Ό μƒμ„±ν•˜λŠ” 것 μž…λ‹ˆλ‹€.

예λ₯Ό λ“€μ–΄, νŠΉμ • μ‘°κ±΄μ—μ„œ 참을 λ°˜ν™˜ν•˜λŠ” ν•¨μˆ˜λ₯Ό μ‚¬μš©ν•˜κ³  ν•„ν„° ν•¨μˆ˜μ™€ κ²°ν•©ν•˜μ—¬ μž¬μ‚¬μš©ν•˜μ—¬ λ°°μ—΄μ—μ„œ μ•„μ΄ν…œμ„ 선택할 수 μžˆμŠ΅λ‹ˆλ‹€.

κ·ΈλŸ¬λ‚˜ μžλ°”μŠ€ν¬λ¦½νŠΈμ—μ„œ λ‹€μŒκ³Ό 같은 λͺ‡κ°€μ§€ κΈ°λŠ₯이 생성될 수 μžˆμŠ΅λ‹ˆλ‹€.

var isGreaterThan = function(limit) {
  return function(value) {
    return value > limit;
  };
};

이 μ˜ˆμ œμ—μ„œλŠ” λ‹€λ₯Έ ν•¨μˆ˜λ₯Ό λ§Œλ“œλŠ” ν•¨μˆ˜κ°€ μ‘΄μž¬ν•©λ‹ˆλ‹€. μ²«λ²ˆμ§ΈλŠ” 단지 value, limit을 κ²°ν•©ν•˜λŠ”λ° 사싀 비ꡐ가 λ°œμƒν•˜κ³ , boolean을 λ°˜ν™˜ν•˜κ³  λ‚œ λ‹€μŒμ— λ‘λ²ˆμ§Έλ₯Ό λ°˜ν™˜ν•©λ‹ˆλ‹€. 이 ν•¨μˆ˜λŠ” curry된 ν˜•νƒœμž…λ‹ˆλ‹€. 즉, ν•˜λ‚˜μ˜ 단일 인자λ₯Ό κ°€μ Έμ™€μ„œ 값을 λ°˜ν™˜ν•˜λŠ” ν•¨μˆ˜ μž…λ‹ˆλ‹€. 값을 κ³„μ‚°ν•˜κΈ° μœ„ν•΄ 더 λ§Žμ€ μΈμˆ˜κ°€ ν•„μš”ν•œ 경우 λͺ¨λ“  ν•¨μˆ˜κ°€ 전달될 λ•ŒκΉŒμ§€ λ‹€μŒ 인수λ₯Ό μ·¨ν•˜λŠ” λ‹€λ₯Έ ν•¨μˆ˜λ₯Ό λ°˜ν™˜ν•©λ‹ˆλ‹€. μ΅œμ’… κ²°κ³Όκ°€ κ³„μ‚°λ˜μ–΄μ§‘λ‹ˆλ‹€.

ES6의 ν™”μ‚΄ν‘œ ν•¨μˆ˜ ꡬ문을 μ‚¬μš©ν•˜λ©΄ 훨씬 더 κ°„νŽΈν•˜κ²Œ μž‘μ„±ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

var isGreaterThan = (limit) => (value) => value > limit;

아직 ES6λ₯Ό μ‚¬μš©ν•˜μ§€ μ•ŠλŠ” κ²½μš°μ—λŠ” ν•˜λ‚˜ 개의 μš°μˆ˜ν•œ 해결방법인 lodash’s _.curry을 μ‚¬μš©ν•˜κ±°λ‚˜ ramda’s R.curry(HTTP처럼)을 μ‚¬μš©ν•˜λŠ” κ²ƒμž…λ‹ˆλ‹€. 이 ν•¨μˆ˜λ“€μ΄ ν•˜λŠ” 일은 μ—¬λŸ¬ 개의 인수 ν•¨μˆ˜λ₯Ό μ·¨ν•˜κ³  그것을 curry의 버젼을 λ°˜ν™˜ν•˜λŠ” κ²ƒμž…λ‹ˆλ‹€.

//Using ramda's curry
var isGreaterThan = R.curry(function(limit, value) {
    return value > limit;
});

이 λ§ˆμ§€λ§‰ ν˜•νƒœμ˜ 예제 μ½”λ“œλ₯Ό μ‚¬μš©ν•˜λ©΄ μ—¬μ „νžˆ 두 가지 인수λ₯Ό 전달 ν•  수 μžˆλ‹€λŠ” 이점이 있으며 μž‘λ™ν•©λ‹ˆλ‹€.

greaterThan(10)(20); //true
greaterThan(10, 20); //true
var greaterThanTen = greaterThan(10);
greaterThanTen(20); //true

curry ν˜•νƒœλ₯Ό μ‚¬μš©ν•˜λ©΄ νŒ©ν† λ¦¬ ν•¨μˆ˜μ™€ 같은 것이 있으며 dataλ₯Ό 전달 ν•˜κ³  결합에 μ‚¬μš©ν•  ν•¨μˆ˜λ₯Ό 받은 λ‹€μŒ 값을 μ „λ‹¬ν•©λ‹ˆλ‹€. Hey Underscore, You’re Doing it Wrong μ—μ„œ 처럼 데이터λ₯Ό λ§ˆμ§€λ§‰μœΌλ‘œ μ „λ‹¬ν•˜κ³ , 지원해야할 값을 λ¨Όμ € 전달 ν•΄μ•Όν•©λ‹ˆλ‹€.

ν•„ν„° κΈ°λŠ₯을 예둜 λ“€μ–΄ λ³΄κ² μŠ΅λ‹ˆλ‹€. locashμ—μ„œλŠ” collection을 첫번째 인수둜 μ·¨ν•œ λ‹€μŒ, 두 번째둜 ν•„ν„°λ§ν•˜λŠ” ν•¨μˆ˜λ₯Ό μ‚¬μš©ν•©λ‹ˆλ‹€. 데이터λ₯Ό λ¨Όμ € μ „λ‹¬ν•˜λ―€λ‘œ μ•„λž˜μ—μ„œ λ³Ό 수 μžˆλ“―μ΄ λ‹€λ₯Έ κΈ°λŠ₯을 μž‘μ„±ν•˜κΈ° 더 μ–΄λ ΅μŠ΅λ‹ˆλ‹€.

//Using lodash here. 
//We flip the order of the arguments in the filter
//function, passing the data last, and curry it.
var filter = _.curry(function(fn, collection) {
  return _.filter(collection, fn);
});

이제 λ”μš±λ” κ²°ν•© κ°€λŠ₯ν•œ ν•„ν„° κΈ°λŠ₯이 μ‘΄μž¬ν•˜κ³ , μ›ν•˜λŠ”λŒ€λ‘œ μ‰½κ²Œ 더 ν•¨μˆ˜λ₯Ό κ²°ν•©ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

var onlyPositives = filter(greaterThan(0));
onlyPositives([-1, 4, 2, -5]); // [4, 5]

이것은 핡심적인 ν•¨μˆ˜ μž…λ‹ˆλ‹€. 이것이 λ°”λ‘œ λžŒλ‹€κ°€ map 및 filter와 같은 κΈ°λ³Έ ν•¨μˆ˜λ‘œ μˆ˜ν–‰ν•˜λŠ” μž‘μ—…μž…λ‹ˆλ‹€. λ§ˆμ§€λ§‰ μ‘°μΉ˜λ‘œλŠ” 데이터λ₯Ό λ§ˆμ§€λ§‰μœΌλ‘œ μ „λ‹¬ν•˜κ³  ν•¨μˆ˜λ₯Ό μ‚¬μš©ν•˜μ—¬ μ—¬λŸ¬ ν•¨μˆ˜λ₯Ό κ²°ν•©ν•œλ‹€λŠ” 사싀을 ν™œμš©ν•˜λŠ” κ²ƒμž…λ‹ˆλ‹€. 언더바, locash 및 λžŒλ‹€λŠ” 그것을 가지고 있으며, λͺ¨λ‘ λΉ„μŠ·ν•©λ‹ˆλ‹€. λ§Žμ€ ν•¨μˆ˜λ₯Ό μ „λ‹¬ν•˜κ³  ν•œ ν•¨μˆ˜μ˜ κ²°κ³Όλ₯Ό λ‹€μŒ ν•¨μˆ˜μ˜ 인수둜 μ „λ‹¬ν•˜κ³ , λ§ˆμ§€λ§‰ ν•¨μˆ˜μ˜ κ²°κ³Όλ₯Ό λ°˜ν™˜ν•˜λŠ” ν•¨μˆ˜λ₯Ό λ°˜ν™˜ν•©λ‹ˆλ‹€. 였λ₯Έμͺ½μœΌλ‘œ μ™Όμͺ½μœΌλ‘œ ~

//read from bottom to top

//+ getFirstPositivePlusOne :: [Number] => Number
var getFirstPositivePlusOne = R.compose(
  R.add(1),                 // 4
  R.get(0),                 // 3
  filter(greaterThan(0))); // [3, 6]

  getFirstPositive([-2, -1, 3, 6]); // 4

데이터-λ§ˆμ§€λ§‰μœΌλ‘œ curry된 ν•¨μˆ˜λ₯Ό compose와 κ²°ν•©ν•˜λŠ” κ²ƒλ§ŒμœΌλ‘œ 훨씬 더 κ°„κ²°ν•˜κ³  합리적인 μ½”λ“œμ™€ μˆœμˆ˜ν•œ ν•¨μˆ˜λ₯Ό λͺ¨λ‘ μž‘μ„±ν•  수 있으며, λžŒλ‹€κ°€ ν•˜λŠ” κΈ°λŠ₯, _와 lodashκ°€ 잘λͺ»ν•˜κ³  μžˆμŠ΅λ‹ˆλ‹€. 그것은 μ μ ˆν•˜κ²Œ curry된 λͺ‡ 가지 κΈ°λŠ₯을 μ œκ³΅ν•˜λ―€λ‘œ point free way라고 λΆˆλ¦¬λŠ” 이 λ°©λ²•μœΌλ‘œ μž‘μ„±ν•  수 μžˆμŠ΅λ‹ˆλ‹€. point free codeλŠ” λ‹€μŒκ³Ό 같이 "glue"λ³€μˆ˜λ₯Ό μ„ μ–Έν•˜μ§€ μ•ŠλŠ” μ½”λ“œ μž…λ‹ˆλ‹€.

//lodash way
var onlyPositives = function(data){ //glue variable (data)
  return data.filter(function(item) {  //glue variable (item)
    return greaterThan(0, item);
  });
} 

//pointfree ramda way
var onlyPositivesPF = R.filter(greaterThan(0)); //no glue variables

μ½”λ“œμ— μ „ν˜€ λ¬Έμ œκ°€ μ—†λŠ” κ²½μš°μ—λ„ 이λ₯Ό μˆ˜ν–‰ν•˜λ©΄ μƒμš©κ΅¬ μ½”λ“œμ˜ λ§Žμ€ λΆ€λΆ„κ³Ό λΆˆν•„μš”ν•œ λ³€μˆ˜λ₯Ό λŒ€λΆ€λΆ„ μ œκ±°ν•˜μ—¬ 더 μž‘κ³  κ°„κ²°ν•œ μ½”λ“œλ₯Ό 생성할 수 있으며 결함이 μžˆμ„ λ•Œ 버그와 버그λ₯Ό μ‰½κ²Œ 식별할 수 μžˆμŠ΅λ‹ˆλ‹€.