Java 8 中带有 2 个箭头的 lambda 是什么意思?
What does lambda with 2 arrows mean in Java 8?
我已经阅读了几个 Java 8 个教程。
现在我遇到了以下话题:
Does java support 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);
在此之前,我只用一个箭头就遇到了 lambdas。
如果您将其表达为非shorthand lambda 语法或pre-lambda Java 匿名class 语法,则发生的事情会更清楚...
原题。为什么是两个箭头?很简单,定义了两个函数...第一个函数是函数定义函数,第二个是该函数的结果,它也恰好是函数。每个都需要一个 ->
运算符来定义它。
非shorthand
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
。 IntUnaryOperator
是一个函数 int -> int
.
因此,IntFunction<IntUnaryOperator>
是一个以 int
作为参数的函数,而 return 是一个以 int
作为参数和 return 的函数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
如果使用匿名 类 到 "decompose" 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;
}
};
}
};
让我们用括号重写 lambda 表达式,使其更清晰:
IntFunction<IntUnaryOperator> curriedAdd = a -> (b -> (a + b));
所以我们声明一个函数接受一个 int
,其中 returns 一个 Function
。更具体地说,返回的函数采用 int
和 returns 和 int
(两个元素的总和):这可以表示为 IntUnaryOperator
.
因此,curriedAdd
是一个接受int
并返回IntUnaryOperator
的函数,所以它可以表示为IntFunction<IntUnaryOperator>
.
添加括号可能会更清楚:
IntFunction<IntUnaryOperator> curriedAdd = a -> (b -> (a + b));
或者中间变量可能有帮助:
IntFunction<IntUnaryOperator> curriedAdd = a -> {
IntUnaryOperator op = b -> a + b;
return op;
};
如果您查看 IntFunction
,它可能会变得更清楚:IntFunction<R>
是一个 FunctionalInterface
。它表示一个函数,该函数采用 int
和 return 类型的值 R
.
在这种情况下,return类型R
也是一个FunctionalInterface
,即一个IntUnaryOperator
。所以 first(外部)函数本身 return 是一个函数。
在这种情况下:当应用于 int
时,curriedAdd
应该 return 一个函数,该函数再次采用 int
(和 return又是 int
,因为那是 IntUnaryOperator
所做的)。
在函数式编程中,将函数类型写成 param -> return_value
很常见,您可以在此处看到。所以curriedAdd
的类型是int -> int -> int
(或者int -> (int -> int)
,如果你更喜欢的话)。
Java 8 的 lambda 语法与此相符。要定义这样一个函数,你写
a -> b -> a + b
这与实际的 lambda 演算非常相似:
λa λb a + b
λb a + b
是一个函数,它采用单个参数 b
和 returns 一个值(总和)。 λa λb a + b
是一个接受单参数的函数,a
和return是另一个单参数的函数。 λa λb a + b
returns λb a + b
with a
set to the parameter value.
是两个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
我已经阅读了几个 Java 8 个教程。
现在我遇到了以下话题: Does java support 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);
在此之前,我只用一个箭头就遇到了 lambdas。
如果您将其表达为非shorthand lambda 语法或pre-lambda Java 匿名class 语法,则发生的事情会更清楚...
原题。为什么是两个箭头?很简单,定义了两个函数...第一个函数是函数定义函数,第二个是该函数的结果,它也恰好是函数。每个都需要一个 ->
运算符来定义它。
非shorthand
IntFunction<IntUnaryOperator> curriedAdd = (a) -> {
return (b) -> {
return a + b;
};
};
Java 8
之前的 Pre-LambdaIntFunction<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
。 IntUnaryOperator
是一个函数 int -> int
.
因此,IntFunction<IntUnaryOperator>
是一个以 int
作为参数的函数,而 return 是一个以 int
作为参数和 return 的函数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
如果使用匿名 类 到 "decompose" 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;
}
};
}
};
让我们用括号重写 lambda 表达式,使其更清晰:
IntFunction<IntUnaryOperator> curriedAdd = a -> (b -> (a + b));
所以我们声明一个函数接受一个 int
,其中 returns 一个 Function
。更具体地说,返回的函数采用 int
和 returns 和 int
(两个元素的总和):这可以表示为 IntUnaryOperator
.
因此,curriedAdd
是一个接受int
并返回IntUnaryOperator
的函数,所以它可以表示为IntFunction<IntUnaryOperator>
.
添加括号可能会更清楚:
IntFunction<IntUnaryOperator> curriedAdd = a -> (b -> (a + b));
或者中间变量可能有帮助:
IntFunction<IntUnaryOperator> curriedAdd = a -> {
IntUnaryOperator op = b -> a + b;
return op;
};
如果您查看 IntFunction
,它可能会变得更清楚:IntFunction<R>
是一个 FunctionalInterface
。它表示一个函数,该函数采用 int
和 return 类型的值 R
.
在这种情况下,return类型R
也是一个FunctionalInterface
,即一个IntUnaryOperator
。所以 first(外部)函数本身 return 是一个函数。
在这种情况下:当应用于 int
时,curriedAdd
应该 return 一个函数,该函数再次采用 int
(和 return又是 int
,因为那是 IntUnaryOperator
所做的)。
在函数式编程中,将函数类型写成 param -> return_value
很常见,您可以在此处看到。所以curriedAdd
的类型是int -> int -> int
(或者int -> (int -> int)
,如果你更喜欢的话)。
Java 8 的 lambda 语法与此相符。要定义这样一个函数,你写
a -> b -> a + b
这与实际的 lambda 演算非常相似:
λa λb a + b
λb a + b
是一个函数,它采用单个参数 b
和 returns 一个值(总和)。 λa λb a + b
是一个接受单参数的函数,a
和return是另一个单参数的函数。 λa λb a + b
returns λb a + b
with a
set to the parameter value.
是两个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