delita
delita

Reputation: 1581

Composing Function interfaces in Java

interface PairFloatFunction {
   Pair<Float,Float> calculate(int x);
}

interface FloatFunction {
   float calculate(int x);
}

class SQRT implements PairFloatFunction {
   public Pair<Float, Float> calculate(int x) {
      return new Pair(-pow(x,0.5), pow(x,0.5))
   }
 }

class ADD_ONE implements FloatFunction {
   public Float calculate(int x) {
      return x + 1;
   }
}

I would like to compose to functions so that I can perfom this:

ADD_ONE(SQRT(100)) = Pair(-9,11)

I understand i need to 'glue' the functions together. but I am stuck here, should I be writing another method overload that does this?

class ADD_ONE {
   public Float calculate(int x) {
      return x + 1;
   }
   public Float calculate(Pair pair) {
     pair.first += 1;
     pair.second += 1;
     return pair
   }
}

Sorry I am new to functional programming, is there a nice solution to this?

Upvotes: 0

Views: 272

Answers (1)

Mr. Polywhirl
Mr. Polywhirl

Reputation: 48600

Based on your code above, I would create a generic interface which will be responsible for calculating.

interface Calculation<T> {
    T calculate(int x);
}

This is a Java 7 implementation, because you did not specify Java 8.

Further Explanation

The return type T is generic; meaning that your implementation can return any Object type but it must consume an integer x. You could even make the x parameter generic so that you can decide what function will take as a parameter type.

Note: The static classes would be moved into their own class files and the static modifier should be removed. I only did this to consolidate everything for the sake of brevity.

Full Example

public class Functional {
    static interface Calculation<T> {
        T calculate(int x);
    }

    static class Sqrt implements Calculation<Pair<Float, Float>> {
        public Pair<Float, Float> calculate(int x) {
            float root = (float) Math.pow(x, 0.5);
            return new Pair<Float, Float>(-root, +root);
        }
    }

    static class AddOne implements Calculation<Float> {
        public Float calculate(int x) {
            return (float) (x + 1);
        }
    }

    static <T> T calculate(int x, Calculation<T> calculation) {
        return calculation.calculate(x);
    }

    public static void main(String[] args) {
        Calculation<?>[] calculations = { new Sqrt(), new AddOne() };
        int x = 49;

        for (Calculation<?> calculation : calculations) {
            System.out.printf("%s: %s%n",
                    calculation.getClass().getSimpleName(),
                    calculate(x, calculation));
        }
    }

    static class Pair<T, U> {
        private T val1;
        private U val2;

        public Pair(T val1, U val2) {
            this.val1 = val1;
            this.val2 = val2;
        }

        protected T getVal1() {
            return val1;
        }

        protected void setVal1(T val1) {
            this.val1 = val1;
        }

        protected U getVal2() {
            return val2;
        }

        protected void setVal2(U val2) {
            this.val2 = val2;
        }

        @Override
        public String toString() {
            return "(" + val1 + ", " + val2 + ")";
        }
    }
}

Output

Sqrt: (-7.0, 7.0)
AddOne: 50.0

Upvotes: 1

Related Questions