Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

Here's the java version extended to work for various input/output types (I also renamed some things to make the code clearer):

public class Z {

    public interface Function<In,Out> {
        public Out apply(In param);
    }

    public interface RecFunction<In,Out>
        extends Function<Function<In,Out>,Function<In,Out>> {
    }

    private interface FixBody<In,Out>
        extends Function<FixBody<In,Out>,Function<In,Out>> {
    }

    public static <In,Out> Function<In,Out> fix(final RecFunction<In,Out> r) {
        return (new Function<FixBody<In,Out>,Function<In,Out>>() {
                public Function<In,Out> apply(FixBody<In,Out> f) {
                    return f.apply(f);
                }
            }).apply(new FixBody<In,Out>() {
                    public Function<In,Out> apply(final FixBody<In,Out> f) {
                        return r.apply(
                                new Function<In,Out>() {
                                    public Out apply(In x) {
                                        return f.apply(f).apply(x);
                                    }
				});
                    }
		});
    }

    public static final RecFunction<Integer,Integer> fact =
	new RecFunction<Integer,Integer>() {
	public Function<Integer,Integer> apply(
		final Function<Integer,Integer> self) {
            return new Function<Integer,Integer>() {
		public Integer apply(Integer n) {
                    if (n == 0)
			return 1;
                    else
                        return n * self.apply(n-1);
		}
            };
	}
    };

    public static void main(String[] args) {
	Function<Integer,Integer> factorial = fix(fact);
	for (int i = 0; i < 10; i++) {
            System.out.println("Factorial " + i + ": " + factorial.apply(i));
	}
    }
}


Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: