본격적인 함수형 프로그래밍의 기초 go

YOUNGJOO-YOON·2021년 10월 11일
0

JavaScript

목록 보기
10/25

reducer 함수

const reducer = (f, acc, iter) => {
	if(!iter){
		iter = acc[Symbol.iterator]();
		acc = iter.next().value;
	}
	for(const a of iter){
		acc = f(a,acc);
	}
	return acc;
}
const add = (a,b)=>a+b;
console.log('reducer: ',reducer(add,[1,3,5,7,11,13]));

reducer 함수를 직접 제작하였는데 이는 iterator protocall을 따르는 값이 iter인 경우 모두 적용이 된다.

go 함수

const reducer = (f, acc, iter) => {
	if(!iter){
		iter = acc[Symbol.iterator]();
		acc = iter.next().value;
	}
	for(const a of iter){
		acc = f(a,acc);
	}
	return acc;
}
const add = (a,b)=>a+b;
console.log('reducer: ',reducer(add,[1,3,5,7,11,13]));
// go Fn
const go = (...args) => reducer((f,a)=>f(a),args)

go(
    0,
    a=>(a+1),
    a=>(a+10),
    a=>(a+100),
    console.log
    )

go 함수는 reducer 함수에 들어갈 인자들을 받아준다.
acc 값이 되어줄 0과 나머지는 보조 함수들을 넣어준다.

go = (...args) => ... 에서 ...args[0, a=>a+1, a=>a+10, a=>a+100, console.log]와 같다.

배열을 전달 받았으므로 reducer 함수의 두 번째 인자가 되면 되고,

reducer 함수는 배열의 0 번째 인자를 acc로 첫 번째 인자로 받은 보조 함수를 실행한다.

go = (...args) => reducer((f,a)=>f(a),args)
에서 reducer((a,f)=>f(a) 함수는 a의 값으로 0 번째 인자인 0을,
f = a=>a+1을 사용한다.

왜 이렇게 되는가?


const reducer = (f, acc, iter) => {
	if(!iter){
		iter = acc[Symbol.iterator]();
		acc = iter.next().value;
	}
	for(const a of iter){
		acc = f(a,acc);
	}
	return acc;
}

for...of문에서 acc의 값은 iter[0]의 값과 같다.
따라서 reducer의 첫 인자인 f(보조함수)의 두번째 인자는 iter[0]의 값이고
a의 값은 iter[1]의 값이다.

여기까지 하고 다시 go 함수에 넘긴 인자를 보자.

go(0, a=>a+1,...)

iter[0] = 0 이 되는 것이고

iter[1] = a=>a+1 이 된다.

0은 reducer의 if 문에의해 for...of문의 순회에서 벗어나게되고
for...of문의 대상은 보조함수인 a=>a+1이 되므로

for...of문은 이런 식으로 이루어진다.

for(const i of iter){ acc = f(a=>a+1,0)=>{ return 0=>0+1 } }

둘 째는 함수가 담긴 iterable 객체에서 다음 함수르 꺼내오게 된다.
acc = f(a=>a+10, 1) => 1 => 1+10
acc의 값은 함수의 리턴값으로 누적되어 1 -> 11이 된다.

이를 반복하는 것이 go 함수이다.

profile
이 블로그의 글은 제 생각을 정리한 글과 인터넷 어딘가에서 배운 것을 정리한 글입니다. 출처는 되도록 남기도록 하겠습니다. 수정 및 건의 오류 등이 있으면 언제든지 댓글 부탁드립니다.

0개의 댓글