0

Is that the best way to implement a "TriFunction" without declaring an own Interface? And how is that construct called?

import java.util.function.BiFunction;
import java.util.function.Function;

public class Rec {
    public static Function<Integer, Function<Integer, Function>> myPowerTriFunction = x -> y -> f -> y == 0 ? 1 : x * (Integer) ((Function<Integer, Function<Integer, Function>>) f).apply(x).apply(y - 1).apply(f);
    public static BiFunction<Integer, Integer, Integer> myPowerBiFunction = (x, y) -> (Integer) myPowerTriFunction.apply(x).apply(y).apply(myPowerTriFunction);

    public static void main(String[] args) {
        System.out.println(myPowerBiFunction.apply(3, 5)); // Prints 243
    }
}
unknown_dcba
  • 135
  • 5
  • Why would you not want to define your own interface? It would take less time than it took to write this question. – Andy Turner Jul 13 '20 at 21:26
  • It seems to me like you've spec'd out requirements for a bi-function. Your example takes in 2 arguments and returns a value, which is what a bi-function does. You've hidden some of the complexity in the function, but that doesn't really make it a tri-function. A tri-function would take 3 values and return 1. If that's what you need, I think you would want/need to create an interface. A good example of doing that can be found in this answer: https://stackoverflow.com/a/19649473/2124562. – tune5ths Jul 13 '20 at 21:41
  • This is recursive, so it's not really a duplicate of the other question, is it? – user Jul 13 '20 at 22:24
  • If you want to make `Function` objects that are recursive, try something like the Y combinator. Here's a basic Java implementation - https://repl.it/repls/GenuineSeashellBootstrapping (Note: this isn't the actual Y-combinator, which would require defining an interface, since it uses a recursive type) – user Jul 13 '20 at 22:31
  • Related: [Implement recursive lambda function using Java 8](https://stackoverflow.com/questions/19429667/implement-recursive-lambda-function-using-java-8) – user Jul 13 '20 at 22:45
  • 1
    @user Yes, this isn't really a duplicate of the other question... Maybe this question could be reopened... Thanks at all for your answers. :) – unknown_dcba Jul 18 '20 at 21:32

1 Answers1

0

You are trying to use a technique called currying. The basic idea is that a function of two or more arguments f(x, y) can be represented as a function that returns a function f(x)(y).

For example here's a "curried" function that adds 3 numbers:

public static Function<Integer, Function<Integer, Function<Integer, Integer>>>
    sum3 = x -> y -> z -> x + y + z;

This style does not really suit Java because a key philosophy of the language is that names are meaningful. Creating anonymous functions goes against this idea.

In your own code, you should not use raw types such as Function. If you don't know/care about the type, use a wildcard ?:

public static Function<Integer, Function<Integer, Function<?,?>>> myPowerTriFunction;
Joni
  • 108,737
  • 14
  • 143
  • 193
  • 1
    I know this is the accepted answer, but it doesn't address the fact that the OP wants a recursive function – user Jul 13 '20 at 22:32