Functions.java
package church.lang;

public class Functions {
    public interface Function1<I1, O> {
        public O of(I1 i1);
    }

    public interface Function2<I1, I2, O> extends Function1<I1, Function1<I2, O>> {
        public O of(I1 i1, I2 i2);

        default Function1<I2, O> of(I1 i1) {
            return i2 -> of(i1, i2);
        }
    }

    public interface Function3<I1, I2, I3, O> extends Function2<I1, I2, Function1<I3, O>> {
        public O of(I1 i1, I2 i2, I3 i3);

        default Function1<I3, O> of(I1 i1, I2 i2) {
            return i3 -> of(i1, i2, i3);
        }
    }

    public interface Function4<I1, I2, I3, I4, O> extends Function3<I1, I2, I3, Function1<I4, O>> {
        public O of(I1 i1, I2 i2, I3 i3, I4 i4);

        default Function1<I4, O> of(I1 i1, I2 i2, I3 i3) {
            return i4 -> of(i1, i2, i3, i4);
        }
    }
}