带有 2 个箭头的 lambda 在 Java 8 中是什么意思?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/32820722/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-11-02 20:49:42  来源:igfitidea点击:

What does lambda with 2 arrows mean in Java 8?

javalambdajava-8currying

提问by gstackoverflow

I have read several Java 8 tutorials before.

我之前读过几篇 Java 8 教程。

Right now I encountered following topic: Does java support Currying?

现在我遇到了以下主题: Does java support Currying?

Here, I see following code:

在这里,我看到以下代码:

IntFunction<IntUnaryOperator> curriedAdd = a -> b -> a + b;
System.out.println(curriedAdd.apply(1).applyAsInt(12));

I understand that this example sum 2 elements but I cannot understand the construction:

我知道这个例子总结了 2 个元素,但我无法理解结构:

a -> b -> a + b;

According to the left part of expression, this row should implement following function:

根据表达式的左侧部分,该行应实现以下功能:

R apply(int value); 

Before this, I only met lambdas only with one arrow.

在此之前,我只用一个箭头遇到了 lambdas。

采纳答案by Adam

If you express this as non-shorthand lambda syntax or pre-lambda Java anonymous class syntax it is clearer what is happening...

如果您将其表示为非速记 lambda 语法或 pre-lambda Java 匿名类语法,则更清楚发生了什么......

The original question. Why are two arrows? Simple, there are two functions being defined... The first function is a function-defining-function, the second is the result of that function, which also happens to be function. Each requires an ->operator to define it.

原来的问题。为什么是两个箭头?很简单,定义了两个函数……第一个函数是一个函数定义函数,第二个是那个函数的结果,也恰好是函数。每个都需要一个->运算符来定义它。

Non-shorthand

非速记

IntFunction<IntUnaryOperator> curriedAdd = (a) -> {
    return (b) -> {
        return a + b;
    };
};

Pre-Lambda before Java 8

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;
    }
};

回答by Alexis C.

An IntFunction<R>is a function int -> R. An IntUnaryOperatoris a function int -> int.

AnIntFunction<R>是一个函数int -> R。AnIntUnaryOperator是一个函数int -> int

Thus an IntFunction<IntUnaryOperator>is a function that takes an intas parameter and return a function that takes an intas parameter and return an 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

Maybe it is more clear if you use anonymous classes to "decompose" the lambda:

如果您使用匿名类来“分解” lambda,也许会更清楚:

IntFunction<IntUnaryOperator> add = new IntFunction<IntUnaryOperator>() {
    @Override
    public IntUnaryOperator apply(int a) {
        return new IntUnaryOperator() {
            @Override
            public int applyAsInt(int b) {
                return a + b;
            }
        };
    }
};

回答by Tagir Valeev

Adding parentheses may make this more clear:

添加括号可能会使这一点更清楚:

IntFunction<IntUnaryOperator> curriedAdd = a -> (b -> (a + b));

Or probably intermediate variable may help:

或者中间变量可能有帮助:

IntFunction<IntUnaryOperator> curriedAdd = a -> {
    IntUnaryOperator op = b -> a + b;
    return op;
};

回答by Tunaki

Let's rewrite that lambda expression with parentheses to make it more clear:

让我们用括号重写 lambda 表达式以使其更清楚:

IntFunction<IntUnaryOperator> curriedAdd = a -> (b -> (a + b));

So we are declaring a function taking an intwhich returns a Function. More specifically, the function returned takes an intand returns an int(the sum of the two elements): this can be represented as an IntUnaryOperator.

所以我们声明了一个函数,它使用 anint返回 a Function。更具体地说,返回的函数采用 anint并返回 an int(两个元素的总和):这可以表示为 an IntUnaryOperator

Therefore, curriedAddis a function taking an intand returning an IntUnaryOperator, so it can be represented as IntFunction<IntUnaryOperator>.

因此,curriedAdd是一个函数,接受一个int并返回一个IntUnaryOperator,所以它可以表示为IntFunction<IntUnaryOperator>

回答by a better oliver

It's two lambda expressions.

这是两个 lambda 表达式。

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

回答by dhke

If you look at IntFunctionit might become clearer: IntFunction<R>is a FunctionalInterface. It represents a function that takes an intand returns a value of type R.

如果你看IntFunction它可能会变得更清楚:IntFunction<R>是一个FunctionalInterface. 它表示一个函数,它接受一个int并返回一个类型为 的值R

In this case, the return type Ris also a FunctionalInterface, namely an IntUnaryOperator. So the first(outer) function itself returns a function.

在这种情况下,返回类型R也是 a FunctionalInterface,即 an IntUnaryOperator。所以第一个(外部)函数本身返回一个函数。

In this case: When applied to an int, curriedAddis supposed to return a function that again takes an int(and returns again int, because that's what IntUnaryOperatordoes).

在这种情况下:当应用于 an 时intcurriedAdd应该返回一个再次接受 an 的函数int(并再次返回int,因为这就是这样IntUnaryOperator做的)。

In functional programming it is common to write the type of a function as param -> return_valueand you see exactly that here. So the type of curriedAddis int -> int -> int(or int -> (int -> int)if you like that better).

在函数式编程中,将函数的类型写为 as 是很常见的param -> return_value,你在这里看到的正是这一点。所以类型curriedAddint -> int -> int(或者int -> (int -> int)如果你更喜欢那个)。

Java 8's lambda syntax goes along with this. To define such a function, you write

Java 8 的 lambda 语法与此一致。要定义这样的函数,您可以编写

a -> b -> a + b

which is very much similar to actual lambda calculus:

这与实际的 lambda 演算非常相似:

λa λb a + b

λb a + bis a function that takes a single parameter band returns a value (the sum). λa λb a + bis a function that accepts a single parameter aand returns another function of a single parameter. λa λb a + breturns λb a + bwith aset to the parameter value.

λb a + b是一个接受单个参数b并返回一个值(总和)的函数。λa λb a + b是一个接受单个参数a并返回单个参数的另一个函数的函数。λa λb a + b收益λb a + ba设定的参数值。