Reputation: 417
The Function
interface has the compose()
and andThen()
methods while the BiFunction
interface only has the andThen()
method. My question is simply how could the corresponding method be implemented? I'll try to represent this graphically.
The single letters are parameterized types as defined by Java's Function
and BiFunction
interfaces. Arrows are the flow of inputs and outputs. Boxes with connected arrows are functions. The dotted box just shows how the apply method is used.
Upvotes: 2
Views: 312
Reputation: 417
The Function
's Compose()
and andThen()
methods are straightforward since a Function
has one input and one output and therefore can only be strung sequentially with another in two ways.
Since a BiFunction
has one output, the "after" function has to be something with only one corresponding input, and Function
fits the bill. And since it has two inputs, the "before" function needs to be something with two outputs? You can't have a method return two things, so there seemingly can't be a "before". The return type of each of these methods is the same as the interface they are defined in, so the proposed method should return a BiFunction
.
My proposal then is a method that takes two Function
s as input and returns a BiFunction
. I'm not sure what else it could even be. It couldn't be two BiFunction
s because then the return type would have to be a QuaterFunction
.
Here is the code as it would be written in the Java Library:
public interface BiFunction<T, U, R> {
// apply()...
default <V, W> BiFunction<V, W, R> compose(
Function<? super V, ? extends T> beforeLeft,
Function<? super W, ? extends U> beforeRight) {
Objects.requireNonNull(beforeLeft);
Objects.requireNonNull(beforeRight);
return (V v, W w) -> apply(beforeLeft.apply(v), beforeRight.apply(w));
}
// andThen()...
}
Here is the finished graph:
Here it is in use:
BiFunction<Integer, Integer, Integer> add = Integer::sum;
Function<Integer, Integer> abs = Math::abs;
BiFunction<Integer, Integer, Integer> addAbs = add.compose(abs, abs);
System.out.println(addAbs.apply(-2, -3));
// output: 5
If you want to actually test this, you can do something like this:
public interface BiFunctionWithCompose<T, U, R> extends BiFunction<T, U, R> {...
Or like this:
package myutil;
public interface BiFunction<T, U, R> extends java.util.function.BiFunction<T, U, R> {...
I have no idea if this will be useful to anyone, but it was really fun to think through and write. Have a wonderful day.
Upvotes: 2