[java] Java 8에서 2 개의 화살표가있는 람다는 무엇을 의미합니까?

전에 몇 가지 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.

이 경우 반환 유형 RFunctionalInterface, 즉 IntUnaryOperator. 따라서 첫 번째 (외부) 함수 자체는 함수를 반환합니다.

이 경우 :에 적용하면 int, curriedAdd다시받는 함수 반환하도록되어 int(다시 되돌아 int가 무엇 때문에, IntUnaryOperator않습니다).

함수형 프로그래밍에서는 함수 유형을 다음 param -> return_value과 같이 작성하는 것이 일반적 이며 여기에서 정확히 볼 수 있습니다. 따라서 유형 curriedAddint -> 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.


답변