Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

커링과 콤비네이터의 차이 (이진혁) #194

Open
LJH098 opened this issue Aug 27, 2024 · 0 comments
Open

커링과 콤비네이터의 차이 (이진혁) #194

LJH098 opened this issue Aug 27, 2024 · 0 comments
Assignees
Labels

Comments

@LJH098
Copy link

LJH098 commented Aug 27, 2024

문제가 무엇인가?

커링과 컴포지션의 차이점이 무엇일까?

왜 이런 문제를 선정하였는가?

맨 처음에 언급한 커링과 맨 마지막의 콤비네이터가 정말 비슷해보여서 어떤 차이점이 있고 어떤 상황에 사용하면 좋을지 알아보려고 한다.

자신이 생각한 답변은 무엇인가?

커링(Currying)

커링은 함수가 여러 개의 인수를 받는 대신, 하나의 인수를 받아 새로운 함수를 반환하는 과정이다. 이 새로운 함수는 나머지 인수를 받고, 이를 통해 복잡한 함수를 인수 하나만 받는 일련의 함수로 변환할 수 있다.

// 일반적인 함수
Function<Integer, Function<Integer, Function<Integer, Integer>>> curriedFunction = 
    x -> y -> z -> x + y + z;

// 사용
Function<Integer, Function<Integer, Integer>> addFive = curriedFunction.apply(5);
Function<Integer, Integer> addFiveAndThree = addFive.apply(3);
int result = addFiveAndThree.apply(2); // 결과는 10

여기서 curriedFunction은 인수 3개를 받는 함수를 각각 1개씩 인수를 받는 함수로 변환한 것.

콤비네이터

콤비네이터는 여러 함수를 조합하여 새로운 함수를 만드는 방법이다. 커링이 함수를 부분적으로 적용하는 방법이라면, 콤비네이터는 함수들을 결합하여 더 복잡한 동작을 만드는 방법

Function<Integer, Integer> multiplyByTwo = x -> x * 2;
Function<Integer, Integer> addThree = x -> x + 3;

// 콤비네이션
Function<Integer, Integer> combinedFunction = multiplyByTwo.andThen(addThree);

// 사용
int result = combinedFunction.apply(5); // 결과는 13 (5 * 2 + 3)

여기서 combinedFunction은 두 함수를 결합하여 하나의 함수로 만든 것이다.
첫 번째 함수(multiplyByTwo)를 적용한 결과를 두 번째 함수(addThree)의 입력으로 전달한다.

사용 상황

커링

  • 부분적 함수 적용이 필요한 경우

커링은 인수 중 일부만 제공하여 함수를 부분적으로 적용하고, 나머지 인수는 나중에 제공할 수 있게 해준다. 예를 들어, 기본 설정을 가진 함수가 있고, 특정 상황에서는 기본 설정만 바꾸고 나머지 로직은 동일하게 사용하고 싶을 때 유용하다.

ex) 데이터베이스 쿼리를 만들 때, 데이터베이스 연결 정보를 미리 설정하고, 이후 특정 조건만 추가로 설정할 때 커링을 사용할 수 있음.

Function<String, Function<String, Function<String, String>>> queryBuilder = 
    db -> table -> condition -> "SELECT * FROM " + table + " WHERE " + condition + " ON " + db;

Function<String, Function<String, String>> tableQuery = queryBuilder.apply("my_database");
Function<String, String> userTableQuery = tableQuery.apply("users");

String query = userTableQuery.apply("age > 30");
// 결과: "SELECT * FROM users WHERE age > 30 ON my_database"
  • 함수를 전달할 때

커링된 함수는 특정 인수를 고정한 후, 나머지 인수를 나중에 전달할 수 있다. 예를 들어, 특정 연산을 수행하는 함수에 기본 인수를 고정하고 다른 곳에서 사용할 때 커링을 사용할 수 있다.

콤비네이터

  • 여러 함수의 결과를 결합해야 할 때

콤비네이터는 여러 함수를 결합하여 연속적인 계산을 수행할 때 유용하다. 예를 들어, 하나의 데이터를 처리하는 여러 단계를 체인처럼 엮어서 한 번에 적용해야 할 때 사용함.

Function<String, String> trim = String::trim;
Function<String, String> toUpperCase = String::toUpperCase;
Function<String, String> addPrefix = s -> "Processed: " + s;

Function<String, String> processString = trim.andThen(toUpperCase).andThen(addPrefix);

String result = processString.apply("  hello world  ");
// 결과: "Processed: HELLO WORLD"

결론

  • 커링은 특정 인수만 고정하고 나머지는 나중에 제공하거나, 복잡한 다중 인수 함수를 부분적으로 나누어 사용해야 할 때 유용
  • 콤비네이터는 여러 단계를 결합하여 하나의 연산을 만들어내거나, 데이터를 연속적인 함수로 처리할 때 효과적이다.

번외

JNU - EatCeed 프로젝트의 MealFoodEntity에서 g과 multiple에 따라서 전략패턴으로 칼로리, 탄수화물, 단백질, 지방을 구했는데 이를 커링으로 바꿀 수 있을 것 같음.

@LJH098 LJH098 self-assigned this Aug 27, 2024
@LJH098 LJH098 added the ch19 label Aug 27, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

1 participant