Currying 함수란?
Currying은 여러 개의 인자를 받는 함수(multi-argument function)를
하나의 인자를 받는 함수들의 연속으로 변환하는 프로그래밍 기법
즉, 하나의 함수가 한 번에 모든 인자를 받는 대신,
각각의 인자를 별도로 받아 새로운 함수를 반환하는 방식으로 동작한다.
이 방식은 복잡한 함수 호출을 간결하게 표현하고,
특정 인자 값을 고정(fixed)하여 재사용성을 높이는 데 유용
커링은 함수형 프로그래밍에서 자주 사용하는 기법으로,
Dart에서도 클로저와 함수 반환을 통해 구현할 수 있어 활용도가 높음
Currying의 기본 개념
// 일반적인 함수
int add(int a, int b) {
return a + b;
}
// Currying 방식
Function addCurry(int a) {
return (int b) => a + b;
}
void main() {
var add7 = add(7, 10); // 인자 고정 안됨
print(add7); // 17
var add5 = addCurry(5); // 첫 번째 인자를 고정
print(add5(10)); // 15
print(add5(20)); // 25
}
- 일반 함수:
add(5, 10)
과 같이 호출. - Curried 함수:
addCurry(5)(10)
또는 첫 번째 인자를 고정한add5(10)
형태로 호출.
Dart에서 Currying의 이점
- 재사용성 증가: 특정 인자를 고정하여 새 함수로 활용.
- 코드 가독성 향상: 복잡한 함수 호출을 간결한 형태로 분리 가능.
- 함수형 프로그래밍 스타일: 체이닝이나 조합(composition)에 유리.
Dart에서 Currying 구현
Dart에서 Currying은 클로저(closure)를 활용하여 구현됨
1. 기본적인 Currying 사용법
두 개의 인자를 받는 곱셈 함수를 커링 방식으로 변환 할 수 있음
Function multiply(int a) {
return (int b) => a * b;
}
void main() {
var doubleValue = multiply(2); // a를 2로 고정
print(doubleValue(10)); // 20
print(doubleValue(15)); // 30
}
위 코드에서 doubleValue
는 b
만 필요로 하는 새로운 함수가 됨
2. 여러 인자를 가진 함수에서의 Currying
다중 인자를 처리하는 경우,
여러 단계를 통해 인자를 하나씩 처리하도록 구현할 수 있음
Function addThreeNumbers(int a) {
return (int b) {
return (int c) => a + b + c;
};
}
void main() {
var add10And5 = addThreeNumbers(10)(5); // a=10, b=5를 고정
print(add10And5(3)); // 18
}
여기서 addThreeNumbers(10)(5)
는 a
와 b
를 고정한 새로운 함수로,c
만 입력받아 계산함
3. 특정 인자 고정 (Partial Application)
Currying은 특정 인자 값을 고정하는 데 유용
이를 Partial Application이라고도 부름
Function subtract(int a) {
return (int b) => a - b;
}
void main() {
var subtractFrom10 = subtract(10); // a를 10으로 고정
print(subtractFrom10(3)); // 7
print(subtractFrom10(7)); // 3
}
subtract(10)
은 항상 10에서 빼는 함수를 생성
4. 커링을 활용한 체이닝
Currying은 체이닝 방식으로 복잡한 로직을 단순화할 때도 유용
Function compose(Function f, Function g) {
return (x) => f(g(x));
}
void main() {
var addTwo = (int x) => x + 2;
var multiplyByThree = (int x) => x * 3;
var addThenMultiply = compose(multiplyByThree, addTwo); // 3 * (x + 2)
print(addThenMultiply(5)); // 21
}
위 코드에서 compose
를 통해 함수 두 개를 결합하여 사용함
5. 실전 예제: 커링과 데이터 필터링
실제로 데이터를 필터링하거나 가공할 때 커링이 특히 유용함
Function filterBy(String field) {
return (String value) {
return (List<Map<String, String>> items) {
return items.where((item) => item[field] == value).toList();
};
};
}
void main() {
var data = [
{'name': 'Alice', 'role': 'admin'},
{'name': 'Bob', 'role': 'user'},
{'name': 'Charlie', 'role': 'admin'}
];
var filterByAdmin = filterBy('role')('admin'); // 'role'이 'admin'인 데이터 필터링
print(filterByAdmin(data)); // [{'name': 'Alice', 'role': 'admin'}, {'name': 'Charlie', 'role': 'admin'}]
}
filterBy 룰 당장 가져다 쓸 수 있음
커링 사용시 주의점!
- 복잡성 증가: 너무 많은 단계로 나누면 가독성이 떨어질 수 있다.
- 성능 고려: 불필요하게 많은 함수를 생성하면 메모리 사용이 증가할 수 있디.
- Dart의 문법적 제약: Dart는 완전한 함수형 언어는 아니기 때문에 일부 함수형 프로그래밍 개념을 제한적으로만 구현할 수 있다.
재사용 가능한 코드와 가독성을 제공하지만, 단점이 있다.
클로저와 함께 사용하여 특정 값을 고정하거나 복잡한 로직을 간단한 단계로 나눌 수 있다.
남용하지 않도록 조심하여 사용하면 코드 리뷰때 칭찬 받을 수 있다
고차 함수 컬렉션 등등은 앞 포스팅에서 살펴볼 수 있다.
2024.11.17 - [develop/Flutter] - Dart의 고급 함수를 적절히 사용하여 코드 퀄리티 높이기
Dart의 고급 함수를 적절히 사용하여 코드 퀄리티 높이기
1. 고차 함수 (Higher-order Functions)고차 함수는 다른 함수를 인자로 받거나, 함수를 반환하는 함수임Dart에서는 고차 함수를 사용하여 코드를 더욱 유연하고 재사용 가능하게 만들 수 있음1.1 함수 전
devfart.tistory.com
'develop > Flutter' 카테고리의 다른 글
Flutter naver map 현재 위치 표시 및 방향 나타내기 (0) | 2025.04.08 |
---|---|
[flutter] 겹치는 프로그래스바 - 값이 여러개인 프로그래스바 만들기 (0) | 2024.11.26 |
Dart의 고오급 함수를 적절히 사용하여 코드 퀄리티 높이기 (1) | 2024.11.17 |
Dart에서 `toList()`와 `toMap()` 사용법, 응용 하기 (0) | 2024.11.12 |
Dart에서 맵(map) 다루기 (0) | 2024.11.11 |