Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Composition of BiFunctions

Tags:

java

java-8

I have a stream of BiFunctions which I want to reduce to a single BiFunction.

To be more specific I have a stream of BiFunctions

BiFunction<x,y,y>

Where x and y denote the types of the arguments.

Assuming I have two functions

f (x, y) -> y
g (x, y) -> y

I want to compose them to the function

h(x, y) -> f(x, g(x, y))

Is this possible using Java 8 streams, and if not, what would be the most elegant way asides of just looping over all the available functions and composing them in another way?

like image 540
lup3x Avatar asked Dec 25 '16 18:12

lup3x


People also ask

What is composition function with example?

A composite function is a function that depends on another function. A composite function is created when one function is substituted into another function. For example, f(g(x)) is the composite function that is formed when g(x) is substituted for x in f(x). f(g(x)) is read as “f of g of x”.

Why do we use composition of functions?

If we are given two functions, we can create another function by composing one function into the other. The steps required to perform this operation are similar to when any function is solved for any given value. Such functions are called composite functions.


2 Answers

Using x=Integer and y=String, you could define f and g as:

BiFunction<Integer, String, String> f = (i, s) -> i + "-f-" + s;
BiFunction<Integer, String, String> g = (i, s) -> i + "-g-" + s;

And the h function could be built using a reduction:

BiFunction<Integer, String, String> h = Stream.of(f, g)
        .reduce((f_, g_) -> (i, s) -> f_.apply(i, g_.apply(i, s)))
        .get(); //we know the stream is not empty so we can call get directly

If you apply h to 1 and "s", it will return 1-f-1-g-s.

like image 85
assylias Avatar answered Oct 26 '22 09:10

assylias


As a slight modification to the answer by assylias : Depending on the application pattern, you can also use the Stream#reduce method that accepts an identity as the first argument, which in this case is the "identity BiFunction" (actually, a projection on the second argument).

import java.util.function.BiFunction;
import java.util.stream.Stream;

public class BiFunctionsComposition
{
    public static void main(String[] args)
    {
        BiFunction<String, String, String> f = (x,y) -> "f("+x+","+y+")";
        BiFunction<String, String, String> g = (x,y) -> "g("+x+","+y+")";

        BiFunction<String, String, String> h = Stream.of(f, g)
            .reduce((x,y) -> y, (ff,gg) -> (x,y) -> ff.apply(x, gg.apply(x, y)));

        String result = h.apply("A", "B");
        System.out.println(result); // Prints f(A,g(A,B))
    }
}
like image 32
Marco13 Avatar answered Oct 26 '22 10:10

Marco13