gst*_*low 118 java lambda currying java-8
我以前读了几篇Java 8教程.
现在我遇到了以下主题: java支持Currying吗?
在这里,我看到以下代码:
IntFunction<IntUnaryOperator> curriedAdd = a -> b -> a + b;
System.out.println(curriedAdd.apply(1).applyAsInt(12));
Run Code Online (Sandbox Code Playgroud)
我明白这个例子总结了2个元素,但我无法理解构造:
a -> b -> a + b;
Run Code Online (Sandbox Code Playgroud)
根据表达式的左侧部分,该行应实现以下功能:
R apply(int value);
Run Code Online (Sandbox Code Playgroud)
在此之前,我只用一支箭只遇到了lambdas.
Ada*_*dam 118
如果你把它表达为非简写lambda语法或pre-lambda Java匿名类语法,那么发生的事情会更清楚......
原来的问题.为什么是两支箭?很简单,定义了两个函数......第一个函数是函数定义函数,第二个函数是函数的结果,它也恰好是函数.每个都需要->操作员来定义它.
IntFunction<IntUnaryOperator> curriedAdd = (a) -> {
return (b) -> {
return a + b;
};
};
Run Code Online (Sandbox Code Playgroud)
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;
}
};
Run Code Online (Sandbox Code Playgroud)
Ale*_* C. 48
一个IntFunction<R>是一个功能int -> R.一个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
Run Code Online (Sandbox Code Playgroud)
也许更清楚的是你是否使用匿名类来"分解"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;
}
};
}
};
Run Code Online (Sandbox Code Playgroud)
Tag*_*eev 29
添加括号可能会更清楚:
IntFunction<IntUnaryOperator> curriedAdd = a -> (b -> (a + b));
Run Code Online (Sandbox Code Playgroud)
或者中间变量可能有帮助:
IntFunction<IntUnaryOperator> curriedAdd = a -> {
IntUnaryOperator op = b -> a + b;
return op;
};
Run Code Online (Sandbox Code Playgroud)
Tun*_*aki 24
让我们用括号重写那个lambda表达式,使其更清晰:
IntFunction<IntUnaryOperator> curriedAdd = a -> (b -> (a + b));
Run Code Online (Sandbox Code Playgroud)
所以我们声明一个函数,int它返回一个Function.更具体地说,返回的函数接受int并返回一个int(两个元素的总和):这可以表示为IntUnaryOperator.
因此,curriedAdd是一个带有int和返回的函数IntUnaryOperator,所以它可以表示为IntFunction<IntUnaryOperator>.
这是两个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
Run Code Online (Sandbox Code Playgroud)
如果你看一下IntFunction它可能会变得更清楚:IntFunction<R>是一个FunctionalInterface.它表示一个函数,它接受一个int并返回一个类型的值R.
在这种情况下,返回类型R也是a FunctionalInterface,即a IntUnaryOperator.所以第一个(外部)函数本身返回一个函数.
在这种情况下:当应用于a时int,curriedAdd应该返回一个再次获取的函数int(并再次返回int,因为那是什么IntUnaryOperator).
在函数式编程中,通常将函数的类型编写为,param -> return_value并且您在此处可以看到.所以类型curriedAdd是int -> int -> int(或者int -> (int -> int)如果你更喜欢那样).
Java 8的lambda语法与此一致.要编写这样的函数,请编写
a -> b -> a + b
Run Code Online (Sandbox Code Playgroud)
这与实际的lambda演算非常相似:
?a ?b a + b
Run Code Online (Sandbox Code Playgroud)
?b a + b是一个函数,它接受一个参数b并返回一个值(总和).?a ?b a + b是一个接受单个参数a并返回单个参数的另一个函数的函数.?a ?b a + b返回?b a + b与a设置该参数值.