전에 몇 가지 Java 8 자습서를 읽었습니다.
바로 지금 다음 주제를 만났습니다.
Java는 Currying을 지원합니까?
여기에 다음 코드가 있습니다.
IntFunction<IntUnaryOperator> curriedAdd = a -> b -> a + b;
System.out.println(curriedAdd.apply(1).applyAsInt(12));
이 예제에는 2 개의 요소가 합산되어 있음을 이해하지만 구성을 이해할 수 없습니다.
a -> b -> a + b;
표현식의 왼쪽 부분에 따르면이 행은 다음 기능을 구현해야합니다.
R apply(int value);
그 전에는 화살 하나만으로 람다를 만났습니다.
답변
이것을 축약이 아닌 람다 구문 또는 사전 람다 Java 익명 클래스 구문으로 표현하면 무슨 일이 일어나고 있는지 더 분명합니다.
원래 질문입니다. 왜 두 개의 화살이 있습니까? 간단합니다. 정의되는 두 가지 함수가 있습니다 … 첫 번째 함수는 함수 정의 함수이고 두 번째 함수는 함수의 결과입니다. 각각 ->
을 정의 하려면 연산자가 필요 합니다.
비 속기
IntFunction<IntUnaryOperator> curriedAdd = (a) -> {
return (b) -> {
return a + b;
};
};
Java 8 이전의 Pre-Lambda
IntFunction<IntUnaryOperator> curriedAdd = new IntFunction<IntUnaryOperator>() {
@Override
public IntUnaryOperator apply(final int value) {
IntUnaryOperator op = new IntUnaryOperator() {
@Override
public int applyAsInt(int operand) {
return operand + value;
}
};
return op;
}
};
답변
안 IntFunction<R>
은 함수 int -> R
입니다. An IntUnaryOperator
은 함수 int -> int
입니다.
따라서 IntFunction<IntUnaryOperator>
는int
파라미터로하고을 취하는 함수 리턴 int
파라미터로하고을 반환이 int
.
a -> b -> a + b;
^ | |
| ---------
| ^
| |
| The IntUnaryOperator (that takes an int, b) and return an int (the sum of a and b)
|
The parameter you give to the IntFunction
익명 클래스를 사용하여 람다를 “분해”하는 것이 더 분명 할 수 있습니다.
IntFunction<IntUnaryOperator> add = new IntFunction<IntUnaryOperator>() {
@Override
public IntUnaryOperator apply(int a) {
return new IntUnaryOperator() {
@Override
public int applyAsInt(int b) {
return a + b;
}
};
}
};
답변
괄호를 추가하면 더 명확해질 수 있습니다.
IntFunction<IntUnaryOperator> curriedAdd = a -> (b -> (a + b));
또는 중간 변수가 도움이 될 수 있습니다.
IntFunction<IntUnaryOperator> curriedAdd = a -> {
IntUnaryOperator op = b -> a + b;
return op;
};
답변
더 명확하게하기 위해 괄호로 람다 식을 다시 작성해 보겠습니다.
IntFunction<IntUnaryOperator> curriedAdd = a -> (b -> (a + b));
그래서 우리는를 int
반환 하는를 취하는 함수를 선언하고 있습니다 Function
. 더 구체적으로, 반환 된 함수는를 취하고 (두 요소의 합)을 int
반환합니다 int
. 이것은 IntUnaryOperator
.
따라서를 curriedAdd
취하고 int
를 반환하는 함수 IntUnaryOperator
이므로 IntFunction<IntUnaryOperator>
.
답변
두 개의 람다 식입니다.
IntFunction<IntUnaryOperator> curriedAdd =
a -> { //this is for the fixed value
return b -> { //this is for the add operation
return a + b;
};
}
IntUnaryOperator addTwo = curriedAdd.apply(2);
System.out.println(addTwo.applyAsInt(12)); //prints 14
답변
당신이 보면 IntFunction
그것은 명확하게 될 수 있습니다 IntFunction<R>
입니다 FunctionalInterface
. 를 취하고 int
유형 값을 반환 하는 함수를 나타냅니다 R
.
이 경우 반환 유형 R
도 FunctionalInterface
, 즉 IntUnaryOperator
. 따라서 첫 번째 (외부) 함수 자체는 함수를 반환합니다.
이 경우 :에 적용하면 int
, curriedAdd
다시받는 함수 반환하도록되어 int
(다시 되돌아 int
가 무엇 때문에, IntUnaryOperator
않습니다).
함수형 프로그래밍에서는 함수 유형을 다음 param -> return_value
과 같이 작성하는 것이 일반적 이며 여기에서 정확히 볼 수 있습니다. 따라서 유형 curriedAdd
은 int -> int -> int
(또는 int -> (int -> int)
더 나은 경우)입니다.
Java 8의 람다 구문은 이와 함께 진행됩니다. 이러한 함수를 정의하려면
a -> b -> a + b
실제 람다 미적분과 매우 유사합니다.
λa λb a + b
λb a + b
단일 매개 변수를 취하고 b
값 (합계)을 리턴 하는 함수입니다 . λa λb a + b
단일 매개 변수를 받아들이고 단일 매개 변수의 a
다른 함수를 반환하는 함수입니다. 매개 변수 값 으로 설정된 상태로 λa λb a + b
반환 λb a + b
됩니다 a
.
답변
