Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- package ch.claude_martin;
- import java.util.function.*;
- /**
- * My Y Combinator can handle any reference type (primitives will be auto-boxed,
- * that's why I can use <code>long/Long</code> here). However, since I'm using
- * {@link UnaryOperator}, the recursive function must return the same type as
- * it's (second) argument. Factorial is a good example of this. Instead of long,
- * it could take a {@link java.math.BigInteger} and also return one.
- *
- */
- public class YComb {
- /**
- * This is the <i>recursive</i> type of the function that will apply itself to
- * itself. This is how the recursion work.s A function needs itself as the first
- * parameter, so it then can call itself recursively.
- * <p>See this partial application in the code below:<br/>
- * <code>b -> b.apply(b)</code>
- */
- interface Fn2Op<T> extends Function<Fn2Op<T>, UnaryOperator<T>> {
- }
- /** Prints the factorial of <code>args[0]</code>.*/
- public static void main(String args[]) {
- final UnaryOperator<UnaryOperator<Long>> factorial =
- f -> n -> (n == 0) ? 1L : n * f.apply(n - 1);
- System.out.println(apply(factorial, Long.parseLong(args[0])));
- }
- /**
- * Takes any <i>recursive</i> function (which takes itself and an argument) and
- * argument and returns the result. The argument and the return value are of the
- * same type <code>T</code>.
- *
- * @param <T> The type of <code>arg</code> and return value
- * @param fn The recursive function (in curried form)
- * @param arg The argument for the function
- * @return the result of applying <code>arg</code> to <code>fn</code>
- */
- private static <T> T apply(UnaryOperator<UnaryOperator<T>> fn, T arg) {
- return ((Function<UnaryOperator<UnaryOperator<T>>, UnaryOperator<T>>)
- a -> ((Fn2Op<T>) b -> b.apply(b))
- .apply(
- c -> a.apply(
- x -> c.apply(c).apply(x)
- )
- )).apply(fn).apply(arg);
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement