Ramda add

What is today’s function?

오늘은 아주 아주 간단한 add 함수 되시겠다.

너무 간단한 함수라 두 개를 해야 하나 걱정이 되기도…

그럼 시작 해 볼까~?

함수 설명

Adds two values.

발 번역: 두 값을 더한다

두 값을 더하면 된다. 끝이다.

코드 분석

외부에 노출되는 함수는 어디에 있다 그랬지?

맞다. source/add.js 에 위치한다.

이번에도 주석 다 떼고 중요한 함수만 한번 코드를 봐보자.

1
2
3
4
var add = _curry2(function add(a, b) {
return Number(a) + Number(b);
});
export default add;

인수를 모두 Number 를 통해 숫자로 형변환 후에 더하면 끝난다.

근데 조기 함수 선언부 쪽에 _curry2 라는 신기한 뭔가가 달라붙어 있는게 보인다.

바로 FP의 꽃인 curry 함수인데 정해진 함수의 인자가 모두 들어올 때 까지 새로운 함수를 만들어 내는 엄청난 녀석이다.

add 함수는 2개의 인자를 받으니, 인자가 2개가 모두 들어올 때 까지 함수의 평가를 미룰 수 있는 엄청난 슈퍼 쿨 짱인 함수다.

이친구 덕분에 함수 합성이 가능해진다. 중독되면 끊기 힘들껄?

아무튼 _curry2 는 나중에 분석할 내용이니 오늘도 링크 만 남기고 넘어간다.

실제 사용 예제

우리의 요구사항은 다음과 같다고 가정해보자.

게시물에 좋아요 기능을 추가한다. 처음 좋아요를 누르면 좋아요가 +1 되고, 다시 한번 누르면 좋아요가 -1 된다.

위의 기능을 위해서는 아래와 같이 총 4개의 함수가 있으며, 모두 curry 된 함수로 가정한다.

  • getPostById(id)
    • 인자로 게시글의 id를 받으며, id 에 해당되는 post 데이터를 반환
  • hasLike(userId, post)
    • 인자로 userId, post 데이터를 받으며, 해당 post 데이터에 좋아요를 눌렀는지 판별하는 boolean 값을 반환
  • updateLikeCountOnPost(post)
    • 인자로 likeCount 가 수정된 post 를 받으며, 성공, 실패를 반환
  • updateLikeCountOnUser(userId, post)
    • 인자로 userIdpost 를 받으며, 내부적으로 post 에서 id 를 가져다가 좋아요를 했는지 여부를 저장

그럼 코드를 한번 만들어 보자.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import R from "ramda";

const id = 12345; // 좋아요 누르면 요 id 는 전달 받는다고 가정한다.
const userId = "dev-huna-001"; // 미들웨어를 통해 로그인 처리가 되었다고 가정한다.

getPostById(id)
.then(R.ifElse(
hasLike(userId),
R.over(R.lensProp("likeCount"), R.add(1)),
R.over(R.lensProp("likeCount"), R.add(-1))
))
.then(R.tap(updateLikeCountOnUser(userId)))
.then(updateLikeCountOnPost)
.then(console.log)
.catch(console.error);

모르는 함수가 4개가 더 나왔는데 간단히 설명을 하자면

  • ifElse: if-else 구문처럼 사용 가능한 함수이며, predicate, onTrue, onFalse 에 해당하는 함수들을 인자로 받는다. 즉, predicatetrue 이면 onTrue 함수를 수행하고, false 이면 onFalse 함수를 수행
  • over: lens, function, Array or Object 를 인자로 받으며, lens 에 해당되는 Object 의 속성 또는 Array 의 인덱스의 값에 function 을 적용하여 복제된 Object 또는 Array 를 반환
  • lensProp: property 를 인자로 받으며, 해당 propertylens 를 반환한다. lensgettersetter 함수를 가지고 있고, 요걸 통해서 렌즈를 통해 집중하고 있는 property 를 보거나 수정할 수 있다. 어후 내가 말하고도 뭔소린지…
  • tap: 내가 아주 좋아하는 함수 중 하나인데, 탭~ 하고 건너 뛴다고 생각하면 되는 함수다. 즉, 전달받은 Object 를 가지고 tap 내에 주어진 함수를 실행한 후에 Object 를 그대로 반환한다. 주로 로그를 남기거나 결과값이 필요 없는 비동기 처리를 할 때 굉장히 유용하다.

아무튼 저런 애들이다. 앞으로 자주 등장할 애들이니 나중에 분석하기 전에 미리 간단하게 설명을 남겼다.

그리고 사실 R.add(1)R.inc 함수와 같고, R.add(-1)R.dec 함수와 같다… 저걸 예제라고 만들었니?

마치며…

너무 두서없고 모르는 것 투성이라는 사실이 뼈저리게 느껴진다.

Ramda 라이브러리를 분석하기 전에 함수형 프로그래밍의 기초부터 더욱 다져야 하는게 아닌가… 하는 생각이 드는 밤이다.

잘자용~