简体   繁体   English

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

[英]What does lambda with 2 arrows mean in Java 8?

I have read several Java 8 tutorials before. 我以前读了几篇Java 8教程。

Right now I encountered following topic: Does java support Currying? 现在我遇到了以下主题: java支持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。

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之前的前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;
    }
};

An IntFunction<R> is a function int -> R . IntFunction<R>是一个函数int -> R An IntUnaryOperator is a function int -> int . IntUnaryOperator是一个函数int -> int

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

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

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 int which returns a Function . 因此,我们宣布一个函数获取int它返回一个Function More specifically, the function returned takes an int and returns an int (the sum of the two elements): this can be represented as an IntUnaryOperator . 更具体地说,返回的函数接受一个int并返回一个int (两个元素的总和):这可以表示为IntUnaryOperator

Therefore, curriedAdd is a function taking an int and returning an IntUnaryOperator , so it can be represented as IntFunction<IntUnaryOperator> . 因此, curriedAdd是一个接受int并返回IntUnaryOperator ,因此它可以表示为IntFunction<IntUnaryOperator>

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

If you look at IntFunction it might become clearer: IntFunction<R> is a FunctionalInterface . 如果你看一下IntFunction它可能会变得更清晰: IntFunction<R>是一个FunctionalInterface It represents a function that takes an int and returns a value of type R . 它表示一个函数,它接受一个int并返回一个R类型的值。

In this case, the return type R is also a FunctionalInterface , namely an IntUnaryOperator . 在这种情况下,返回类型R也是FunctionalInterface ,即IntUnaryOperator So the first (outer) function itself returns a function. 所以第一个 (外部)函数本身返回一个函数。

In this case: When applied to an int , curriedAdd is supposed to return a function that again takes an int (and returns again int , because that's what IntUnaryOperator does). 在这种情况下:当应用于intcurriedAdd应该返回一个再次接受int的函数(并再次返回int ,因为这是IntUnaryOperator所做的)。

In functional programming it is common to write the type of a function as param -> return_value and you see exactly that here. 在函数式编程中,通常将函数的类型写为param -> return_value ,你可以在这里看到。 So the type of curriedAdd is int -> int -> int (or int -> (int -> int) if you like that better). 所以curriedAdd的类型是int -> int -> int (或int -> (int -> int)如果你更喜欢那样)。

Java 8's lambda syntax goes along with this. Java 8的lambda语法与此一致。 To define such a function, you write 要编写这样的函数,请编写

a -> b -> a + b

which is very much similar to actual lambda calculus: 这与实际的lambda演算非常相似:

λa λb a + b

λb a + b is a function that takes a single parameter b and returns a value (the sum). λb a + b是一个函数,它接受一个参数b并返回一个值(总和)。 λa λb a + b is a function that accepts a single parameter a and returns another function of a single parameter. λa λb a + b是接受单个参数a并返回单个参数a另一个函数的函数。 λa λb a + b returns λb a + b with a set to the parameter value. λa λb a + b返回λb a + ba设置为参数值。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM