안녕하세요. 휴먼스케이프 Software Engineer David 입니다.
코틀린으로 함수형 프로그래밍 4장의 커링함수와 함성함수에 대해 알아보겠습니다.
커링(currying) 함수
커링 함수란?
여러개의 매개변수를 받는 함수를 분리하여, 단일 매개변수를 받는 부분 적용 함수의 체인으로 만드는 방법입니다.
커링 함수 예제 코드
복잡한 커링 함수를 사용하는 이유는 무엇일까?
위 코드에서 partial1이나 partial2는 부분 적용 함수입니다. 커링의 장점 중 하나로 이러한 부분 적용 함수를 다양하게 재사용할 수 있다는 점이 있습니다.
또 마지막 매개변수가 입력될 때까지 함수의 실행을 늦출 수 있습니다.
하스켈 언어의 경우 언어 차원에서 커링 함수를 지원하기 때문에 모든 함수의 매개변수는 하나라고 합니다.
그러나 코틀린에서는 언어차원에서 커링 함수를 지원하지않기 때문에 커링 함수를 추상화하여 사용해 쉽게 만들 수 있는 방법사용합니다.
코드에서 보이는 것처럼 curried 함수와 uncurried 함수를 통해 3개의 인자를 받는 함수를 커링해서 사용할 수 있습니다.
합성 함수
합성 함수란?
함수를 매개변수로 받고, 함수를 반환할 수 있는 고차 함수를 이용해서 두 개의 함수를 결합하는 것을 말합니다.
(f * g)(x) = f(g(x))
수학에서의 합성 함수와 같은 개념으로 코드에서도 비슷하게 구현되는 것을 아래 예를 통해 볼 수 있습니다.
하스켈 언어의 경우 순수 함수형 언어라 연산자(Operator) 를 지원합니다. 그래서 addThree . twice 와 같이 함수를 합성할 수 있는데, 코틀린에서는 연산자를 지원하지 않아 합성 함수를 사용할 때 일반화해서 사용할 수 있습니다.
위 예는 compose 확장 함수를 정의하여 하스켈의 연산자(.)와 유사하게 구현된 코드입니다.
addThree compose twice 합성함수가 만들어지면 뒤(twice)에서 부터 실행되는 것에 유의해야합니다.
리스트를 모두 음수로 만든 후 최솟값 구하는 코드
위 코드의 result1은 compose를 사용하지 않고, 함수를 매개변수로 넣어서 호출하는 예입니다.
result2는 compose를 사용하여 composed 함수를 만들기 위해 타입이나 매개변수에 대한 선언을 하지않았습니다. 이를 포인트 프리 프로그래밍이라고 합니다.
포인트 프리 프로그래밍은 코드의 가독성을 높여주는데, 지나치게 많은 함수를 체인으로 만드는 것은 가독성을 해치기도해 적절하게 함수를 분리해서 합성 함수를 만드는 것이 좋다고합니다.
하나 이상의 매개변수를 받는 함수의 합성
두 값을 각각 제곱한 후 최대공약수를 구하는 코드의 예이다.
위 예제 코드는 잘못된 합성으로 잘못된 출력이 나오는 코드와 적절한 합성으로 제대로된 출력이 나오는 코드로 구성되어있습니다.
잘못된 합성의 코드는 어떤 부분이 잘못되었을까요?
함수 합성은 입력 매개변수가 한 개인 함수로 체이닝되어야 합니다. 그러나 입력이 두 개인 함수를 커링을 사용해서 분리했기 때문에 powerOfTwo 함수의 결괏값은 첫 번째 매개변수에만 반영되고, 두 번째 매개변수까지는 전달되지않게 됩니다.
이렇듯 커링과 합성을 복합적으로 사용하다 보면 결괏값이 어디까지 전달되는지 헷갈리기 쉽습니다.
따라서 두 개 이상의 매개변수를 받는 함수를 사용해서 합성할 때는 늘 주의해야합니다.
결괏값이 제대로 나오는 합성 코드를 한번 살펴보면,
curried 함수를 만들 때, 두 번째 매개변수에 대한 처리를 했습니다. 문제는 해결되었지만 좋은 코드라고 보기는 어려워보이네요. 이러한 이유로 여러 개의 매개변수에 동일한 함수를 적용해야 할 때, 함수 합성을 사용하는 것은 적합하지 않습니다. 이 경우 일반적인 고차함수로의 연결이 더 좋다고 합니다.
조금 극단 적일 수 있지만, 고차 함수와 커링의 사용으로 가독성을 개선한 아래 예시 코드를 보며 이 글을 마무리하겠습니다.
감사합니다.
Get to know us better! Join our official channels below.
Telegram(EN) : t.me/Humanscape KakaoTalk(KR) : open.kakao.com/o/gqbUQEM Website : humanscape.io Medium : medium.com/humanscape-ico Facebook : www.facebook.com/humanscape Twitter : twitter.com/Humanscape_io Reddit : https://www.reddit.com/r/Humanscape_official Bitcointalk announcement : https://bit.ly/2rVsP4T Email : support@humanscape.io