Currying in Java

Function<Integer, Function<Integer, Integer>> Carry(BiFunction<Integer, Integer, Integer> f) {
    return a -> b -> f.apply(ab);
}

BiFunction<Integer, Integer, Integer> avg = (ab) -> (a + b)/2;
Integer n1 = avg.apply(1, 3);
//n1 is 2

//first universal method
Function<Integer, Integer> avg1 = Carry(avg).apply(1);
//avg1 is avg func with first param = 1
int n2 = avg1.apply(3);
//n2 is 2 = (1 + 3)/2

//second specialized method
IntFunction<IntUnaryOperator> curriedAvg = a -> b -> (a + b)/2;
IntUnaryOperator avg3 = curriedAvg.apply(3);
int n3 = avg3.applyAsInt(3);
//n3 is 3 = (3 + 3)/2