3

In the book Functional Programming in Java the author builds a compose function using only the Function<T, U> interface (the interface however is not one shipped with Java 8 but very similar though) the snippet of which is show below

public interface Function<T, U> {
  U apply(T arg);
}

though I could understand the method version of compose below, which takes in 2 functions and return a composed function

public static final Function<Integer, Integer> compose (final Function<Integer, Integer> f1, 
                                   final Function<Integer, Integer> f2) {
         arg -> f1.apply(f2.apply(arg));
}

I just couldn't get my head around the below compose implementation with Function<> and lambdas

static Function<Function<Integer, Integer>,
            Function<Function<Integer, Integer>,
                    Function<Integer, Integer>>> compose =
            x -> y -> z -> x.apply(y.apply(z));

PS: couldn't get my mind out of this and move forward with remaining sections :(

4
  • 1
    stackoverflow.com/questions/19834611/… maybe Commented Jun 23, 2016 at 15:48
  • I see how to compose two fxn with the given functions, but concern was about how to implement that compose function Commented Jun 23, 2016 at 15:51
  • 1
    stackoverflow.com/questions/32820722/… Commented Jun 23, 2016 at 16:05
  • This really lacks C pointers! Commented Jun 24, 2016 at 15:38

3 Answers 3

5

Referring to a Function<Integer, Integer> as an integer function, what you have there is a function that maps {an integer function} to {a function mapping an integer function to another integer function}.

Specifically, when given an integer function x, it returns a function that, given an integer function y, returns an integer function that maps an integer z to x(y(z)).

Given a function x
Returns a function that:
    Given a function y
    Returns a function that:
        Given an integer z
        Returns x(y(z))
Sign up to request clarification or add additional context in comments.

Comments

3

Let me use a simpler λ-notation omitting types, where λx.E means a function that takes an argument x and returns the value of E. For instance, λx. λy. x+y is a function that takes x and returns λy. x+y, which itself is a function that takes y and returns x+y. Let us also write λ(x,y).E for a function that takes two arguments x and y, and returns the value of E. For example, λ(x,y). x+y is a function that takes x and y at once and returns x+y.

Then the "two arguments at once" version of compose is: λ(f,g). λx.f(g(x))

The second, "one-by-one" version is: λf. λg. λx.f(g(x))

Everything else that looks scary in the Java code is just type annotations. Both f and g (as well as the result of compose) have type Function < Integer, Integer > . Let's write this type as T. Then the second version of compose has type Function < T, Function < T, T > >.

P.S. Functions like λx. λy. E are called curried, while λ(x,y). E is uncurried. See: https://en.wikipedia.org/wiki/Currying

Comments

0

This type of illustration might make more sense using different types and/or generics.

Function<Function<R, S>,
         Function<Function<T, R>,
                  Function<T, S>>> compose = x -> y -> z -> x.apply(y.apply(z));

edit: Types were incorrectly placed (this is why it's a better exercise when they're different)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.