2개의 인수를 가지고 합을 구하는 함수가 있다.
1 2 3 4 5 6 7 | Prelude> let add x y = x + y ::Integer Prelude> add 3 5 8 Prelude> :type add add :: Integer -> Integer -> Integer | cs |
-> 연산자는 right-associative 이므로, 위의 의미는 아래와 같다.
add :: Integer -> (Integer -> Integer)
이것은 무슨 의미인가? negate 함수를 다시 떠올려보자.
1 2 | Prelude> let neg x = -x ::Integer neg :: Integer -> Integer | cs |
여기서 다시 add 를 등장시키자. 우선 순위를 보여주기 위해서 괄호를 이용하자.
1 2 3 4 | Prelude> let add x y = x + y::Integer add :: Integer -> (Integer -> Integer) | cs |
위의 add :: Integer -> (Integer -> Integer) 에서 add는 정수를 인수로 받아서 결과로 함수를 반환하는 함수이다.
즉 add 3 5 는 (add 3) 5 을 뜻한다.
3이라는 값을 가진 add 를 호출한다. 이름없는 함수를 만든다.
그 이름없는 함수에 5라는 인수를 넣어서 호출한다.
Partial application
요구되는 인수보다 적은 갯수의 인수가 주어졌을 때, 그 결과는 partial application 이라고 부른다. 그것 역시 함수이다.
아래와 같이 partial application 에 이름을 붙일 수 있다.
1 2 3 4 | Prelude> let plusThree = add 3 plusThree :: Integer -> Integer | cs |
plusThree 라는 이름은 정수를 받아 정수를 반환하는 함수를 참조한다.
그러면 plusThree 5 는 무엇을 반환하는지 보자.
1 2 3 4 5 6 | Prelude> plusThree 5 8 it :: Integer Prelude> | cs |
간단히 말해 plusThree 는 마치 계산기에서 3을 누르고 + 를 누른 것처럼 작동한다.
1 2 3 4 5 6 7 | Prelude> let add x y = x + y ::Integer add :: Integer -> Integer -> Integer Prelude> let plusthree = add 3 plusthree :: Integer -> Integer | cs |
1 2 3 4 5 6 7 | Prelude> let add x y = x + y ::Integer add :: Integer -> Integer -> Integer Prelude> let add3 x y z = x + y + z ::Integer add3 :: Integer -> Integer -> Integer -> Integer | cs |
인수의 부분 적용을 가능하게 하는 curried form 으로 정의되었다고 말할 수 있다. partially applicable function 의 아이디어는 Moses Schönfinkel 에 의해 처음 언급되었다. 그리고 Haskell B. Curry 에 의해 더 발전했다. 두 명 모두 1920년대에 David Hilbert 와 같이 연구했다.
In mathematics and computer science, currying is the technique of translating the evaluation of a function that takes multiple arguments (or a tuple of arguments) into evaluating a sequence of functions, each with a single argument. Currying is related to, but not the same as, partial application.