문서의 임의 삭제는 제재 대상으로, 문서를 삭제하려면 삭제 토론을 진행해야 합니다. 문서 보기문서 삭제토론 Haskell (문단 편집) === Currying === 수학/논리학자인 하스켈 커리(Haskell Curry)는 오늘날 함수형 언어에서 가장 중요한 컨셉 중 하나로 볼 수 있는 Currying으로 유명한데, 이 Currying은 사실 하스켈만의 특징이라기보다는 거의 모든 함수형 언어가 공유하는 특징이기도 하다. Currying은 다인자 함수의 변수(parameter)를 쪼개기로 생각하면 간단하다. 즉, 다변수 함수(여러 개의 값을 묶어서 한꺼번에 입력으로 받는 함수)를 일변수 함수(값을 하나씩 입력으로 받는 함수) 여러개로 쪼개는 것이다.[* 실제로 하스켈은 함수의 파라미터를 하나만 선언할 수 있다. 그 이상의 갯수의 파라미터를 가진 함수는 배후에서 커링으로 처리된다.] 예를들어, f(x,y)라는 함수를 g_x (y)로 바꾸는것이다. 여기서 g_x 함수는 이름처럼 고정된 게 아니라, x 값에 따라 정해진다. 따라서 g_x (y)에는 y를 받아 결과값을 돌려주는 g_x (y) 함수와, x를 받아 g_x 자체를 돌려주는 함수라는 2개의 일변수 함수가 중첩되어 들어 있다. 혹은 (g(x))(y)라고 생각해도 된다. 보다 구체적인 예를 들어 보자. 3*2에서 *를 두개의 인자를 받는 함수라고 생각하고 보통 함수와 같은 방식으로 쓴다면 *(3,2)이라고 쓰면 될 것이다. 즉 * 함수가 3과 2의 쌍을 한번에 받아서 6을 돌려주게 되는 것이다. 그런데, 입력값을 받아서 그 입력값의 3배를 돌려주는 것도 함수이므로, 그 함수를 (×3)이라고 표시해 보자. 그러면 (×3)(2) 라는 표현도 가능하다. 같은 방법으로, 입력값을 받아서 그 입력값의 4배를 돌려주는 함수를 (×4)라고 표시한다면, (×4)(3) 같은 식도 가능해진다. 이런 식으로 일반화해서 입력값을 받아서 그 입력값의 m배를 돌려주는 함수를 (×m)이라고 써 보자. 그러면 *(m,n)=(×m)(n) 이라는 일반식이 성립한다. 이 식의 우변에 일변수 함수 1개가 있다고 생각하기 쉽지만, 그렇지 않다. 왜냐하면 '''×는 m을 입력으로 받아서 (×m)이라는 함수를 출력으로 돌려주는 함수'''이기 때문이다. 따라서 좌변에는 이변수함수 *, 우변에는 일변수함수 ×와 (×m)이 있다고 보아야 한다.[* 그래서 수학적으로 엄격하게는 *(m,n)=(×(m))(n) 이 맞다. 그렇지만 가독성 문제가 있어 생략.] 이런 식으로, '''모든 이변수함수는 일변수함수 하나와 그 일변수함수를 결과값으로 내놓는 다른 일변수함수의 조합으로 분해가 가능'''하다. 이런 것을 currying이라고 하며, 타입을 이용하여 다음과 같이 생각해 볼 수도 있다. *(m,n)은 (int, int) → int 라는 타입을 가지고, 이는 * 함수가 정수의 쌍을 받아서 정수를 돌려주는 함수라는 의미이다. 한편 (×m)(n)의 타입은 int → (int → int)가 되고, 이는 × 함수가 정수를 받아서 함수를 돌려주는 함수인데 ×가 돌려준 함수는 정수를 받아서 정수를 돌려주는 함수라는 것을 의미한다.[* 이처럼, 함수의 출력이 함수가 되는 것을 얼마나 적절히 활용할 수 있느냐가 하스켈로 얼마나 괜찮은 코드를 짤 수 있는가를 말해주는 한 요소가 된다.] 이렇기 때문에, 하스켈에서는 그냥 * 3 2 라고 쓰고, *과 3 사이에서 끊어 읽으면 *(3,2) 가 되고 3과 2 사이에서 끊어 읽으면 (×3)(2) 가 된다는 식으로 처리한다. * 3 2 라는 표기 자체가 currying을 반영하고 있으며, 이런 currying 덕에 여러 가지 함수를 사용해서 코드를 짜면서도 코드가 간결해지고, 풍부한 의미를 담을 수도 있게 된다.[* 여러 개의 함수를 사용하면서 f(x), g(x,y)와 같은 방법으로 쓴다면 앞 주석의 (×(m))(n) 처럼 괄호가 한없이 불어나게 마련인데, currying 덕에 괄호를 최대한으로 생략하면서도 코딩할 수 있게 된다. 따라서 여러 개의 함수를 사용하더라도 덜 복잡하게 보이고, 따라서 여러 가지 함수 여러 개를 쓰고 싶은 만큼 마음껏 쓰는 것도 할 만해진다.] 덧붙여 위의 * 3 2 는 그냥 설명을 위한 예시이고, 실제 하스켈에서는 {{{(*) 3 2}}}로 쓰거나 더 간단하게 *을 중위 연산자로 취급하여 {{{3*2}}}로 표기한다. Currying과 연관된 집합론적 내용도 생각해 볼 수 있는데, 다음과 같다. A×B를 앞자리는 A의 원소, 뒷자리는 B의 원소인 순서쌍의 집합이라고 정의하고 D^C를 C에서 D로의 함수의 집합으로 정의하면, C^(A×B)와 (C^B)^A 사이에는 매우 적절한 일대일 대응이 존재한다. 이에서 집합의 기수 또는 농도(Cardinal number, cardinality) 의 지수법칙의 일부도 증명된다. Currying 은 type inference 알고리즘에 의해 자동으로 수행되므로, 프로그래머가 골치썩일 필요 없이 알아서 적용된다. Currying 은 언뜻보기에 별 쓸모없어보이지만, 사실 이게 빠진 함수형 언어는 포인터 없는 C 언어라 봐도 무방할 정도로 핵심적인 위치를 갖는다.~~그래서 언어 이름도 하스켈~~저장 버튼을 클릭하면 당신이 기여한 내용을 CC-BY-NC-SA 2.0 KR으로 배포하고,기여한 문서에 대한 하이퍼링크나 URL을 이용하여 저작자 표시를 하는 것으로 충분하다는 데 동의하는 것입니다.이 동의는 철회할 수 없습니다.캡챠저장미리보기