순수 함수로 부작용 피하기
순수 함수 : 동일한 입력에 대해서는 항상 같은 결과를 반환하는 함수
함수 내에서 전역 변수 등 외부의 변수를 참조하지 않기 때문에 외부 상태를 변경하는 부작용이 발생하지 않는다.
float circleArea(float r)
{
return 3.14f * r * r;
}
float f = 2.5f; // 지역 변수
for (int i = 1; i <= 5; ++i) circleArea(f);
동일한 입력에 대해 항상 같은 값을 출력하므로 circleArea는 순수 함수이다.
int currentState = 0; // 전역 변수
int increment(int i)
{
currentState += i;
return currentState;
}
int fix = 5; // 지역 변수
for (int i = 1; i <= 5; ++i) increment(fix);
increment는 매번 다른 값을 반환할 뿐만 아니라 함수 외부의 전역 변수에 의존하므로 순수 함수가 아니다.
float phi = 3.14f; // 전역 변수
float circleArea(float r)
{
return phi * r * r;
}
float f = 2.5f; // 지역 변수
for (int i = 1; i <= 5; ++i) circleArea(f);
circleArea는 매번 같은 값을 반환하지만 함수 외부의 전역 변수를 참조하기 때문에 순수 함수가 아니다.
추가로 함수에 의해 변경되는 전역 변수나 참조자의 상태뿐만 아니라 화면 출력, I/O 연산 등의 IPC 역시 부작용에 포함된다.
커링으로 함수 분리하기
커링 : 여러 개의 인수를 갖는 하나의 함수를 단일 인수를 갖는 여러 개의 연속된 함수로 나누는 것
template<typename Func, typename... Args>
auto curry(Func func, Args... args)
{
return [=](auto... lastParam) {
return func(args..., lastParam...);
};
}
int areaOfRectangle(int length, int width)
{
return legnth * width;
}
auto length5 = curry(areaOfRectangle, 5);
for (int i = 0; i <= 5; ++i) std::cout << length5(i) << '\n';
/* length5(i) == areaOfRectangle(5, i); */
다수의 인자를 받는 함수를 단일 인자를 받는 함수로 줄인 코드이다.
auto multiply2(int a)
{
return [=](int b) {
return a * b;
};
}
auto multiply3(int a)
{
return [=](int b) {
return multiply2(a * b);
};
}
std::cout << multiply3(5)(10)(2) << '\n';
이런 식으로도 사용 가능하다.
'도서 > 모던 C++로 배우는 함수형 프로그래밍' 카테고리의 다른 글
재귀 함수 호출 (1) (0) | 2022.12.09 |
---|---|
함수에 불변 객체 사용하기 (0) | 2022.12.09 |
함수형 프로그래밍에서 함수 다루기 (2) (0) | 2022.12.09 |
함수형 프로그래밍에서 함수 다루기 (1) (0) | 2022.12.09 |
모던 C++와 친숙해지기 (4) (0) | 2022.12.09 |